1.增加session超时的跳转

2.从新整理过滤器,refreshSession放到base拦截器
3.全局异常拦截器,特殊考虑session超时情况
pull/65/head
fengshuonan 2021-01-02 22:24:02 +08:00
parent 33c42e144d
commit 3e049fc14d
5 changed files with 103 additions and 20 deletions

View File

@ -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>

View File

@ -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>
* ajaxresponseheadersession-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;
}
/**
*
*

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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";
}
}