mirror of https://gitee.com/stylefeng/roses
Merge branch 'master' into group5-msg
commit
422d5a6398
|
@ -22,10 +22,10 @@ public class AntPathMatcherUtil {
|
||||||
* @author fengshuonan
|
* @author fengshuonan
|
||||||
* @date 2020/12/15 22:31
|
* @date 2020/12/15 22:31
|
||||||
*/
|
*/
|
||||||
public static Boolean getAntMatchFLag(String requestURI, List<String> antPatterns) {
|
public static Boolean getAntMatchFLag(String requestURI, String contextPath, List<String> antPatterns) {
|
||||||
AntPathMatcher antPathMatcher = new AntPathMatcher();
|
AntPathMatcher antPathMatcher = new AntPathMatcher();
|
||||||
for (String notAuthResourcePattern : antPatterns) {
|
for (String notAuthResourcePattern : antPatterns) {
|
||||||
if (antPathMatcher.match(notAuthResourcePattern, requestURI)) {
|
if (antPathMatcher.match(contextPath + notAuthResourcePattern, requestURI)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,23 @@ import java.io.IOException;
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class ResponseRenderUtil {
|
public class ResponseRenderUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渲染接口json信息
|
||||||
|
*
|
||||||
|
* @author fengshuonan
|
||||||
|
* @date 2020/12/15 21:40
|
||||||
|
*/
|
||||||
|
public static void renderJsonResponse(HttpServletResponse response, Object responseData) {
|
||||||
|
response.setCharacterEncoding(CharsetUtil.UTF_8);
|
||||||
|
response.setContentType(ContentType.JSON.toString());
|
||||||
|
String errorResponseJsonData = JSON.toJSONString(responseData);
|
||||||
|
try {
|
||||||
|
response.getWriter().write(errorResponseJsonData);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("渲染http json信息错误!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 渲染接口json信息
|
* 渲染接口json信息
|
||||||
*
|
*
|
||||||
|
|
|
@ -49,7 +49,9 @@ public interface AuthServiceApi {
|
||||||
void logoutWithToken(String token);
|
void logoutWithToken(String token);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验token
|
* 校验jwt token的正确性,调用jwt工具类相关方法校验
|
||||||
|
* <p>
|
||||||
|
* 结果有三种,第一是jwt过期了,第二是用户随便写的错误token,第三种是token正确,token正确不会抛出异常
|
||||||
*
|
*
|
||||||
* @param token 某个用户的登录token
|
* @param token 某个用户的登录token
|
||||||
* @throws AuthException 认证异常,如果token错误或过期,会有相关的异常抛出
|
* @throws AuthException 认证异常,如果token错误或过期,会有相关的异常抛出
|
||||||
|
@ -58,16 +60,6 @@ public interface AuthServiceApi {
|
||||||
*/
|
*/
|
||||||
void validateToken(String token) throws AuthException;
|
void validateToken(String token) throws AuthException;
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取token是否正确
|
|
||||||
*
|
|
||||||
* @param token 某个用户的登录token
|
|
||||||
* @return true-token正确,false-token错误
|
|
||||||
* @author fengshuonan
|
|
||||||
* @date 2020/10/19 14:16
|
|
||||||
*/
|
|
||||||
boolean getTokenFlag(String token);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验用户是否认证通过,认证是校验token的过程,校验失败会抛出异常
|
* 校验用户是否认证通过,认证是校验token的过程,校验失败会抛出异常
|
||||||
*
|
*
|
||||||
|
|
|
@ -73,4 +73,14 @@ public interface SessionManagerApi {
|
||||||
*/
|
*/
|
||||||
void refreshSession(String token);
|
void refreshSession(String token);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 销毁当前用户对应的会话cookie
|
||||||
|
* <p>
|
||||||
|
* 一般用在单体不分离版本中
|
||||||
|
*
|
||||||
|
* @author fengshuonan
|
||||||
|
* @date 2021/1/2 20:25
|
||||||
|
*/
|
||||||
|
void destroySessionCookie();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package cn.stylefeng.roses.kernel.auth.api.cookie;
|
package cn.stylefeng.roses.kernel.auth.api.cookie;
|
||||||
|
|
||||||
import cn.hutool.core.convert.Convert;
|
|
||||||
|
|
||||||
import javax.servlet.http.Cookie;
|
import javax.servlet.http.Cookie;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,7 +25,7 @@ public abstract class SessionCookieCreator {
|
||||||
*/
|
*/
|
||||||
public Cookie createCookie(String cookieName, String cookieValue, Integer sessionExpiredSeconds) {
|
public Cookie createCookie(String cookieName, String cookieValue, Integer sessionExpiredSeconds) {
|
||||||
Cookie cookie = new Cookie(cookieName, cookieValue);
|
Cookie cookie = new Cookie(cookieName, cookieValue);
|
||||||
cookie.setMaxAge(Convert.toInt(sessionExpiredSeconds));
|
cookie.setMaxAge(sessionExpiredSeconds);
|
||||||
this.expandCookieProp(cookie);
|
this.expandCookieProp(cookie);
|
||||||
return cookie;
|
return cookie;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,44 +15,44 @@ import lombok.Getter;
|
||||||
public enum AuthExceptionEnum implements AbstractExceptionEnum {
|
public enum AuthExceptionEnum implements AbstractExceptionEnum {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 认证异常
|
* 会话过期或超时,token过期,都属于这种异常,提示用户从新登录
|
||||||
*/
|
*/
|
||||||
AUTH_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "01", "认证失败,请检查您的登录是否过期"),
|
AUTH_EXPIRED_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "01", "当前登录会话过期,请重新登录"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* jwt token解析失败,可能用户写错了token,或者用户随意写的token,导致jwt无法解析
|
||||||
|
*/
|
||||||
|
TOKEN_PARSE_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "02", "TOKEN解析失败,请传递正常TOKEN"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登陆时,账号或密码为空
|
* 登陆时,账号或密码为空
|
||||||
*/
|
*/
|
||||||
PARAM_EMPTY(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "02", "登陆失败,账号或密码参数为空"),
|
PARAM_EMPTY(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "03", "登陆失败,账号或密码参数为空"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 账号或密码错误
|
* 账号或密码错误
|
||||||
*/
|
*/
|
||||||
USERNAME_PASSWORD_ERROR(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "03", "账号或密码错误"),
|
USERNAME_PASSWORD_ERROR(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "04", "账号或密码错误"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户状态异常,可能被禁用可能被冻结,用StrUtil.format()格式化
|
* 用户状态异常,可能被禁用可能被冻结,用StrUtil.format()格式化
|
||||||
*/
|
*/
|
||||||
USER_STATUS_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "04", "当前用户被{},请检查用户状态是否正常"),
|
USER_STATUS_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "05", "当前用户被{},请检查用户状态是否正常"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登陆失败,账号参数为空
|
* 登陆失败,账号参数为空
|
||||||
*/
|
*/
|
||||||
ACCOUNT_IS_BLANK(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "05", "登陆失败,账号参数为空"),
|
ACCOUNT_IS_BLANK(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "06", "登陆失败,账号参数为空"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取token失败
|
* 获取token失败
|
||||||
*/
|
*/
|
||||||
TOKEN_GET_ERROR(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "06", "获取token失败,请检查header和param中是否传递了用户token"),
|
TOKEN_GET_ERROR(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "07", "获取token失败,请检查header和param中是否传递了用户token"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取资源为空
|
* 获取资源为空
|
||||||
*/
|
*/
|
||||||
RESOURCE_DEFINITION_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "07", "获取资源为空,请检查当前请求url是否存在对应的ResourceDefinition"),
|
RESOURCE_DEFINITION_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "08", "获取资源为空,请检查当前请求url是否存在对应的ResourceDefinition"),
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取不到token对应的用户信息,请检查登录是否过期
|
|
||||||
*/
|
|
||||||
TOKEN_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "08", "获取不到token对应的用户信息,请检查登录是否过期"),
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 权限校验失败,请检查用户是否有该资源的权限
|
* 权限校验失败,请检查用户是否有该资源的权限
|
||||||
|
|
|
@ -14,6 +14,7 @@ import cn.stylefeng.roses.kernel.auth.api.pojo.auth.LoginResponse;
|
||||||
import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser;
|
import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser;
|
||||||
import cn.stylefeng.roses.kernel.jwt.api.context.JwtContext;
|
import cn.stylefeng.roses.kernel.jwt.api.context.JwtContext;
|
||||||
import cn.stylefeng.roses.kernel.jwt.api.exception.JwtException;
|
import cn.stylefeng.roses.kernel.jwt.api.exception.JwtException;
|
||||||
|
import cn.stylefeng.roses.kernel.jwt.api.exception.enums.JwtExceptionEnum;
|
||||||
import cn.stylefeng.roses.kernel.jwt.api.pojo.payload.DefaultJwtPayload;
|
import cn.stylefeng.roses.kernel.jwt.api.pojo.payload.DefaultJwtPayload;
|
||||||
import cn.stylefeng.roses.kernel.rule.util.HttpServletUtil;
|
import cn.stylefeng.roses.kernel.rule.util.HttpServletUtil;
|
||||||
import cn.stylefeng.roses.kernel.system.UserServiceApi;
|
import cn.stylefeng.roses.kernel.system.UserServiceApi;
|
||||||
|
@ -24,6 +25,9 @@ import org.springframework.stereotype.Service;
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
import static cn.stylefeng.roses.kernel.auth.api.exception.enums.AuthExceptionEnum.AUTH_EXPIRED_ERROR;
|
||||||
|
import static cn.stylefeng.roses.kernel.auth.api.exception.enums.AuthExceptionEnum.TOKEN_PARSE_ERROR;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 认证服务的实现
|
* 认证服务的实现
|
||||||
*
|
*
|
||||||
|
@ -77,15 +81,26 @@ public class AuthServiceImpl implements AuthServiceApi {
|
||||||
@Override
|
@Override
|
||||||
public void validateToken(String token) throws AuthException {
|
public void validateToken(String token) throws AuthException {
|
||||||
try {
|
try {
|
||||||
|
// 1. 先校验jwt token本身是否有问题
|
||||||
JwtContext.me().validateTokenWithException(token);
|
JwtContext.me().validateTokenWithException(token);
|
||||||
} catch (JwtException e) {
|
|
||||||
throw new AuthException(e.getErrorCode(), e.getUserTip());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
// 2. 判断session里是否有这个token
|
||||||
public boolean getTokenFlag(String token) {
|
LoginUser session = sessionManagerApi.getSession(token);
|
||||||
return JwtContext.me().validateToken(token);
|
if (session == null) {
|
||||||
|
throw new AuthException(AUTH_EXPIRED_ERROR);
|
||||||
|
}
|
||||||
|
} catch (JwtException jwtException) {
|
||||||
|
// jwt token本身过期的话,返回 AUTH_EXPIRED_ERROR
|
||||||
|
if (JwtExceptionEnum.JWT_EXPIRED_ERROR.getErrorCode().equals(jwtException.getErrorCode())) {
|
||||||
|
throw new AuthException(AUTH_EXPIRED_ERROR);
|
||||||
|
} else {
|
||||||
|
// 其他情况为返回jwt解析错误
|
||||||
|
throw new AuthException(TOKEN_PARSE_ERROR);
|
||||||
|
}
|
||||||
|
} catch (io.jsonwebtoken.JwtException jwtSelfException) {
|
||||||
|
// 其他jwt解析错误
|
||||||
|
throw new AuthException(TOKEN_PARSE_ERROR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -114,7 +129,7 @@ public class AuthServiceImpl implements AuthServiceApi {
|
||||||
|
|
||||||
// 6. 如果会话信息为空,则判定此次校验失败
|
// 6. 如果会话信息为空,则判定此次校验失败
|
||||||
if (loginUser == null) {
|
if (loginUser == null) {
|
||||||
throw new AuthException(AuthExceptionEnum.AUTH_ERROR);
|
throw new AuthException(AUTH_EXPIRED_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,8 @@ import org.springframework.stereotype.Service;
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static cn.stylefeng.roses.kernel.auth.api.exception.enums.AuthExceptionEnum.AUTH_EXPIRED_ERROR;
|
||||||
import static cn.stylefeng.roses.kernel.auth.api.exception.enums.AuthExceptionEnum.PERMISSION_RES_VALIDATE_ERROR;
|
import static cn.stylefeng.roses.kernel.auth.api.exception.enums.AuthExceptionEnum.PERMISSION_RES_VALIDATE_ERROR;
|
||||||
import static cn.stylefeng.roses.kernel.auth.api.exception.enums.AuthExceptionEnum.TOKEN_ERROR;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 权限相关的service
|
* 权限相关的service
|
||||||
|
@ -37,7 +37,7 @@ public class PermissionServiceImpl implements PermissionServiceApi {
|
||||||
// 2. 获取token对应的用户信息
|
// 2. 获取token对应的用户信息
|
||||||
LoginUser session = sessionManagerApi.getSession(token);
|
LoginUser session = sessionManagerApi.getSession(token);
|
||||||
if (session == null) {
|
if (session == null) {
|
||||||
throw new AuthException(TOKEN_ERROR);
|
throw new AuthException(AUTH_EXPIRED_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 验证用户有没有当前url的权限
|
// 3. 验证用户有没有当前url的权限
|
||||||
|
|
|
@ -76,7 +76,7 @@ public class DefaultSessionManager implements SessionManagerApi {
|
||||||
// 如果开启了cookie存储会话信息,则需要给HttpServletResponse添加一个cookie
|
// 如果开启了cookie存储会话信息,则需要给HttpServletResponse添加一个cookie
|
||||||
if (AuthConfigExpander.getSessionAddToCookie()) {
|
if (AuthConfigExpander.getSessionAddToCookie()) {
|
||||||
String sessionCookieName = AuthConfigExpander.getSessionCookieName();
|
String sessionCookieName = AuthConfigExpander.getSessionCookieName();
|
||||||
Cookie cookie = sessionCookieCreator.createCookie(sessionCookieName, token, Convert.toInt(sessionExpiredSeconds));
|
Cookie cookie = sessionCookieCreator.createCookie(sessionCookieName, token, Convert.toInt(AuthConfigExpander.getAuthJwtTimeoutSeconds()));
|
||||||
HttpServletResponse response = HttpServletUtil.getResponse();
|
HttpServletResponse response = HttpServletUtil.getResponse();
|
||||||
response.addCookie(cookie);
|
response.addCookie(cookie);
|
||||||
}
|
}
|
||||||
|
@ -155,4 +155,15 @@ public class DefaultSessionManager implements SessionManagerApi {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroySessionCookie() {
|
||||||
|
// 如果开启了cookie存储会话信息,则需要给HttpServletResponse添加一个cookie
|
||||||
|
if (AuthConfigExpander.getSessionAddToCookie()) {
|
||||||
|
String sessionCookieName = AuthConfigExpander.getSessionCookieName();
|
||||||
|
Cookie cookie = sessionCookieCreator.createCookie(sessionCookieName, null, 0);
|
||||||
|
HttpServletResponse response = HttpServletUtil.getResponse();
|
||||||
|
response.addCookie(cookie);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import cn.stylefeng.roses.kernel.file.util.DownloadUtil;
|
||||||
import cn.stylefeng.roses.kernel.file.util.PdfFileTypeUtil;
|
import cn.stylefeng.roses.kernel.file.util.PdfFileTypeUtil;
|
||||||
import cn.stylefeng.roses.kernel.file.util.PicFileTypeUtil;
|
import cn.stylefeng.roses.kernel.file.util.PicFileTypeUtil;
|
||||||
import cn.stylefeng.roses.kernel.rule.enums.YesOrNotEnum;
|
import cn.stylefeng.roses.kernel.rule.enums.YesOrNotEnum;
|
||||||
|
import cn.stylefeng.roses.kernel.rule.util.HttpServletUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||||
|
@ -365,7 +366,10 @@ public class SysFileInfoServiceImpl extends ServiceImpl<SysFileInfoMapper, SysFi
|
||||||
// 获取登录用户的token
|
// 获取登录用户的token
|
||||||
String token = LoginContext.me().getToken();
|
String token = LoginContext.me().getToken();
|
||||||
|
|
||||||
return FileConfigExpander.getServerDeployHost() + FileConstants.FILE_PRIVATE_PREVIEW_URL + "?fileId=" + fileId + "&token=" + token;
|
// 获取context-path
|
||||||
|
String contextPath = HttpServletUtil.getRequest().getContextPath();
|
||||||
|
|
||||||
|
return FileConfigExpander.getServerDeployHost() + contextPath + FileConstants.FILE_PRIVATE_PREVIEW_URL + "?fileId=" + fileId + "&token=" + token;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -11,6 +11,7 @@ import cn.stylefeng.roses.kernel.file.exception.FileException;
|
||||||
import cn.stylefeng.roses.kernel.file.exception.enums.FileExceptionEnum;
|
import cn.stylefeng.roses.kernel.file.exception.enums.FileExceptionEnum;
|
||||||
import cn.stylefeng.roses.kernel.file.expander.FileConfigExpander;
|
import cn.stylefeng.roses.kernel.file.expander.FileConfigExpander;
|
||||||
import cn.stylefeng.roses.kernel.file.pojo.props.LocalFileProperties;
|
import cn.stylefeng.roses.kernel.file.pojo.props.LocalFileProperties;
|
||||||
|
import cn.stylefeng.roses.kernel.rule.util.HttpServletUtil;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
@ -151,7 +152,10 @@ public class LocalFileOperator implements FileOperatorApi {
|
||||||
// 获取登录用户的token
|
// 获取登录用户的token
|
||||||
String token = LoginContext.me().getToken();
|
String token = LoginContext.me().getToken();
|
||||||
|
|
||||||
return FileConfigExpander.getServerDeployHost() + FileConstants.FILE_PRIVATE_PREVIEW_URL + "?fileBucket=" + bucketName + "&fileObjectName=" + key + "&token=" + token;
|
// 获取context-path
|
||||||
|
String contextPath = HttpServletUtil.getRequest().getContextPath();
|
||||||
|
|
||||||
|
return FileConfigExpander.getServerDeployHost() + contextPath + FileConstants.FILE_PRIVATE_PREVIEW_URL + "?fileBucket=" + bucketName + "&fileObjectName=" + key + "&token=" + token;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -12,6 +12,7 @@ import cn.stylefeng.roses.kernel.file.exception.FileException;
|
||||||
import cn.stylefeng.roses.kernel.file.exception.enums.FileExceptionEnum;
|
import cn.stylefeng.roses.kernel.file.exception.enums.FileExceptionEnum;
|
||||||
import cn.stylefeng.roses.kernel.file.expander.FileConfigExpander;
|
import cn.stylefeng.roses.kernel.file.expander.FileConfigExpander;
|
||||||
import cn.stylefeng.roses.kernel.file.pojo.props.MinIoProperties;
|
import cn.stylefeng.roses.kernel.file.pojo.props.MinIoProperties;
|
||||||
|
import cn.stylefeng.roses.kernel.rule.util.HttpServletUtil;
|
||||||
import io.minio.MinioClient;
|
import io.minio.MinioClient;
|
||||||
import io.minio.errors.InvalidEndpointException;
|
import io.minio.errors.InvalidEndpointException;
|
||||||
import io.minio.errors.InvalidPortException;
|
import io.minio.errors.InvalidPortException;
|
||||||
|
@ -195,7 +196,10 @@ public class MinIoFileOperator implements FileOperatorApi {
|
||||||
// 获取登录用户的token
|
// 获取登录用户的token
|
||||||
String token = LoginContext.me().getToken();
|
String token = LoginContext.me().getToken();
|
||||||
|
|
||||||
return FileConfigExpander.getServerDeployHost() + FileConstants.FILE_PRIVATE_PREVIEW_URL + "?fileBucket=" + bucketName + "&fileObjectName=" + key + "&token=" + token;
|
// 获取context-path
|
||||||
|
String contextPath = HttpServletUtil.getRequest().getContextPath();
|
||||||
|
|
||||||
|
return FileConfigExpander.getServerDeployHost() + contextPath + FileConstants.FILE_PRIVATE_PREVIEW_URL + "?fileBucket=" + bucketName + "&fileObjectName=" + key + "&token=" + token;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,13 @@ public interface JwtApi {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验jwt token是否正确
|
* 校验jwt token是否正确
|
||||||
|
* <p>
|
||||||
|
* 不正确的token有两种:
|
||||||
|
* <p>
|
||||||
|
* 1. 第一种是jwt token过期了
|
||||||
|
* 2. 第二种是jwt本身是错误的
|
||||||
|
* <p>
|
||||||
|
* 本方法只会响应正确还是错误
|
||||||
*
|
*
|
||||||
* @param token jwt的token
|
* @param token jwt的token
|
||||||
* @return true-token正确,false-token错误或失效
|
* @return true-token正确,false-token错误或失效
|
||||||
|
@ -64,7 +71,12 @@ public interface JwtApi {
|
||||||
boolean validateToken(String token);
|
boolean validateToken(String token);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验jwt token是否正确,如果jwt异常,或者jwt过期,则直接抛出异常
|
* 校验jwt token是否正确,如果参数token是错误的会抛出对应异常
|
||||||
|
* <p>
|
||||||
|
* 不正确的token有两种:
|
||||||
|
* <p>
|
||||||
|
* 1. 第一种是jwt token过期了
|
||||||
|
* 2. 第二种是jwt本身是错误的
|
||||||
*
|
*
|
||||||
* @param token jwt的token
|
* @param token jwt的token
|
||||||
* @throws JwtException Jwt相关的业务异常
|
* @throws JwtException Jwt相关的业务异常
|
||||||
|
@ -74,13 +86,13 @@ public interface JwtApi {
|
||||||
void validateTokenWithException(String token) throws JwtException;
|
void validateTokenWithException(String token) throws JwtException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取 token 的失效时间
|
* 校验jwt token是否失效了
|
||||||
*
|
*
|
||||||
* @param token jwt token
|
* @param token jwt token
|
||||||
* @return true-token失效,false-token没失效
|
* @return true-token失效,false-token没失效
|
||||||
* @author fengshuonan
|
* @author fengshuonan
|
||||||
* @date 2020/10/21 11:56
|
* @date 2020/10/21 11:56
|
||||||
*/
|
*/
|
||||||
boolean getTokenExpiredFlag(String token);
|
boolean validateTokenIsExpired(String token);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package cn.stylefeng.roses.kernel.jwt.api.exception;
|
package cn.stylefeng.roses.kernel.jwt.api.exception;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.stylefeng.roses.kernel.jwt.api.constants.JwtConstants;
|
import cn.stylefeng.roses.kernel.jwt.api.constants.JwtConstants;
|
||||||
import cn.stylefeng.roses.kernel.rule.abstracts.AbstractExceptionEnum;
|
import cn.stylefeng.roses.kernel.rule.abstracts.AbstractExceptionEnum;
|
||||||
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
|
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
|
||||||
|
@ -12,8 +13,8 @@ import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
|
||||||
*/
|
*/
|
||||||
public class JwtException extends ServiceException {
|
public class JwtException extends ServiceException {
|
||||||
|
|
||||||
public JwtException(AbstractExceptionEnum exception, String userTip) {
|
public JwtException(AbstractExceptionEnum exception, Object... params) {
|
||||||
super(JwtConstants.JWT_MODULE_NAME, exception.getErrorCode(), userTip);
|
super(JwtConstants.JWT_MODULE_NAME, exception.getErrorCode(), StrUtil.format(exception.getUserTip(), params));
|
||||||
}
|
}
|
||||||
|
|
||||||
public JwtException(AbstractExceptionEnum exception) {
|
public JwtException(AbstractExceptionEnum exception) {
|
||||||
|
|
|
@ -17,7 +17,12 @@ public enum JwtExceptionEnum implements AbstractExceptionEnum {
|
||||||
/**
|
/**
|
||||||
* jwt解析异常
|
* jwt解析异常
|
||||||
*/
|
*/
|
||||||
JWT_PARSE_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + JwtConstants.JWT_EXCEPTION_STEP_CODE + "01", "jwt解析错误!jwt为:{}");
|
JWT_PARSE_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + JwtConstants.JWT_EXCEPTION_STEP_CODE + "01", "jwt解析错误!jwt为:{}"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* jwt过期了
|
||||||
|
*/
|
||||||
|
JWT_EXPIRED_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + JwtConstants.JWT_EXCEPTION_STEP_CODE + "02", "jwt过期了!jwt为:{}");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 错误编码
|
* 错误编码
|
||||||
|
|
|
@ -4,9 +4,9 @@ import cn.hutool.core.bean.BeanUtil;
|
||||||
import cn.hutool.core.convert.Convert;
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.date.DateTime;
|
import cn.hutool.core.date.DateTime;
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import cn.stylefeng.roses.kernel.jwt.api.JwtApi;
|
import cn.stylefeng.roses.kernel.jwt.api.JwtApi;
|
||||||
import cn.stylefeng.roses.kernel.jwt.api.exception.JwtException;
|
import cn.stylefeng.roses.kernel.jwt.api.exception.JwtException;
|
||||||
|
import cn.stylefeng.roses.kernel.jwt.api.exception.enums.JwtExceptionEnum;
|
||||||
import cn.stylefeng.roses.kernel.jwt.api.pojo.config.JwtConfig;
|
import cn.stylefeng.roses.kernel.jwt.api.pojo.config.JwtConfig;
|
||||||
import cn.stylefeng.roses.kernel.jwt.api.pojo.payload.DefaultJwtPayload;
|
import cn.stylefeng.roses.kernel.jwt.api.pojo.payload.DefaultJwtPayload;
|
||||||
import io.jsonwebtoken.Claims;
|
import io.jsonwebtoken.Claims;
|
||||||
|
@ -90,16 +90,23 @@ public class JwtTokenOperator implements JwtApi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void validateTokenWithException(String token) throws JwtException {
|
public void validateTokenWithException(String token) throws JwtException {
|
||||||
|
|
||||||
|
// 1.先判断是否是token过期了
|
||||||
|
boolean tokenIsExpired = this.validateTokenIsExpired(token);
|
||||||
|
if (tokenIsExpired) {
|
||||||
|
throw new JwtException(JwtExceptionEnum.JWT_EXPIRED_ERROR, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2.判断是否是jwt本身的错误
|
||||||
try {
|
try {
|
||||||
getJwtPayloadClaims(token);
|
getJwtPayloadClaims(token);
|
||||||
} catch (io.jsonwebtoken.JwtException jwtException) {
|
} catch (io.jsonwebtoken.JwtException jwtException) {
|
||||||
String userTip = StrUtil.format(JWT_PARSE_ERROR.getUserTip(), token);
|
throw new JwtException(JWT_PARSE_ERROR, token);
|
||||||
throw new JwtException(JWT_PARSE_ERROR, userTip);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean getTokenExpiredFlag(String token) {
|
public boolean validateTokenIsExpired(String token) {
|
||||||
try {
|
try {
|
||||||
Claims claims = getJwtPayloadClaims(token);
|
Claims claims = getJwtPayloadClaims(token);
|
||||||
final Date expiration = claims.getExpiration();
|
final Date expiration = claims.getExpiration();
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,11 +1,10 @@
|
||||||
package cn.stylefeng.roses.kernel.menu.modular.factory;
|
package cn.stylefeng.roses.kernel.menu.modular.factory;
|
||||||
|
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
import cn.hutool.core.collection.CollectionUtil;
|
|
||||||
import cn.hutool.extra.spring.SpringUtil;
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
import cn.stylefeng.roses.kernel.menu.modular.entity.SysMenu;
|
import cn.stylefeng.roses.kernel.menu.modular.entity.SysMenu;
|
||||||
import cn.stylefeng.roses.kernel.rule.enums.StatusEnum;
|
|
||||||
import cn.stylefeng.roses.kernel.rule.factory.DefaultTreeBuildFactory;
|
import cn.stylefeng.roses.kernel.rule.factory.DefaultTreeBuildFactory;
|
||||||
|
import cn.stylefeng.roses.kernel.rule.util.HttpServletUtil;
|
||||||
import cn.stylefeng.roses.kernel.system.AppServiceApi;
|
import cn.stylefeng.roses.kernel.system.AppServiceApi;
|
||||||
import cn.stylefeng.roses.kernel.system.pojo.menu.layui.LayuiAppIndexMenus;
|
import cn.stylefeng.roses.kernel.system.pojo.menu.layui.LayuiAppIndexMenus;
|
||||||
import cn.stylefeng.roses.kernel.system.pojo.menu.layui.LayuiIndexMenuTreeNode;
|
import cn.stylefeng.roses.kernel.system.pojo.menu.layui.LayuiIndexMenuTreeNode;
|
||||||
|
@ -32,6 +31,8 @@ public class LayuiMenusFactory {
|
||||||
*/
|
*/
|
||||||
public static List<LayuiAppIndexMenus> createLayuiAppIndexMenus(List<SysMenu> sysMenuList) {
|
public static List<LayuiAppIndexMenus> createLayuiAppIndexMenus(List<SysMenu> sysMenuList) {
|
||||||
|
|
||||||
|
String contextPath = HttpServletUtil.getRequest().getContextPath();
|
||||||
|
|
||||||
ArrayList<LayuiAppIndexMenus> resultList = new ArrayList<>();
|
ArrayList<LayuiAppIndexMenus> resultList = new ArrayList<>();
|
||||||
|
|
||||||
// 找出用户有多少个应用的菜单
|
// 找出用户有多少个应用的菜单
|
||||||
|
@ -54,6 +55,10 @@ public class LayuiMenusFactory {
|
||||||
for (SysMenu appMenu : appMenus) {
|
for (SysMenu appMenu : appMenus) {
|
||||||
LayuiIndexMenuTreeNode layuiIndexMenuTreeNode = new LayuiIndexMenuTreeNode();
|
LayuiIndexMenuTreeNode layuiIndexMenuTreeNode = new LayuiIndexMenuTreeNode();
|
||||||
BeanUtil.copyProperties(appMenu, layuiIndexMenuTreeNode);
|
BeanUtil.copyProperties(appMenu, layuiIndexMenuTreeNode);
|
||||||
|
|
||||||
|
// 每个节点的url要加上context-path
|
||||||
|
layuiIndexMenuTreeNode.setRouter(contextPath + layuiIndexMenuTreeNode.getRouter());
|
||||||
|
|
||||||
layuiIndexMenuTreeNodes.add(layuiIndexMenuTreeNode);
|
layuiIndexMenuTreeNodes.add(layuiIndexMenuTreeNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue