From 51dc2a5d5a21050cf1957a8d8b4b5a833af25d33 Mon Sep 17 00:00:00 2001 From: lbw Date: Wed, 10 Jan 2024 16:37:23 +0800 Subject: [PATCH] =?UTF-8?q?:recycle:=20Refactoring=20code.=20=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E7=BD=91=E5=85=B3filter=20=E5=88=A4=E6=96=AD=E9=80=BB?= =?UTF-8?q?=E8=BE=91=EF=BC=8C=E9=9D=9E=E5=AF=86=E7=A0=81=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?=E7=9B=B4=E6=8E=A5=E8=B7=B3=E8=BF=87=20PasswordDecoderFilter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/PigDaoAuthenticationProvider.java | 5 +- .../core/constant/SecurityConstants.java | 5 + .../gateway/filter/PasswordDecoderFilter.java | 174 +++++++++--------- 3 files changed, 98 insertions(+), 86 deletions(-) diff --git a/pig-auth/src/main/java/com/pig4cloud/pig/auth/support/core/PigDaoAuthenticationProvider.java b/pig-auth/src/main/java/com/pig4cloud/pig/auth/support/core/PigDaoAuthenticationProvider.java index 67463377..b587d68b 100644 --- a/pig-auth/src/main/java/com/pig4cloud/pig/auth/support/core/PigDaoAuthenticationProvider.java +++ b/pig-auth/src/main/java/com/pig4cloud/pig/auth/support/core/PigDaoAuthenticationProvider.java @@ -20,6 +20,7 @@ import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.factory.PasswordEncoderFactories; import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.oauth2.core.AuthorizationGrantType; import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; import org.springframework.security.web.authentication.www.BasicAuthenticationConverter; import org.springframework.util.Assert; @@ -67,9 +68,9 @@ public class PigDaoAuthenticationProvider extends AbstractUserDetailsAuthenticat protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { - // app 模式不用校验密码 + // 只有密码模式需要校验密码 String grantType = WebUtils.getRequest().get().getParameter(OAuth2ParameterNames.GRANT_TYPE); - if (StrUtil.equals(SecurityConstants.MOBILE, grantType)) { + if (!StrUtil.equals(AuthorizationGrantType.PASSWORD.getValue(), grantType)) { return; } diff --git a/pig-common/pig-common-core/src/main/java/com/pig4cloud/pig/common/core/constant/SecurityConstants.java b/pig-common/pig-common-core/src/main/java/com/pig4cloud/pig/common/core/constant/SecurityConstants.java index acda5fa6..fe757be2 100755 --- a/pig-common/pig-common-core/src/main/java/com/pig4cloud/pig/common/core/constant/SecurityConstants.java +++ b/pig-common/pig-common-core/src/main/java/com/pig4cloud/pig/common/core/constant/SecurityConstants.java @@ -62,6 +62,11 @@ public interface SecurityConstants { */ String REFRESH_TOKEN = "refresh_token"; + /** + * password 模式 + */ + String PASSWORD = "password"; + /** * 手机号登录 */ diff --git a/pig-gateway/src/main/java/com/pig4cloud/pig/gateway/filter/PasswordDecoderFilter.java b/pig-gateway/src/main/java/com/pig4cloud/pig/gateway/filter/PasswordDecoderFilter.java index c5b916bd..61c18ef6 100755 --- a/pig-gateway/src/main/java/com/pig4cloud/pig/gateway/filter/PasswordDecoderFilter.java +++ b/pig-gateway/src/main/java/com/pig4cloud/pig/gateway/filter/PasswordDecoderFilter.java @@ -20,6 +20,7 @@ import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.Mode; import cn.hutool.crypto.Padding; +import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.symmetric.AES; import cn.hutool.http.HttpUtil; import com.pig4cloud.pig.common.core.constant.SecurityConstants; @@ -59,102 +60,107 @@ import java.util.function.Function; @RequiredArgsConstructor public class PasswordDecoderFilter extends AbstractGatewayFilterFactory { - private static final List> messageReaders = HandlerStrategies.withDefaults().messageReaders(); + private static final List> messageReaders = HandlerStrategies.withDefaults().messageReaders(); - private static final String PASSWORD = "password"; + private static final String PASSWORD = "password"; - private static final String KEY_ALGORITHM = "AES"; + private static final String KEY_ALGORITHM = "AES"; - private final GatewayConfigProperties gatewayConfig; + private final GatewayConfigProperties gatewayConfig; - @Override - public GatewayFilter apply(Object config) { - return (exchange, chain) -> { - ServerHttpRequest request = exchange.getRequest(); - // 1. 不是登录请求,直接向下执行 - if (!StrUtil.containsAnyIgnoreCase(request.getURI().getPath(), SecurityConstants.OAUTH_TOKEN_URL)) { - return chain.filter(exchange); - } + static { + // 关闭hutool 强制关闭Bouncy Castle库的依赖 + SecureUtil.disableBouncyCastle(); + } - // 2. 刷新token类型,直接向下执行 - String grantType = request.getQueryParams().getFirst("grant_type"); - if (StrUtil.equals(SecurityConstants.REFRESH_TOKEN, grantType)) { - return chain.filter(exchange); - } + @Override + public GatewayFilter apply(Object config) { + return (exchange, chain) -> { + ServerHttpRequest request = exchange.getRequest(); + // 1. 不是登录请求,直接向下执行 + if (!StrUtil.containsAnyIgnoreCase(request.getURI().getPath(), SecurityConstants.OAUTH_TOKEN_URL)) { + return chain.filter(exchange); + } - // 3. 前端加密密文解密逻辑 - Class inClass = String.class; - Class outClass = String.class; - ServerRequest serverRequest = ServerRequest.create(exchange, messageReaders); + // 2. 不是密码登录模式直接跳过 + String grantType = request.getQueryParams().getFirst("grant_type"); + if (!StrUtil.equals(SecurityConstants.PASSWORD, grantType)) { + return chain.filter(exchange); + } - // 4. 解密生成新的报文 - Mono modifiedBody = serverRequest.bodyToMono(inClass).flatMap(decryptAES()); + // 3. 前端加密密文解密逻辑 + Class inClass = String.class; + Class outClass = String.class; + ServerRequest serverRequest = ServerRequest.create(exchange, messageReaders); - BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody, outClass); - HttpHeaders headers = new HttpHeaders(); - headers.putAll(exchange.getRequest().getHeaders()); - headers.remove(HttpHeaders.CONTENT_LENGTH); + // 4. 解密生成新的报文 + Mono modifiedBody = serverRequest.bodyToMono(inClass).flatMap(decryptAES()); - headers.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE); - CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, headers); - return bodyInserter.insert(outputMessage, new BodyInserterContext()).then(Mono.defer(() -> { - ServerHttpRequest decorator = decorate(exchange, headers, outputMessage); - return chain.filter(exchange.mutate().request(decorator).build()); - })); - }; - } + BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody, outClass); + HttpHeaders headers = new HttpHeaders(); + headers.putAll(exchange.getRequest().getHeaders()); + headers.remove(HttpHeaders.CONTENT_LENGTH); - /** - * 原文解密 - * @return - */ - private Function decryptAES() { - return s -> { - // 构建前端对应解密AES 因子 - AES aes = new AES(Mode.CFB, Padding.NoPadding, - new SecretKeySpec(gatewayConfig.getEncodeKey().getBytes(), KEY_ALGORITHM), - new IvParameterSpec(gatewayConfig.getEncodeKey().getBytes())); + headers.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE); + CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, headers); + return bodyInserter.insert(outputMessage, new BodyInserterContext()).then(Mono.defer(() -> { + ServerHttpRequest decorator = decorate(exchange, headers, outputMessage); + return chain.filter(exchange.mutate().request(decorator).build()); + })); + }; + } - // 获取请求密码并解密 - Map inParamsMap = HttpUtil.decodeParamMap((String) s, CharsetUtil.CHARSET_UTF_8); - if (inParamsMap.containsKey(PASSWORD)) { - String password = aes.decryptStr(inParamsMap.get(PASSWORD)); - // 返回修改后报文字符 - inParamsMap.put(PASSWORD, password); - } - else { - log.error("非法请求数据:{}", s); - } - return Mono.just(HttpUtil.toParams(inParamsMap, Charset.defaultCharset(), true)); - }; - } + /** + * 原文解密 + * + * @return + */ + private Function decryptAES() { + return s -> { + // 构建前端对应解密AES 因子 + AES aes = new AES(Mode.CFB, Padding.NoPadding, + new SecretKeySpec(gatewayConfig.getEncodeKey().getBytes(), KEY_ALGORITHM), + new IvParameterSpec(gatewayConfig.getEncodeKey().getBytes())); - /** - * 报文转换 - * @return - */ - private ServerHttpRequestDecorator decorate(ServerWebExchange exchange, HttpHeaders headers, - CachedBodyOutputMessage outputMessage) { - return new ServerHttpRequestDecorator(exchange.getRequest()) { - @Override - public HttpHeaders getHeaders() { - long contentLength = headers.getContentLength(); - HttpHeaders httpHeaders = new HttpHeaders(); - httpHeaders.putAll(super.getHeaders()); - if (contentLength > 0) { - httpHeaders.setContentLength(contentLength); - } - else { - httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked"); - } - return httpHeaders; - } + // 获取请求密码并解密 + Map inParamsMap = HttpUtil.decodeParamMap((String) s, CharsetUtil.CHARSET_UTF_8); + if (inParamsMap.containsKey(PASSWORD)) { + String password = aes.decryptStr(inParamsMap.get(PASSWORD)); + // 返回修改后报文字符 + inParamsMap.put(PASSWORD, password); + } else { + log.error("非法请求数据:{}", s); + } + return Mono.just(HttpUtil.toParams(inParamsMap, Charset.defaultCharset(), true)); + }; + } - @Override - public Flux getBody() { - return outputMessage.getBody(); - } - }; - } + /** + * 报文转换 + * + * @return + */ + private ServerHttpRequestDecorator decorate(ServerWebExchange exchange, HttpHeaders headers, + CachedBodyOutputMessage outputMessage) { + return new ServerHttpRequestDecorator(exchange.getRequest()) { + @Override + public HttpHeaders getHeaders() { + long contentLength = headers.getContentLength(); + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.putAll(super.getHeaders()); + if (contentLength > 0) { + httpHeaders.setContentLength(contentLength); + } else { + httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked"); + } + return httpHeaders; + } + + @Override + public Flux getBody() { + return outputMessage.getBody(); + } + }; + } }