!113 重构网关

Merge pull request !113 from huwenfeng/master
This commit is contained in:
lengleng 2021-06-11 15:57:16 +08:00 committed by Gitee
commit cd387aa904
6 changed files with 48 additions and 59 deletions

View File

@ -20,11 +20,11 @@ public class GatewayConfigProperties {
/**
* 网关解密登录前端密码 秘钥 {@link com.pig4cloud.pig.gateway.filter.PasswordDecoderFilter}
*/
public String encodeKey;
private String encodeKey;
/**
* 网关不需要校验验证码的客户端 {@link com.pig4cloud.pig.gateway.filter.ValidateCodeGatewayFilter}
*/
public List<String> ignoreClients;
private List<String> ignoreClients;
}

View File

@ -20,6 +20,7 @@ import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;
import java.util.Objects;
/**
* @author lengleng
@ -28,9 +29,16 @@ import reactor.core.publisher.Mono;
@Configuration(proxyBeanMethods = false)
public class RateLimiterConfiguration {
@Bean(value = "remoteAddrKeyResolver")
/**
* Remote addr key resolver key resolver.
*
* @link {https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#the-requestratelimiter-gatewayfilter-factory}
*/
@Bean
public KeyResolver remoteAddrKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
return exchange -> Mono
.just(Objects.requireNonNull(Objects.requireNonNull(exchange.getRequest().getRemoteAddress()))
.getAddress().getHostAddress());
}
}

View File

@ -22,9 +22,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RequestPredicates;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.*;
/**
* 路由配置信息
@ -40,7 +38,7 @@ public class RouterFunctionConfiguration {
private final ImageCodeHandler imageCodeHandler;
@Bean
public RouterFunction routerFunction() {
public RouterFunction<ServerResponse> routerFunction() {
return RouterFunctions.route(
RequestPredicates.path("/code").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), imageCodeHandler);
}

View File

@ -17,8 +17,8 @@
package com.pig4cloud.pig.gateway.filter;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.text.CharSequenceUtil;
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.symmetric.AES;
@ -41,7 +41,7 @@ import java.util.Map;
/**
* @author lengleng
* @date 2019/2/1 密码解密工具类
* @date 2019 /2/1 密码解密工具类
*/
@Slf4j
@RequiredArgsConstructor
@ -53,20 +53,13 @@ public class PasswordDecoderFilter extends AbstractGatewayFilterFactory {
private final GatewayConfigProperties configProperties;
private static String decryptAES(String data, String pass) {
AES aes = new AES(Mode.CBC, Padding.NoPadding, new SecretKeySpec(pass.getBytes(), KEY_ALGORITHM),
new IvParameterSpec(pass.getBytes()));
byte[] result = aes.decrypt(Base64.decode(data.getBytes(StandardCharsets.UTF_8)));
return new String(result, StandardCharsets.UTF_8);
}
@Override
public GatewayFilter apply(Object config) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
// 不是登录请求直接向下执行
if (!StrUtil.containsAnyIgnoreCase(request.getURI().getPath(), SecurityConstants.OAUTH_TOKEN_URL)) {
if (!CharSequenceUtil.containsAnyIgnoreCase(request.getURI().getPath(), SecurityConstants.OAUTH_TOKEN_URL)) {
return chain.filter(exchange);
}
@ -75,9 +68,9 @@ public class PasswordDecoderFilter extends AbstractGatewayFilterFactory {
Map<String, String> paramMap = HttpUtil.decodeParamMap(queryParam, CharsetUtil.CHARSET_UTF_8);
String password = paramMap.get(PASSWORD);
if (StrUtil.isNotBlank(password)) {
if (CharSequenceUtil.isNotBlank(password)) {
try {
password = decryptAES(password, configProperties.getEncodeKey());
password = decrypt(password, configProperties.getEncodeKey());
}
catch (Exception e) {
log.error("密码解密失败:{}", password);
@ -94,4 +87,11 @@ public class PasswordDecoderFilter extends AbstractGatewayFilterFactory {
};
}
private static String decrypt(String data, String pass) {
AES aes = new AES(Mode.CBC, Padding.NoPadding, new SecretKeySpec(pass.getBytes(), KEY_ALGORITHM),
new IvParameterSpec(pass.getBytes()));
byte[] result = aes.decrypt(Base64.decode(data.getBytes(StandardCharsets.UTF_8)));
return new String(result, StandardCharsets.UTF_8);
}
}

View File

@ -16,6 +16,7 @@
package com.pig4cloud.pig.gateway.filter;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
@ -39,44 +40,34 @@ import org.springframework.http.server.reactive.ServerHttpResponse;
import reactor.core.publisher.Mono;
/**
* The type Validate code gateway filter.
*
* @author lengleng
* @date 2018/7/4 验证码处理
* @date 2018 /7/4 验证码处理
*/
@Slf4j
@RequiredArgsConstructor
public class ValidateCodeGatewayFilter extends AbstractGatewayFilterFactory {
public class ValidateCodeGatewayFilter extends AbstractGatewayFilterFactory<Object> {
private final GatewayConfigProperties configProperties;
private final ObjectMapper objectMapper;
private final RedisTemplate redisTemplate;
private final RedisTemplate<String, Object> redisTemplate;
@Override
public GatewayFilter apply(Object config) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
// 不是登录请求直接向下执行
if (!StrUtil.containsAnyIgnoreCase(request.getURI().getPath(), SecurityConstants.OAUTH_TOKEN_URL)) {
return chain.filter(exchange);
}
// 刷新token直接向下执行
String grantType = request.getQueryParams().getFirst("grant_type");
if (StrUtil.equals(SecurityConstants.REFRESH_TOKEN, grantType)) {
return chain.filter(exchange);
}
// 终端设置不校验 直接向下执行
boolean isAuthToken = CharSequenceUtil.containsAnyIgnoreCase(request.getURI().getPath(),
SecurityConstants.OAUTH_TOKEN_URL);
boolean isIgnoreClient = configProperties.getIgnoreClients()
.contains(WebUtils.getClientId(request)[0]);
try {
String[] clientInfos = WebUtils.getClientId(request);
if (configProperties.getIgnoreClients().contains(clientInfos[0])) {
return chain.filter(exchange);
// only oauth and the request not in ignore clients need check code.
if (isAuthToken && !isIgnoreClient) {
checkCode(request);
}
// 校验验证码
checkCode(request);
}
catch (Exception e) {
ServerHttpResponse response = exchange.getResponse();
@ -102,25 +93,21 @@ public class ValidateCodeGatewayFilter extends AbstractGatewayFilterFactory {
};
}
/**
* 检查code
* @param request
*/
@SneakyThrows
private void checkCode(ServerHttpRequest request) {
String code = request.getQueryParams().getFirst("code");
if (StrUtil.isBlank(code)) {
if (CharSequenceUtil.isBlank(code)) {
throw new ValidateCodeException("验证码不能为空");
}
String randomStr = request.getQueryParams().getFirst("randomStr");
if (StrUtil.isBlank(randomStr)) {
if (CharSequenceUtil.isBlank(randomStr)) {
randomStr = request.getQueryParams().getFirst("mobile");
}
String key = CacheConstants.DEFAULT_CODE_KEY + randomStr;
if (!redisTemplate.hasKey(key)) {
if (Boolean.FALSE.equals(redisTemplate.hasKey(key))) {
throw new ValidateCodeException("验证码不合法");
}
@ -131,12 +118,7 @@ public class ValidateCodeGatewayFilter extends AbstractGatewayFilterFactory {
}
String saveCode = codeObj.toString();
if (StrUtil.isBlank(saveCode)) {
redisTemplate.delete(key);
throw new ValidateCodeException("验证码不合法");
}
if (!StrUtil.equals(saveCode, code)) {
if (CharSequenceUtil.isBlank(saveCode)) {
redisTemplate.delete(key);
throw new ValidateCodeException("验证码不合法");
}

View File

@ -33,6 +33,7 @@ import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
/**
@ -47,7 +48,7 @@ public class ImageCodeHandler implements HandlerFunction<ServerResponse> {
private static final Integer DEFAULT_IMAGE_HEIGHT = 40;
private final RedisTemplate redisTemplate;
private final RedisTemplate<String, Object> redisTemplate;
@Override
public Mono<ServerResponse> handle(ServerRequest serverRequest) {
@ -56,10 +57,10 @@ public class ImageCodeHandler implements HandlerFunction<ServerResponse> {
String result = captcha.text();
// 保存验证码信息
String randomStr = serverRequest.queryParam("randomStr").get();
Optional<String> randomStr = serverRequest.queryParam("randomStr");
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.opsForValue().set(CacheConstants.DEFAULT_CODE_KEY + randomStr, result,
SecurityConstants.CODE_TIME, TimeUnit.SECONDS);
randomStr.ifPresent(s -> redisTemplate.opsForValue().set(CacheConstants.DEFAULT_CODE_KEY + s, result,
SecurityConstants.CODE_TIME, TimeUnit.SECONDS));
// 转换流信息写出
FastByteArrayOutputStream os = new FastByteArrayOutputStream();