| | |
| | | package org.dromara.common.encrypt.filter; |
| | | |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import jakarta.servlet.*; |
| | | import jakarta.servlet.http.HttpServletRequest; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import org.dromara.common.core.constant.HttpStatus; |
| | | import org.dromara.common.core.exception.ServiceException; |
| | | import org.dromara.common.core.utils.SpringUtils; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.encrypt.annotation.ApiEncrypt; |
| | | import org.dromara.common.encrypt.properties.ApiDecryptProperties; |
| | | import org.springframework.http.HttpMethod; |
| | | import org.springframework.http.MediaType; |
| | | import org.springframework.web.method.HandlerMethod; |
| | | import org.springframework.web.servlet.HandlerExceptionResolver; |
| | | import org.springframework.web.servlet.HandlerExecutionChain; |
| | | import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; |
| | | |
| | | import java.io.IOException; |
| | | import java.util.Objects; |
| | | |
| | | |
| | | /** |
| | |
| | | |
| | | @Override |
| | | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { |
| | | ServletRequest requestWrapper = null; |
| | | HttpServletRequest servletRequest = (HttpServletRequest) request; |
| | | // 是否为 json 请求 |
| | | if (StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)) { |
| | | // 是否为 put 或者 post 请求 |
| | | if (HttpMethod.PUT.matches(servletRequest.getMethod()) || HttpMethod.POST.matches(servletRequest.getMethod())) { |
| | | // 是否存在加密标头 |
| | | String headerValue = servletRequest.getHeader(properties.getHeaderFlag()); |
| | | if (StringUtils.isNotBlank(headerValue)) { |
| | | requestWrapper = new DecryptRequestBodyWrapper(servletRequest, properties.getPublicKey(), properties.getPrivateKey(), properties.getHeaderFlag()); |
| | | HttpServletResponse servletResponse = (HttpServletResponse) response; |
| | | // 获取加密注解 |
| | | ApiEncrypt apiEncrypt = this.getApiEncryptAnnotation(servletRequest); |
| | | boolean responseFlag = apiEncrypt != null && apiEncrypt.response(); |
| | | ServletRequest requestWrapper = null; |
| | | ServletResponse responseWrapper = null; |
| | | EncryptResponseBodyWrapper responseBodyWrapper = null; |
| | | |
| | | // 是否为 put 或者 post 请求 |
| | | if (HttpMethod.PUT.matches(servletRequest.getMethod()) || HttpMethod.POST.matches(servletRequest.getMethod())) { |
| | | // 是否存在加密标头 |
| | | String headerValue = servletRequest.getHeader(properties.getHeaderFlag()); |
| | | if (StringUtils.isNotBlank(headerValue)) { |
| | | // 请求解密 |
| | | requestWrapper = new DecryptRequestBodyWrapper(servletRequest, properties.getPrivateKey(), properties.getHeaderFlag()); |
| | | } else { |
| | | // 是否有注解,有就报错,没有放行 |
| | | if (ObjectUtil.isNotNull(apiEncrypt)) { |
| | | HandlerExceptionResolver exceptionResolver = SpringUtils.getBean("handlerExceptionResolver", HandlerExceptionResolver.class); |
| | | exceptionResolver.resolveException( |
| | | servletRequest, servletResponse, null, |
| | | new ServiceException("没有访问权限,请联系管理员授权", HttpStatus.FORBIDDEN)); |
| | | return; |
| | | } |
| | | } |
| | | } |
| | | chain.doFilter(Objects.requireNonNullElse(requestWrapper, request), response); |
| | | |
| | | // 判断是否响应加密 |
| | | if (responseFlag) { |
| | | responseBodyWrapper = new EncryptResponseBodyWrapper(servletResponse); |
| | | responseWrapper = responseBodyWrapper; |
| | | } |
| | | |
| | | chain.doFilter( |
| | | ObjectUtil.defaultIfNull(requestWrapper, request), |
| | | ObjectUtil.defaultIfNull(responseWrapper, response)); |
| | | |
| | | if (responseFlag) { |
| | | servletResponse.reset(); |
| | | // 对原始内容加密 |
| | | String encryptContent = responseBodyWrapper.getEncryptContent( |
| | | servletResponse, properties.getPublicKey(), properties.getHeaderFlag()); |
| | | // 对加密后的内容写出 |
| | | servletResponse.getWriter().write(encryptContent); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 获取 ApiEncrypt 注解 |
| | | */ |
| | | private ApiEncrypt getApiEncryptAnnotation(HttpServletRequest servletRequest) { |
| | | RequestMappingHandlerMapping handlerMapping = SpringUtils.getBean("requestMappingHandlerMapping", RequestMappingHandlerMapping.class); |
| | | // 获取注解 |
| | | try { |
| | | HandlerExecutionChain mappingHandler = handlerMapping.getHandler(servletRequest); |
| | | if (ObjectUtil.isNotNull(mappingHandler)) { |
| | | Object handler = mappingHandler.getHandler(); |
| | | if (ObjectUtil.isNotNull(handler)) { |
| | | // 从handler获取注解 |
| | | if (handler instanceof HandlerMethod handlerMethod) { |
| | | return handlerMethod.getMethodAnnotation(ApiEncrypt.class); |
| | | } |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | return null; |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public void destroy() { |
| | | |
| | | } |
| | | } |