Browse Source

异常处理优化;安全认证优化

woody 1 year ago
parent
commit
76f66915ee

+ 15 - 6
framework-base/src/main/java/com/chelvc/framework/base/interceptor/GlobalExceptionInterceptor.java

@@ -188,13 +188,22 @@ public class GlobalExceptionInterceptor extends AbstractErrorController {
                 || e instanceof MultipartException || e instanceof HttpMessageConversionException
                 || e instanceof ServletRequestBindingException) {
             return Result.build(HttpStatus.BAD_REQUEST, null, e.getMessage());
-        } else if (e instanceof FrameworkException) {
-            FrameworkException exception = (FrameworkException) e;
-            return Result.build(exception.getStatus(), exception.getData(), exception.getMessage());
         }
-        boolean wrapping = SessionContextHolder.isResponseWrappingHeader(request);
-        String message = wrapping ? HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase() : e.getMessage();
-        return Result.build(HttpStatus.INTERNAL_SERVER_ERROR, null, message);
+
+        // 未知异常处理
+        Object data = null;
+        String message = e.getMessage();
+        HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR;
+        if (e instanceof FrameworkException) {
+            data = ((FrameworkException) e).getData();
+            status = ((FrameworkException) e).getStatus();
+        }
+
+        // 如果是5xx异常且需要返回包装类型则屏蔽详细的异常信息
+        if (status.is5xxServerError() && SessionContextHolder.isResponseWrappingHeader(request)) {
+            message = status.getReasonPhrase();
+        }
+        return Result.build(status, data, message);
     }
 
     /**

+ 17 - 19
framework-database/src/main/java/com/chelvc/framework/database/interceptor/DatabaseExceptionInterceptor.java

@@ -29,41 +29,39 @@ public class DatabaseExceptionInterceptor {
     /**
      * 参数异常转换
      *
-     * @param response  请求响应对象
-     * @param exception 异常对象
+     * @param request  Http请求对象
+     * @param response Http响应对象
+     * @param e        异常对象
      * @return 请求结果
      */
     @ResponseStatus(HttpStatus.PRECONDITION_FAILED)
     @ExceptionHandler(ParameterInvalidException.class)
-    public Result<?> exception(HttpServletRequest request, HttpServletResponse response,
-                               ParameterInvalidException exception) {
-        log.warn(SessionContextHolder.getLoggingMessage(request, HttpStatus.PRECONDITION_FAILED, exception));
-        Result<?> result = Result.build(HttpStatus.PRECONDITION_FAILED, exception.getData());
-        response.setStatus(result.getCode());
+    public Result<?> exception(HttpServletRequest request, HttpServletResponse response, ParameterInvalidException e) {
+        log.warn(SessionContextHolder.getLoggingMessage(request, HttpStatus.PRECONDITION_FAILED, e));
         SessionContextHolder.initializeResponseWrappingHeader(response);
-        return result;
+        return Result.build(HttpStatus.PRECONDITION_FAILED, e.getData());
     }
 
     /**
      * 数据持久化异常转换
      *
-     * @param response  请求响应对象
-     * @param exception 异常对象
+     * @param request  Http请求对象
+     * @param response Http响应对象
+     * @param e        异常对象
      * @return 请求结果
      */
     @ExceptionHandler(MyBatisSystemException.class)
-    public Result<?> exception(HttpServletRequest request, HttpServletResponse response,
-                               MyBatisSystemException exception) {
-        ParameterInvalidException parameterInvalidException =
-                ErrorUtils.lookup(exception, ParameterInvalidException.class);
+    public Result<?> exception(HttpServletRequest request, HttpServletResponse response, MyBatisSystemException e) {
+        ParameterInvalidException parameterInvalidException = ErrorUtils.lookup(e, ParameterInvalidException.class);
         if (parameterInvalidException != null) {
+            response.setStatus(HttpStatus.PRECONDITION_FAILED.value());
             return this.exception(request, response, parameterInvalidException);
         }
-        String message = SessionContextHolder.getLoggingMessage(request, HttpStatus.INTERNAL_SERVER_ERROR, exception);
-        log.error(message, exception);
-        Result<?> result = Result.build(HttpStatus.INTERNAL_SERVER_ERROR);
-        response.setStatus(result.getCode());
+        log.error(SessionContextHolder.getLoggingMessage(request, HttpStatus.INTERNAL_SERVER_ERROR, e), e);
+        response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
         SessionContextHolder.initializeResponseWrappingHeader(response);
-        return result;
+        boolean wrapping = SessionContextHolder.isResponseWrappingHeader(request);
+        String message = wrapping ? HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase() : e.getMessage();
+        return Result.build(HttpStatus.INTERNAL_SERVER_ERROR, null, message);
     }
 }

+ 8 - 6
framework-oauth/src/main/java/com/chelvc/framework/oauth/interceptor/OauthExceptionInterceptor.java

@@ -27,16 +27,18 @@ public class OauthExceptionInterceptor {
     /**
      * 认证异常转换
      *
-     * @param response  请求响应对象
-     * @param exception 异常对象
+     * @param request  Http请求对象
+     * @param response Http响应对象
+     * @param e        异常对象
      * @return 请求结果
      */
     @ResponseStatus(HttpStatus.UNAUTHORIZED)
     @ExceptionHandler(BadCredentialsException.class)
-    public Result<?> exception(HttpServletRequest request, HttpServletResponse response,
-                               BadCredentialsException exception) {
-        log.warn(SessionContextHolder.getLoggingMessage(request, HttpStatus.UNAUTHORIZED, exception));
+    public Result<?> exception(HttpServletRequest request, HttpServletResponse response, BadCredentialsException e) {
+        log.warn(SessionContextHolder.getLoggingMessage(request, HttpStatus.UNAUTHORIZED, e));
         SessionContextHolder.initializeResponseWrappingHeader(response);
-        return Result.build(HttpStatus.UNAUTHORIZED);
+        boolean wrapping = SessionContextHolder.isResponseWrappingHeader(request);
+        String message = wrapping ? HttpStatus.UNAUTHORIZED.getReasonPhrase() : e.getMessage();
+        return Result.build(HttpStatus.UNAUTHORIZED, null, message);
     }
 }

+ 10 - 0
framework-security/src/main/java/com/chelvc/framework/security/config/SecurityProperties.java

@@ -44,6 +44,11 @@ public class SecurityProperties {
          */
         private String[] permit;
 
+        /**
+         * 必须校验的资源地址,多个地址使用","号隔开
+         */
+        private String[] require;
+
         /**
          * 允许的请求耗时(毫秒)
          */
@@ -59,5 +64,10 @@ public class SecurityProperties {
          * 放行资源地址,多个地址使用","号隔开
          */
         private String[] permit;
+
+        /**
+         * 必须校验的资源地址,多个地址使用","号隔开
+         */
+        private String[] require;
     }
 }

+ 4 - 1
framework-security/src/main/java/com/chelvc/framework/security/interceptor/RequestSecurityInterceptor.java

@@ -13,6 +13,7 @@ import com.chelvc.framework.base.context.SessionContextHolder;
 import com.chelvc.framework.base.model.Result;
 import com.chelvc.framework.base.util.HttpUtils;
 import com.chelvc.framework.base.util.SpringUtils;
+import com.chelvc.framework.common.util.ObjectUtils;
 import com.chelvc.framework.common.util.StringUtils;
 import com.chelvc.framework.security.config.SecurityProperties;
 import com.chelvc.framework.security.context.SecurityContextHolder;
@@ -46,8 +47,10 @@ public class RequestSecurityInterceptor implements Filter {
         }
 
         // 判断是否需要放行
+        String uri = HttpUtils.getRequestURI(request);
         SecurityProperties.Request configuration = SecurityContextHolder.getProperties().getRequest();
-        if (SpringUtils.isPath(HttpUtils.getRequestURI(request), configuration.getPermit())) {
+        if (SpringUtils.isPath(uri, configuration.getPermit()) || (ObjectUtils.nonEmpty(configuration.getRequire())
+                && !SpringUtils.isPath(uri, configuration.getRequire()))) {
             return true;
         }
 

+ 8 - 6
framework-security/src/main/java/com/chelvc/framework/security/interceptor/SecurityExceptionInterceptor.java

@@ -27,16 +27,18 @@ public class SecurityExceptionInterceptor {
     /**
      * 拒绝访问异常转换
      *
-     * @param response  请求响应对象
-     * @param exception 异常对象
+     * @param request  Http请求对象
+     * @param response Http响应对象
+     * @param e        异常对象
      * @return 请求结果
      */
     @ResponseStatus(HttpStatus.FORBIDDEN)
     @ExceptionHandler(AccessDeniedException.class)
-    public Result<?> exception(HttpServletRequest request, HttpServletResponse response,
-                               AccessDeniedException exception) {
-        log.warn(SessionContextHolder.getLoggingMessage(request, HttpStatus.FORBIDDEN, exception));
+    public Result<?> exception(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e) {
+        log.warn(SessionContextHolder.getLoggingMessage(request, HttpStatus.FORBIDDEN, e));
         SessionContextHolder.initializeResponseWrappingHeader(response);
-        return Result.build(HttpStatus.FORBIDDEN);
+        boolean wrapping = SessionContextHolder.isResponseWrappingHeader(request);
+        String message = wrapping ? HttpStatus.FORBIDDEN.getReasonPhrase() : e.getMessage();
+        return Result.build(HttpStatus.FORBIDDEN, null, message);
     }
 }

+ 5 - 1
framework-security/src/main/java/com/chelvc/framework/security/interceptor/SignatureValidateInterceptor.java

@@ -15,6 +15,7 @@ import com.chelvc.framework.base.model.Result;
 import com.chelvc.framework.base.util.HttpUtils;
 import com.chelvc.framework.base.util.SpringUtils;
 import com.chelvc.framework.common.util.CodecUtils;
+import com.chelvc.framework.common.util.ObjectUtils;
 import com.chelvc.framework.security.config.SecurityProperties;
 import com.chelvc.framework.security.context.SecurityContextHolder;
 import lombok.extern.slf4j.Slf4j;
@@ -47,8 +48,11 @@ public class SignatureValidateInterceptor implements Filter {
         }
 
         // 判断请求是否需要放行
+        String uri = HttpUtils.getRequestURI(request);
         SecurityProperties properties = SecurityContextHolder.getProperties();
-        if (SpringUtils.isPath(HttpUtils.getRequestURI(request), properties.getSignature().getPermit())) {
+        SecurityProperties.Signature configuration = properties.getSignature();
+        if (SpringUtils.isPath(uri, configuration.getPermit()) || (ObjectUtils.nonEmpty(configuration.getRequire())
+                && !SpringUtils.isPath(uri, configuration.getRequire()))) {
             return true;
         }