mirror of https://gitee.com/maxjhandsome/pig
commit
cd387aa904
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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("验证码不合法");
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue