mirror of https://gitee.com/stylefeng/roses
【auth】整理auth和permission校验的逻辑,增加一些周边工具类
parent
443297da6c
commit
8750a66f5e
|
@ -22,7 +22,8 @@ public class ErrorResponseData extends ResponseData {
|
|||
super(Boolean.FALSE, code, message, null);
|
||||
}
|
||||
|
||||
ErrorResponseData(String code, String message, Object object) {
|
||||
public ErrorResponseData(String code, String message, Object object) {
|
||||
super(Boolean.FALSE, code, message, object);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package cn.stylefeng.roses.kernel.rule.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* ant风格资源过滤工具
|
||||
*
|
||||
* @author fengshuonan
|
||||
* @date 2020/12/15 22:31
|
||||
*/
|
||||
@Slf4j
|
||||
public class AntPathMatcherUtil {
|
||||
|
||||
/**
|
||||
* 判断某个接口是否在一组ant资源表达式下匹配
|
||||
*
|
||||
* @param requestURI 请求的url
|
||||
* @param antPatterns ant风格资源表达式
|
||||
* @author fengshuonan
|
||||
* @date 2020/12/15 22:31
|
||||
*/
|
||||
public static Boolean getAntMatchFLag(String requestURI, List<String> antPatterns) {
|
||||
AntPathMatcher antPathMatcher = new AntPathMatcher();
|
||||
for (String notAuthResourcePattern : antPatterns) {
|
||||
if (antPathMatcher.match(notAuthResourcePattern, requestURI)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package cn.stylefeng.roses.kernel.rule.util;
|
||||
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.http.ContentType;
|
||||
import cn.stylefeng.roses.kernel.rule.pojo.response.ErrorResponseData;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* http响应信息的直接渲染工具
|
||||
*
|
||||
* @author fengshuonan
|
||||
* @date 2020/12/15 21:39
|
||||
*/
|
||||
@Slf4j
|
||||
public class ResponseRenderUtil {
|
||||
|
||||
/**
|
||||
* 渲染接口json信息
|
||||
*
|
||||
* @author fengshuonan
|
||||
* @date 2020/12/15 21:40
|
||||
*/
|
||||
public static void renderErrorResponse(HttpServletResponse response,
|
||||
String code, String message, String exceptionClazz) {
|
||||
response.setCharacterEncoding(CharsetUtil.UTF_8);
|
||||
response.setContentType(ContentType.JSON.toString());
|
||||
ErrorResponseData errorResponseData = new ErrorResponseData(code, message);
|
||||
errorResponseData.setExceptionClazz(exceptionClazz);
|
||||
String errorResponseJsonData = JSON.toJSONString(errorResponseData);
|
||||
try {
|
||||
response.getWriter().write(errorResponseJsonData);
|
||||
} catch (IOException e) {
|
||||
log.error("渲染http json信息错误!", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -70,6 +70,12 @@ public interface AuthServiceApi {
|
|||
|
||||
/**
|
||||
* 校验用户访问的url是否认证通过
|
||||
* <p>
|
||||
* 校验会进行两方面:
|
||||
* <p>
|
||||
* 第一,校验用户的token是否过期
|
||||
* <p>
|
||||
* 第二,校验用户的session是否失效,但是记住我的session失效后会自动创建session,之道jwt失效后
|
||||
*
|
||||
* @param token 用户登陆的token
|
||||
* @param requestUrl 被校验的url
|
||||
|
|
|
@ -17,7 +17,7 @@ public enum AuthExceptionEnum implements AbstractExceptionEnum {
|
|||
/**
|
||||
* 认证异常
|
||||
*/
|
||||
AUTH_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "01", "认证失败,请检查您的操作是否正确"),
|
||||
AUTH_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + AuthConstants.AUTH_EXCEPTION_STEP_CODE + "01", "认证失败,请检查您的登录是否过期"),
|
||||
|
||||
/**
|
||||
* 登陆时,账号或密码为空
|
||||
|
|
|
@ -27,9 +27,6 @@ import org.springframework.stereotype.Service;
|
|||
import javax.annotation.Resource;
|
||||
import java.util.Date;
|
||||
|
||||
import static cn.stylefeng.roses.kernel.auth.api.exception.enums.AuthExceptionEnum.RESOURCE_DEFINITION_ERROR;
|
||||
import static cn.stylefeng.roses.kernel.auth.api.exception.enums.AuthExceptionEnum.TOKEN_ERROR;
|
||||
|
||||
/**
|
||||
* 认证服务的实现
|
||||
*
|
||||
|
@ -94,29 +91,39 @@ public class AuthServiceImpl implements AuthServiceApi {
|
|||
@Override
|
||||
public void checkAuth(String token, String requestUrl) {
|
||||
|
||||
// 获取url对应的资源信息ResourceDefinition
|
||||
// 1. 获取url对应的资源信息ResourceDefinition
|
||||
ResourceUrlParam resourceUrlReq = new ResourceUrlParam();
|
||||
resourceUrlReq.setUrl(requestUrl);
|
||||
ResourceDefinition resourceDefinition = resourceServiceApi.getResourceByUrl(resourceUrlReq);
|
||||
|
||||
// 获取token对应的用户信息
|
||||
LoginUser session = sessionManagerApi.getSession(token);
|
||||
if (session == null) {
|
||||
throw new AuthException(TOKEN_ERROR);
|
||||
// 2. 如果此接口不需要权限校验或者查询到资源为空,则放开过滤
|
||||
if (resourceDefinition == null || !resourceDefinition.getRequiredLogin()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 资源为空,直接响应异常,禁止用户访问
|
||||
if (resourceDefinition == null) {
|
||||
throw new AuthException(RESOURCE_DEFINITION_ERROR);
|
||||
}
|
||||
|
||||
// 检查接口是否需要鉴权
|
||||
Boolean requiredLogin = resourceDefinition.getRequiredLogin();
|
||||
|
||||
// 需要鉴权,则判断token是否过期
|
||||
if (requiredLogin) {
|
||||
// 3. 如果当前接口需要鉴权,则校验用户token是否正确,校验失败会抛出异常
|
||||
if (resourceDefinition.getRequiredLogin()) {
|
||||
this.validateToken(token);
|
||||
}
|
||||
|
||||
// 4. 如果token校验通过,获取token的payload,以及是否开启了记住我功能
|
||||
DefaultJwtPayload defaultPayload = JwtContext.me().getDefaultPayload(token);
|
||||
Boolean rememberMe = defaultPayload.getRememberMe();
|
||||
|
||||
// 5. 获取用户的当前会话信息
|
||||
LoginUser loginUser = sessionManagerApi.getSession(token);
|
||||
|
||||
// 6. 如果开了记住我,但是会话为空,则创建一次会话信息
|
||||
if (rememberMe && loginUser == null) {
|
||||
UserLoginInfoDTO userLoginInfo = userServiceApi.getUserLoginInfo(defaultPayload.getAccount());
|
||||
sessionManagerApi.createSession(token, userLoginInfo.getLoginUser());
|
||||
}
|
||||
|
||||
// 7. 如果会话信息为空,则判定此次校验失败
|
||||
if (loginUser == null) {
|
||||
throw new AuthException(AuthExceptionEnum.AUTH_ERROR);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -12,7 +12,8 @@ import org.springframework.stereotype.Service;
|
|||
import javax.annotation.Resource;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.stylefeng.roses.kernel.auth.api.exception.enums.AuthExceptionEnum.*;
|
||||
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
|
||||
|
@ -32,30 +33,31 @@ public class PermissionServiceImpl implements PermissionServiceApi {
|
|||
@Override
|
||||
public void checkPermission(String token, String requestUrl) {
|
||||
|
||||
// 获取token对应的用户信息
|
||||
// 1. 获取url对应的资源信息ResourceDefinition
|
||||
ResourceUrlParam resourceUrlReq = new ResourceUrlParam();
|
||||
resourceUrlReq.setUrl(requestUrl);
|
||||
ResourceDefinition resourceDefinition = resourceServiceApi.getResourceByUrl(resourceUrlReq);
|
||||
|
||||
// 2. 如果此接口不需要权限校验或者查询到资源为空,则放开过滤
|
||||
if (resourceDefinition == null || !resourceDefinition.getRequiredPermission()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. 获取token对应的用户信息
|
||||
LoginUser session = sessionManagerApi.getSession(token);
|
||||
if (session == null) {
|
||||
throw new AuthException(TOKEN_ERROR);
|
||||
}
|
||||
|
||||
// 获取url对应的资源信息ResourceDefinition
|
||||
ResourceUrlParam resourceUrlReq = new ResourceUrlParam();
|
||||
resourceUrlReq.setUrl(requestUrl);
|
||||
ResourceDefinition resourceDefinition = resourceServiceApi.getResourceByUrl(resourceUrlReq);
|
||||
|
||||
// 资源为空,直接响应异常,禁止用户访问
|
||||
if (resourceDefinition == null) {
|
||||
throw new AuthException(RESOURCE_DEFINITION_ERROR);
|
||||
}
|
||||
|
||||
// 检查接口是否需要权限验证
|
||||
Boolean requiredPermission = resourceDefinition.getRequiredPermission();
|
||||
|
||||
// 需要权限认证,验证用户有没有当前url的权限
|
||||
if (requiredPermission) {
|
||||
// 4. 如果需要权限认证,验证用户有没有当前url的权限
|
||||
if (resourceDefinition.getRequiredPermission()) {
|
||||
Set<String> resourceUrls = session.getResourceUrls();
|
||||
if (resourceUrls == null || resourceUrls.size() == 0) {
|
||||
throw new AuthException(PERMISSION_RES_VALIDATE_ERROR);
|
||||
} else {
|
||||
if (!resourceUrls.contains(requestUrl)) {
|
||||
throw new AuthException(PERMISSION_RES_VALIDATE_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ public class DefaultJwtPayload {
|
|||
/**
|
||||
* 是否记住我
|
||||
*/
|
||||
private boolean rememberMe;
|
||||
private Boolean rememberMe;
|
||||
|
||||
/**
|
||||
* 其他载体信息
|
||||
|
|
Loading…
Reference in New Issue