mirror of https://gitee.com/stylefeng/guns
1.增加session超时的跳转
2.从新整理过滤器,refreshSession放到base拦截器 3.全局异常拦截器,特殊考虑session超时情况pull/65/head
parent
33c42e144d
commit
3e049fc14d
6
pom.xml
6
pom.xml
|
@ -60,12 +60,6 @@
|
|||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.stylefeng.roses</groupId>
|
||||
<artifactId>jwt-spring-boot-starter</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.stylefeng.roses</groupId>
|
||||
<artifactId>scanner-spring-boot-starter</artifactId>
|
||||
|
|
|
@ -2,17 +2,21 @@ package cn.stylefeng.guns.core.error;
|
|||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.stylefeng.roses.kernel.auth.api.exception.AuthException;
|
||||
import cn.stylefeng.roses.kernel.auth.api.exception.enums.AuthExceptionEnum;
|
||||
import cn.stylefeng.roses.kernel.rule.abstracts.AbstractExceptionEnum;
|
||||
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
|
||||
import cn.stylefeng.roses.kernel.rule.exception.enums.defaults.DefaultBusinessExceptionEnum;
|
||||
import cn.stylefeng.roses.kernel.rule.pojo.response.ErrorResponseData;
|
||||
import cn.stylefeng.roses.kernel.rule.util.ExceptionUtil;
|
||||
import cn.stylefeng.roses.kernel.rule.util.ResponseRenderUtil;
|
||||
import cn.stylefeng.roses.kernel.system.constants.SymbolConstant;
|
||||
import cn.stylefeng.roses.kernel.validator.exception.ParamValidateException;
|
||||
import cn.stylefeng.roses.kernel.validator.exception.enums.ValidatorExceptionEnum;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.validation.ObjectError;
|
||||
|
@ -27,6 +31,7 @@ import org.springframework.web.bind.annotation.ResponseStatus;
|
|||
import org.springframework.web.servlet.NoHandlerFoundException;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.ValidationException;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -159,6 +164,44 @@ public class GlobalExceptionHandler {
|
|||
return renderJson(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* 拦截全校校验一类的异常
|
||||
* <p>
|
||||
* 这里重点做一类特殊处理,也就是对过期登录用用户
|
||||
* <p>
|
||||
* 如果用户登录过期,并且为ajax请求,则response的header增加session-timeout的标识
|
||||
* <p>
|
||||
* 如果用户登录过期,不是ajax请求,则直接跳转到登录页面,并提示会话超时
|
||||
*
|
||||
* @author fengshuonan
|
||||
* @date 2020/12/16 15:11
|
||||
*/
|
||||
@ExceptionHandler(AuthException.class)
|
||||
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||
public String authError(AuthException authException, HttpServletRequest request, HttpServletResponse response, Model model) {
|
||||
String errorCode = authException.getErrorCode();
|
||||
if (AuthExceptionEnum.AUTH_EXPIRED_ERROR.getErrorCode().equals(errorCode)) {
|
||||
|
||||
// 如果是普通请求
|
||||
if (request.getContentType() == null
|
||||
|| request.getContentType().toLowerCase().contains("text/html")) {
|
||||
model.addAttribute("tips", AuthExceptionEnum.AUTH_EXPIRED_ERROR.getUserTip());
|
||||
return "/login.html";
|
||||
} else {
|
||||
// 其他请求或者是ajax请求
|
||||
response.setHeader("Guns-Session-Timeout", "true");
|
||||
ErrorResponseData errorResponseData = renderJson(authException);
|
||||
ResponseRenderUtil.renderJsonResponse(response, errorResponseData);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// 默认响应前端json
|
||||
ErrorResponseData errorResponseData = renderJson(authException);
|
||||
ResponseRenderUtil.renderJsonResponse(response, errorResponseData);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 拦截业务代码抛出的异常
|
||||
*
|
||||
|
|
|
@ -3,7 +3,6 @@ package cn.stylefeng.guns.core.security;
|
|||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.stylefeng.guns.core.security.base.BaseSecurityInterceptor;
|
||||
import cn.stylefeng.roses.kernel.auth.api.AuthServiceApi;
|
||||
import cn.stylefeng.roses.kernel.auth.api.SessionManagerApi;
|
||||
import cn.stylefeng.roses.kernel.auth.api.exception.AuthException;
|
||||
import cn.stylefeng.roses.kernel.auth.api.exception.enums.AuthExceptionEnum;
|
||||
import cn.stylefeng.roses.kernel.resource.api.pojo.resource.ResourceDefinition;
|
||||
|
@ -30,12 +29,6 @@ public class AuthJwtTokenSecurityInterceptor extends BaseSecurityInterceptor {
|
|||
@Resource
|
||||
private AuthServiceApi authServiceApi;
|
||||
|
||||
/**
|
||||
* 用户会话管理Api
|
||||
*/
|
||||
@Resource
|
||||
private SessionManagerApi sessionManagerApi;
|
||||
|
||||
@Override
|
||||
public void filterAction(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, ResourceDefinition resourceDefinition, String token) {
|
||||
|
||||
|
@ -52,9 +45,6 @@ public class AuthJwtTokenSecurityInterceptor extends BaseSecurityInterceptor {
|
|||
|
||||
// 3.校验token和用户会话信息是否正确
|
||||
authServiceApi.checkAuth(token, requestURI);
|
||||
|
||||
// 4.刷新用户的session的过期时间
|
||||
sessionManagerApi.refreshSession(token);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
package cn.stylefeng.guns.core.security.base;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.stylefeng.roses.kernel.auth.api.AuthServiceApi;
|
||||
import cn.stylefeng.roses.kernel.auth.api.SessionManagerApi;
|
||||
import cn.stylefeng.roses.kernel.auth.api.context.LoginContext;
|
||||
import cn.stylefeng.roses.kernel.auth.api.exception.AuthException;
|
||||
import cn.stylefeng.roses.kernel.auth.api.exception.enums.AuthExceptionEnum;
|
||||
import cn.stylefeng.roses.kernel.auth.api.expander.AuthConfigExpander;
|
||||
import cn.stylefeng.roses.kernel.resource.api.pojo.resource.ResourceDefinition;
|
||||
import cn.stylefeng.roses.kernel.resource.api.pojo.resource.ResourceUrlParam;
|
||||
|
@ -25,6 +30,12 @@ public abstract class BaseSecurityInterceptor implements HandlerInterceptor {
|
|||
@Resource
|
||||
private ResourceServiceApi resourceServiceApi;
|
||||
|
||||
@Resource
|
||||
private AuthServiceApi authServiceApi;
|
||||
|
||||
@Resource
|
||||
private SessionManagerApi sessionManagerApi;
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
|
||||
|
||||
|
@ -32,7 +43,7 @@ public abstract class BaseSecurityInterceptor implements HandlerInterceptor {
|
|||
String requestURI = request.getRequestURI();
|
||||
|
||||
// 2. 不需要权限过滤的资源,直接放行
|
||||
Boolean noneSecurityFlag = AntPathMatcherUtil.getAntMatchFLag(requestURI, AuthConfigExpander.getNoneSecurityConfig());
|
||||
Boolean noneSecurityFlag = AntPathMatcherUtil.getAntMatchFLag(requestURI, request.getContextPath(), AuthConfigExpander.getNoneSecurityConfig());
|
||||
if (noneSecurityFlag) {
|
||||
return true;
|
||||
}
|
||||
|
@ -45,17 +56,32 @@ public abstract class BaseSecurityInterceptor implements HandlerInterceptor {
|
|||
// 不做处理,因为本接口可能是不需要鉴权
|
||||
}
|
||||
|
||||
// 4. 获取ResourceDefinition,可能为null
|
||||
// 4. 如果token不为空,则先判断是否登录过期了,过期了就直接打回,不过期不做处理
|
||||
if (StrUtil.isNotBlank(token)) {
|
||||
try {
|
||||
authServiceApi.validateToken(token);
|
||||
} catch (AuthException authException) {
|
||||
if (AuthExceptionEnum.AUTH_EXPIRED_ERROR.getErrorCode().equals(authException.getErrorCode())) {
|
||||
sessionManagerApi.destroySessionCookie();
|
||||
throw authException;
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 刷新用户的session的过期时间
|
||||
sessionManagerApi.refreshSession(token);
|
||||
}
|
||||
|
||||
// 6. 获取ResourceDefinition,可能为null
|
||||
ResourceUrlParam resourceUrlParam = new ResourceUrlParam();
|
||||
resourceUrlParam.setUrl(requestURI);
|
||||
ResourceDefinition resourceDefinition = resourceServiceApi.getResourceByUrl(resourceUrlParam);
|
||||
|
||||
// 5. 资源找不到,则当前url不被权限控制,直接放行
|
||||
// 7. 资源找不到,则当前url不被权限控制,直接放行
|
||||
if (resourceDefinition == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 6.执行真正过滤器业务,如果拦截器执行不成功会抛出异常
|
||||
// 8.执行真正过滤器业务,如果拦截器执行不成功会抛出异常
|
||||
this.filterAction(request, response, resourceDefinition, token);
|
||||
|
||||
return true;
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package cn.stylefeng.guns.modular.error;
|
||||
|
||||
import cn.stylefeng.roses.kernel.resource.api.annotation.ApiResource;
|
||||
import cn.stylefeng.roses.kernel.resource.api.annotation.GetResource;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
|
||||
/**
|
||||
* 错误页面的跳转
|
||||
*
|
||||
* @author fengshuonan
|
||||
* @date 2021/1/1 21:20
|
||||
*/
|
||||
@Controller
|
||||
@ApiResource(name = "错误页面的跳转")
|
||||
public class ErrorViewController {
|
||||
|
||||
/**
|
||||
* 跳转到session超时页面
|
||||
*
|
||||
* @author fengshuonan
|
||||
* @date 2021/1/1 21:21
|
||||
*/
|
||||
@GetResource(name = "跳转到session超时页面", path = "/global/sessionError", requiredPermission = false, requiredLogin = false)
|
||||
public String errorPageInfo(Model model) {
|
||||
model.addAttribute("tips", "登陆超时,请您重新登陆!");
|
||||
return "/login.html";
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue