全项目代码格式化

This commit is contained in:
疯狂的狮子li
2021-12-31 16:31:17 +08:00
parent a53db40b49
commit db9fd081e6
239 changed files with 4509 additions and 9471 deletions

View File

@@ -6,14 +6,12 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
/**
* 网关启动程序
*
*
* @author ruoyi
*/
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
public class RuoYiGatewayApplication
{
public static void main(String[] args)
{
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class RuoYiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(RuoYiGatewayApplication.class, args);
System.out.println("(♥◠‿◠)ノ゙ 若依网关启动成功 ლ(´ڡ`ლ)゙ ");
}

View File

@@ -13,73 +13,73 @@ import com.ruoyi.common.core.utils.StringUtils;
*/
public class UnsignedMathGenerator implements CodeGenerator {
private static final long serialVersionUID = -5514819971774091076L;
private static final long serialVersionUID = -5514819971774091076L;
private static final String operators = "+-*";
private static final String operators = "+-*";
/**
* 参与计算数字最大长度
*/
private final int numberLength;
/**
* 参与计算数字最大长度
*/
private final int numberLength;
/**
* 构造
*/
public UnsignedMathGenerator() {
this(2);
}
/**
* 构造
*/
public UnsignedMathGenerator() {
this(2);
}
/**
* 构造
*
* @param numberLength 参与计算最大数字位数
*/
public UnsignedMathGenerator(int numberLength) {
this.numberLength = numberLength;
}
/**
* 构造
*
* @param numberLength 参与计算最大数字位数
*/
public UnsignedMathGenerator(int numberLength) {
this.numberLength = numberLength;
}
@Override
public String generate() {
final int limit = getLimit();
int min = RandomUtil.randomInt(limit);
int max = RandomUtil.randomInt(min, limit);
String number1 = Integer.toString(max);
String number2 = Integer.toString(min);
number1 = StringUtils.rightPad(number1, this.numberLength, CharUtil.SPACE);
number2 = StringUtils.rightPad(number2, this.numberLength, CharUtil.SPACE);
@Override
public String generate() {
final int limit = getLimit();
int min = RandomUtil.randomInt(limit);
int max = RandomUtil.randomInt(min, limit);
String number1 = Integer.toString(max);
String number2 = Integer.toString(min);
number1 = StringUtils.rightPad(number1, this.numberLength, CharUtil.SPACE);
number2 = StringUtils.rightPad(number2, this.numberLength, CharUtil.SPACE);
return number1 + RandomUtil.randomChar(operators) + number2 + '=';
}
return number1 + RandomUtil.randomChar(operators) + number2 + '=';
}
@Override
public boolean verify(String code, String userInputCode) {
int result;
try {
result = Integer.parseInt(userInputCode);
} catch (NumberFormatException e) {
// 用户输入非数字
return false;
}
@Override
public boolean verify(String code, String userInputCode) {
int result;
try {
result = Integer.parseInt(userInputCode);
} catch (NumberFormatException e) {
// 用户输入非数字
return false;
}
final int calculateResult = (int) Calculator.conversion(code);
return result == calculateResult;
}
final int calculateResult = (int) Calculator.conversion(code);
return result == calculateResult;
}
/**
* 获取验证码长度
*
* @return 验证码长度
*/
public int getLength() {
return this.numberLength * 2 + 2;
}
/**
* 获取验证码长度
*
* @return 验证码长度
*/
public int getLength() {
return this.numberLength * 2 + 2;
}
/**
* 根据长度获取参与计算数字最大值
*
* @return 最大值
*/
private int getLimit() {
return Integer.parseInt("1" + StringUtils.repeat('0', this.numberLength));
}
/**
* 根据长度获取参与计算数字最大值
*
* @return 最大值
*/
private int getLimit() {
return Integer.parseInt("1" + StringUtils.repeat('0', this.numberLength));
}
}

View File

@@ -1,23 +1,21 @@
package com.ruoyi.gateway.config;
import com.ruoyi.gateway.handler.SentinelFallbackHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import com.ruoyi.gateway.handler.SentinelFallbackHandler;
/**
* 网关限流配置
*
*
* @author ruoyi
*/
@Configuration
public class GatewayConfig
{
public class GatewayConfig {
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SentinelFallbackHandler sentinelGatewayExceptionHandler()
{
public SentinelFallbackHandler sentinelGatewayExceptionHandler() {
return new SentinelFallbackHandler();
}
}

View File

@@ -1,5 +1,6 @@
package com.ruoyi.gateway.config;
import com.ruoyi.gateway.handler.ValidateCodeHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -7,23 +8,20 @@ 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 com.ruoyi.gateway.handler.ValidateCodeHandler;
/**
* 路由配置信息
*
*
* @author ruoyi
*/
@Configuration
public class RouterFunctionConfiguration
{
public class RouterFunctionConfiguration {
@Autowired
private ValidateCodeHandler validateCodeHandler;
@SuppressWarnings("rawtypes")
@Bean
public RouterFunction routerFunction()
{
public RouterFunction routerFunction() {
return RouterFunctions.route(
RequestPredicates.GET("/code").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)),
validateCodeHandler);

View File

@@ -1,7 +1,5 @@
package com.ruoyi.gateway.config;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.config.GatewayProperties;
import org.springframework.cloud.gateway.route.RouteLocator;
@@ -12,14 +10,16 @@ import org.springframework.web.reactive.config.WebFluxConfigurer;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;
import java.util.ArrayList;
import java.util.List;
/**
* 聚合系统接口
*
*
* @author ruoyi
*/
@Component
public class SwaggerProvider implements SwaggerResourcesProvider, WebFluxConfigurer
{
public class SwaggerProvider implements SwaggerResourcesProvider, WebFluxConfigurer {
/**
* Swagger2默认的url后缀
*/
@@ -35,12 +35,11 @@ public class SwaggerProvider implements SwaggerResourcesProvider, WebFluxConfigu
/**
* 聚合其他服务接口
*
*
* @return
*/
@Override
public List<SwaggerResource> get()
{
public List<SwaggerResource> get() {
List<SwaggerResource> resourceList = new ArrayList<>();
List<String> routes = new ArrayList<>();
// 获取网关中配置的route
@@ -57,8 +56,7 @@ public class SwaggerProvider implements SwaggerResourcesProvider, WebFluxConfigu
return resourceList;
}
private SwaggerResource swaggerResource(String name, String location)
{
private SwaggerResource swaggerResource(String name, String location) {
SwaggerResource swaggerResource = new SwaggerResource();
swaggerResource.setName(name);
swaggerResource.setLocation(location);
@@ -67,8 +65,7 @@ public class SwaggerProvider implements SwaggerResourcesProvider, WebFluxConfigu
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
public void addResourceHandlers(ResourceHandlerRegistry registry) {
/** swagger-ui 地址 */
registry.addResourceHandler("/swagger-ui/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/");

View File

@@ -9,15 +9,14 @@ import org.springframework.context.annotation.Configuration;
/**
* 验证码配置
*
*
* @author ruoyi
*/
@Data
@Configuration
@RefreshScope
@ConfigurationProperties(prefix = "security.captcha")
public class CaptchaProperties
{
public class CaptchaProperties {
/**
* 验证码类型
*/

View File

@@ -1,14 +1,15 @@
package com.ruoyi.gateway.config.properties;
import java.util.ArrayList;
import java.util.List;
import lombok.*;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
/**
* 放行白名单配置
*

View File

@@ -1,24 +1,23 @@
package com.ruoyi.gateway.config.properties;
import java.util.ArrayList;
import java.util.List;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
/**
* XSS跨站脚本配置
*
*
* @author ruoyi
*/
@Data
@Configuration
@RefreshScope
@ConfigurationProperties(prefix = "security.xss")
public class XssProperties
{
public class XssProperties {
/**
* Xss开关
*/

View File

@@ -23,12 +23,11 @@ import reactor.core.publisher.Mono;
/**
* 网关鉴权
*
*
* @author ruoyi
*/
@Component
public class AuthFilter implements GlobalFilter, Ordered
{
public class AuthFilter implements GlobalFilter, Ordered {
private static final Logger log = LoggerFactory.getLogger(AuthFilter.class);
// 排除过滤的 uri 地址nacos自行添加
@@ -36,37 +35,31 @@ public class AuthFilter implements GlobalFilter, Ordered
private IgnoreWhiteProperties ignoreWhite;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
{
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpRequest.Builder mutate = request.mutate();
String url = request.getURI().getPath();
// 跳过不需要验证的路径
if (StringUtils.matches(url, ignoreWhite.getWhites()))
{
if (StringUtils.matches(url, ignoreWhite.getWhites())) {
return chain.filter(exchange);
}
String token = getToken(request);
if (StringUtils.isEmpty(token))
{
if (StringUtils.isEmpty(token)) {
return unauthorizedResponse(exchange, "令牌不能为空");
}
JSONObject claims = JwtUtils.parseToken(token);
if (claims == null)
{
if (claims == null) {
return unauthorizedResponse(exchange, "令牌已过期或验证不正确!");
}
String userkey = JwtUtils.getUserKey(claims);
boolean islogin = RedisUtils.hasKey(getTokenKey(userkey));
if (!islogin)
{
if (!islogin) {
return unauthorizedResponse(exchange, "登录状态已过期");
}
String userid = JwtUtils.getUserId(claims);
String username = JwtUtils.getUserName(claims);
if (StringUtils.isEmpty(userid) || StringUtils.isEmpty(username))
{
if (StringUtils.isEmpty(userid) || StringUtils.isEmpty(username)) {
return unauthorizedResponse(exchange, "令牌验证失败");
}
@@ -79,10 +72,8 @@ public class AuthFilter implements GlobalFilter, Ordered
return chain.filter(exchange.mutate().request(mutate.build()).build());
}
private void addHeader(ServerHttpRequest.Builder mutate, String name, Object value)
{
if (value == null)
{
private void addHeader(ServerHttpRequest.Builder mutate, String name, Object value) {
if (value == null) {
return;
}
String valueStr = value.toString();
@@ -90,13 +81,11 @@ public class AuthFilter implements GlobalFilter, Ordered
mutate.header(name, valueEncode);
}
private void removeHeader(ServerHttpRequest.Builder mutate, String name)
{
private void removeHeader(ServerHttpRequest.Builder mutate, String name) {
mutate.headers(httpHeaders -> httpHeaders.remove(name)).build();
}
private Mono<Void> unauthorizedResponse(ServerWebExchange exchange, String msg)
{
private Mono<Void> unauthorizedResponse(ServerWebExchange exchange, String msg) {
log.error("[鉴权异常处理]请求路径:{}", exchange.getRequest().getPath());
return ServletUtils.webFluxResponseWriter(exchange.getResponse(), msg, HttpStatus.UNAUTHORIZED);
}
@@ -104,28 +93,24 @@ public class AuthFilter implements GlobalFilter, Ordered
/**
* 获取缓存key
*/
private String getTokenKey(String token)
{
private String getTokenKey(String token) {
return CacheConstants.LOGIN_TOKEN_KEY + token;
}
/**
* 获取请求token
*/
private String getToken(ServerHttpRequest request)
{
private String getToken(ServerHttpRequest request) {
String token = request.getHeaders().getFirst(TokenConstants.AUTHENTICATION);
// 如果前端设置了令牌前缀,则裁剪掉前缀
if (StringUtils.isNotEmpty(token) && token.startsWith(TokenConstants.PREFIX))
{
if (StringUtils.isNotEmpty(token) && token.startsWith(TokenConstants.PREFIX)) {
token = token.replaceFirst(TokenConstants.PREFIX, StringUtils.EMPTY);
}
return token;
}
@Override
public int getOrder()
{
public int getOrder() {
return -200;
}
}

View File

@@ -1,29 +1,27 @@
package com.ruoyi.gateway.filter;
import com.ruoyi.common.core.utils.ServletUtils;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;
import com.ruoyi.common.core.utils.ServletUtils;
/**
* 黑名单过滤器
*
*
* @author ruoyi
*/
@Component
public class BlackListUrlFilter extends AbstractGatewayFilterFactory<BlackListUrlFilter.Config>
{
public class BlackListUrlFilter extends AbstractGatewayFilterFactory<BlackListUrlFilter.Config> {
@Override
public GatewayFilter apply(Config config)
{
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
String url = exchange.getRequest().getURI().getPath();
if (config.matchBlacklist(url))
{
if (config.matchBlacklist(url)) {
return ServletUtils.webFluxResponseWriter(exchange.getResponse(), "请求地址不允许访问");
}
@@ -31,29 +29,24 @@ public class BlackListUrlFilter extends AbstractGatewayFilterFactory<BlackListUr
};
}
public BlackListUrlFilter()
{
public BlackListUrlFilter() {
super(Config.class);
}
public static class Config
{
public static class Config {
private List<String> blacklistUrl;
private List<Pattern> blacklistUrlPattern = new ArrayList<>();
public boolean matchBlacklist(String url)
{
public boolean matchBlacklist(String url) {
return blacklistUrlPattern.isEmpty() ? false : blacklistUrlPattern.stream().filter(p -> p.matcher(url).find()).findAny().isPresent();
}
public List<String> getBlacklistUrl()
{
public List<String> getBlacklistUrl() {
return blacklistUrl;
}
public void setBlacklistUrl(List<String> blacklistUrl)
{
public void setBlacklistUrl(List<String> blacklistUrl) {
this.blacklistUrl = blacklistUrl;
this.blacklistUrlPattern.clear();
this.blacklistUrl.forEach(url -> {

View File

@@ -1,7 +1,5 @@
package com.ruoyi.gateway.filter;
import java.util.Collections;
import java.util.List;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.OrderedGatewayFilter;
@@ -16,46 +14,41 @@ import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.Collections;
import java.util.List;
/**
* 获取body请求数据解决流不能重复读取问题
*
*
* @author ruoyi
*/
@Component
public class CacheRequestFilter extends AbstractGatewayFilterFactory<CacheRequestFilter.Config>
{
public CacheRequestFilter()
{
public class CacheRequestFilter extends AbstractGatewayFilterFactory<CacheRequestFilter.Config> {
public CacheRequestFilter() {
super(Config.class);
}
@Override
public String name()
{
public String name() {
return "CacheRequestFilter";
}
@Override
public GatewayFilter apply(Config config)
{
public GatewayFilter apply(Config config) {
CacheRequestGatewayFilter cacheRequestGatewayFilter = new CacheRequestGatewayFilter();
Integer order = config.getOrder();
if (order == null)
{
if (order == null) {
return cacheRequestGatewayFilter;
}
return new OrderedGatewayFilter(cacheRequestGatewayFilter, order);
}
public static class CacheRequestGatewayFilter implements GatewayFilter
{
public static class CacheRequestGatewayFilter implements GatewayFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
{
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// GET DELETE 不过滤
HttpMethod method = exchange.getRequest().getMethod();
if (method == null || method.matches("GET") || method.matches("DELETE"))
{
if (method == null || method.matches("GET") || method.matches("DELETE")) {
return chain.filter(exchange);
}
return DataBufferUtils.join(exchange.getRequest().getBody()).map(dataBuffer -> {
@@ -65,13 +58,10 @@ public class CacheRequestFilter extends AbstractGatewayFilterFactory<CacheReques
return bytes;
}).defaultIfEmpty(new byte[0]).flatMap(bytes -> {
DataBufferFactory dataBufferFactory = exchange.getResponse().bufferFactory();
ServerHttpRequestDecorator decorator = new ServerHttpRequestDecorator(exchange.getRequest())
{
ServerHttpRequestDecorator decorator = new ServerHttpRequestDecorator(exchange.getRequest()) {
@Override
public Flux<DataBuffer> getBody()
{
if (bytes.length > 0)
{
public Flux<DataBuffer> getBody() {
if (bytes.length > 0) {
return Flux.just(dataBufferFactory.wrap(bytes));
}
return Flux.empty();
@@ -83,22 +73,18 @@ public class CacheRequestFilter extends AbstractGatewayFilterFactory<CacheReques
}
@Override
public List<String> shortcutFieldOrder()
{
public List<String> shortcutFieldOrder() {
return Collections.singletonList("order");
}
static class Config
{
static class Config {
private Integer order;
public Integer getOrder()
{
public Integer getOrder() {
return order;
}
public void setOrder(Integer order)
{
public void setOrder(Integer order) {
this.order = order;
}
}

View File

@@ -1,8 +1,10 @@
package com.ruoyi.gateway.filter;
import java.nio.CharBuffer;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.atomic.AtomicReference;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.utils.ServletUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.gateway.config.properties.CaptchaProperties;
import com.ruoyi.gateway.service.ValidateCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
@@ -10,22 +12,20 @@ import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.utils.ServletUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.gateway.config.properties.CaptchaProperties;
import com.ruoyi.gateway.service.ValidateCodeService;
import reactor.core.publisher.Flux;
import java.nio.CharBuffer;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.atomic.AtomicReference;
/**
* 验证码过滤器
*
*
* @author ruoyi
*/
@Component
public class ValidateCodeFilter extends AbstractGatewayFilterFactory<Object>
{
private final static String[] VALIDATE_URL = new String[] { "/auth/login", "/auth/register" };
public class ValidateCodeFilter extends AbstractGatewayFilterFactory<Object> {
private final static String[] VALIDATE_URL = new String[]{"/auth/login", "/auth/register"};
@Autowired
private ValidateCodeService validateCodeService;
@@ -38,33 +38,27 @@ public class ValidateCodeFilter extends AbstractGatewayFilterFactory<Object>
private static final String UUID = "uuid";
@Override
public GatewayFilter apply(Object config)
{
public GatewayFilter apply(Object config) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
// 非登录/注册请求或验证码关闭,不处理
if (!StringUtils.containsAnyIgnoreCase(request.getURI().getPath(), VALIDATE_URL) || !captchaProperties.getEnabled())
{
if (!StringUtils.containsAnyIgnoreCase(request.getURI().getPath(), VALIDATE_URL) || !captchaProperties.getEnabled()) {
return chain.filter(exchange);
}
try
{
try {
String rspStr = resolveBodyFromRequest(request);
JSONObject obj = JSONObject.parseObject(rspStr);
validateCodeService.checkCapcha(obj.getString(CODE), obj.getString(UUID));
}
catch (Exception e)
{
} catch (Exception e) {
return ServletUtils.webFluxResponseWriter(exchange.getResponse(), e.getMessage());
}
return chain.filter(exchange);
};
}
private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest)
{
private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest) {
// 获取请求体
Flux<DataBuffer> body = serverHttpRequest.getBody();
AtomicReference<String> bodyRef = new AtomicReference<>();

View File

@@ -1,16 +1,15 @@
package com.ruoyi.gateway.filter;
import java.nio.charset.StandardCharsets;
import cn.hutool.http.HtmlUtil;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.gateway.config.properties.XssProperties;
import io.netty.buffer.ByteBufAllocator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.core.io.buffer.NettyDataBufferFactory;
import org.springframework.core.io.buffer.*;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
@@ -18,13 +17,11 @@ import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.html.EscapeUtil;
import com.ruoyi.gateway.config.properties.XssProperties;
import io.netty.buffer.ByteBufAllocator;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.nio.charset.StandardCharsets;
/**
* 跨站脚本过滤器
*
@@ -32,31 +29,26 @@ import reactor.core.publisher.Mono;
*/
@Component
@ConditionalOnProperty(value = "security.xss.enabled", havingValue = "true")
public class XssFilter implements GlobalFilter, Ordered
{
public class XssFilter implements GlobalFilter, Ordered {
// 跨站脚本的 xss 配置nacos自行添加
@Autowired
private XssProperties xss;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
{
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
// GET DELETE 不过滤
HttpMethod method = request.getMethod();
if (method == null || method.matches("GET") || method.matches("DELETE"))
{
if (method == null || method.matches("GET") || method.matches("DELETE")) {
return chain.filter(exchange);
}
// 非json类型不过滤
if (!isJsonRequest(exchange))
{
if (!isJsonRequest(exchange)) {
return chain.filter(exchange);
}
// excludeUrls 不过滤
String url = request.getURI().getPath();
if (StringUtils.matches(url, xss.getExcludeUrls()))
{
if (StringUtils.matches(url, xss.getExcludeUrls())) {
return chain.filter(exchange);
}
ServerHttpRequestDecorator httpRequestDecorator = requestDecorator(exchange);
@@ -64,13 +56,10 @@ public class XssFilter implements GlobalFilter, Ordered
}
private ServerHttpRequestDecorator requestDecorator(ServerWebExchange exchange)
{
ServerHttpRequestDecorator serverHttpRequestDecorator = new ServerHttpRequestDecorator(exchange.getRequest())
{
private ServerHttpRequestDecorator requestDecorator(ServerWebExchange exchange) {
ServerHttpRequestDecorator serverHttpRequestDecorator = new ServerHttpRequestDecorator(exchange.getRequest()) {
@Override
public Flux<DataBuffer> getBody()
{
public Flux<DataBuffer> getBody() {
Flux<DataBuffer> body = super.getBody();
return body.buffer().map(dataBuffers -> {
DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory();
@@ -80,7 +69,7 @@ public class XssFilter implements GlobalFilter, Ordered
DataBufferUtils.release(join);
String bodyStr = new String(content, StandardCharsets.UTF_8);
// 防xss攻击过滤
bodyStr = EscapeUtil.clean(bodyStr);
bodyStr = HtmlUtil.cleanHtmlTag(bodyStr);
// 转成字节
byte[] bytes = bodyStr.getBytes();
NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);
@@ -91,8 +80,7 @@ public class XssFilter implements GlobalFilter, Ordered
}
@Override
public HttpHeaders getHeaders()
{
public HttpHeaders getHeaders() {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.putAll(super.getHeaders());
// 由于修改了请求体的body导致content-length长度不确定因此需要删除原先的content-length
@@ -107,18 +95,16 @@ public class XssFilter implements GlobalFilter, Ordered
/**
* 是否是Json请求
*
*
* @param request
*/
public boolean isJsonRequest(ServerWebExchange exchange)
{
public boolean isJsonRequest(ServerWebExchange exchange) {
String header = exchange.getRequest().getHeaders().getFirst(HttpHeaders.CONTENT_TYPE);
return StringUtils.startsWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE);
}
@Override
public int getOrder()
{
public int getOrder() {
return -100;
}
}

View File

@@ -1,16 +1,14 @@
package com.ruoyi.gateway.handler;
import com.ruoyi.common.core.utils.ServletUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.support.NotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
import org.springframework.cloud.gateway.support.NotFoundException;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.server.ServerWebExchange;
import com.ruoyi.common.core.utils.ServletUtils;
import reactor.core.publisher.Mono;
/**
@@ -21,32 +19,24 @@ import reactor.core.publisher.Mono;
@Slf4j
@Order(-1)
@Configuration
public class GatewayExceptionHandler implements ErrorWebExceptionHandler
{
public class GatewayExceptionHandler implements ErrorWebExceptionHandler {
@Override
public Mono<Void> handle(ServerWebExchange exchange, Throwable ex)
{
public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
ServerHttpResponse response = exchange.getResponse();
if (exchange.getResponse().isCommitted())
{
if (exchange.getResponse().isCommitted()) {
return Mono.error(ex);
}
String msg;
if (ex instanceof NotFoundException)
{
if (ex instanceof NotFoundException) {
msg = "服务未找到";
}
else if (ex instanceof ResponseStatusException)
{
} else if (ex instanceof ResponseStatusException) {
ResponseStatusException responseStatusException = (ResponseStatusException) ex;
msg = responseStatusException.getMessage();
}
else
{
} else {
msg = "内部服务器错误";
}

View File

@@ -13,29 +13,23 @@ import reactor.core.publisher.Mono;
*
* @author ruoyi
*/
public class SentinelFallbackHandler implements WebExceptionHandler
{
private Mono<Void> writeResponse(ServerResponse response, ServerWebExchange exchange)
{
public class SentinelFallbackHandler implements WebExceptionHandler {
private Mono<Void> writeResponse(ServerResponse response, ServerWebExchange exchange) {
return ServletUtils.webFluxResponseWriter(exchange.getResponse(), "请求超过最大数,请稍候再试");
}
@Override
public Mono<Void> handle(ServerWebExchange exchange, Throwable ex)
{
if (exchange.getResponse().isCommitted())
{
public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
if (exchange.getResponse().isCommitted()) {
return Mono.error(ex);
}
if (!BlockException.isBlockException(ex))
{
if (!BlockException.isBlockException(ex)) {
return Mono.error(ex);
}
return handleBlockedRequest(exchange, ex).flatMap(response -> writeResponse(response, exchange));
}
private Mono<ServerResponse> handleBlockedRequest(ServerWebExchange exchange, Throwable throwable)
{
private Mono<ServerResponse> handleBlockedRequest(ServerWebExchange exchange, Throwable throwable) {
return GatewayCallbackManager.getBlockHandler().handleRequest(exchange, throwable);
}
}

View File

@@ -1,6 +1,5 @@
package com.ruoyi.gateway.handler;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
@@ -8,16 +7,13 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
import springfox.documentation.swagger.web.SecurityConfiguration;
import springfox.documentation.swagger.web.SecurityConfigurationBuilder;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;
import springfox.documentation.swagger.web.UiConfiguration;
import springfox.documentation.swagger.web.UiConfigurationBuilder;
import springfox.documentation.swagger.web.*;
import java.util.Optional;
@RestController
@RequestMapping("/swagger-resources")
public class SwaggerHandler
{
public class SwaggerHandler {
@Autowired(required = false)
private SecurityConfiguration securityConfiguration;
@@ -27,30 +23,26 @@ public class SwaggerHandler
private final SwaggerResourcesProvider swaggerResources;
@Autowired
public SwaggerHandler(SwaggerResourcesProvider swaggerResources)
{
public SwaggerHandler(SwaggerResourcesProvider swaggerResources) {
this.swaggerResources = swaggerResources;
}
@GetMapping("/configuration/security")
public Mono<ResponseEntity<SecurityConfiguration>> securityConfiguration()
{
public Mono<ResponseEntity<SecurityConfiguration>> securityConfiguration() {
return Mono.just(new ResponseEntity<>(
Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()),
HttpStatus.OK));
}
@GetMapping("/configuration/ui")
public Mono<ResponseEntity<UiConfiguration>> uiConfiguration()
{
public Mono<ResponseEntity<UiConfiguration>> uiConfiguration() {
return Mono.just(new ResponseEntity<>(
Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK));
}
@SuppressWarnings("rawtypes")
@GetMapping("")
public Mono<ResponseEntity> swaggerResources()
{
public Mono<ResponseEntity> swaggerResources() {
return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
}
}

View File

@@ -1,6 +1,8 @@
package com.ruoyi.gateway.handler;
import java.io.IOException;
import com.ruoyi.common.core.exception.CaptchaException;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.gateway.service.ValidateCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
@@ -8,32 +10,26 @@ import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.HandlerFunction;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import com.ruoyi.common.core.exception.CaptchaException;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.gateway.service.ValidateCodeService;
import reactor.core.publisher.Mono;
import java.io.IOException;
/**
* 验证码获取
*
*
* @author ruoyi
*/
@Component
public class ValidateCodeHandler implements HandlerFunction<ServerResponse>
{
public class ValidateCodeHandler implements HandlerFunction<ServerResponse> {
@Autowired
private ValidateCodeService validateCodeService;
@Override
public Mono<ServerResponse> handle(ServerRequest serverRequest)
{
public Mono<ServerResponse> handle(ServerRequest serverRequest) {
AjaxResult ajax;
try
{
try {
ajax = validateCodeService.createCapcha();
}
catch (CaptchaException | IOException e)
{
} catch (CaptchaException | IOException e) {
return Mono.error(e);
}
return ServerResponse.status(HttpStatus.OK).body(BodyInserters.fromValue(ajax));

View File

@@ -1,23 +1,23 @@
package com.ruoyi.gateway.service;
import java.io.IOException;
import com.ruoyi.common.core.exception.CaptchaException;
import com.ruoyi.common.core.web.domain.AjaxResult;
import java.io.IOException;
/**
* 验证码处理
*
*
* @author ruoyi
*/
public interface ValidateCodeService
{
public interface ValidateCodeService {
/**
* 生成验证码
*/
public AjaxResult createCapcha() throws IOException, CaptchaException;
AjaxResult createCapcha() throws IOException, CaptchaException;
/**
* 校验验证码
*/
public void checkCapcha(String key, String value) throws CaptchaException;
void checkCapcha(String key, String value) throws CaptchaException;
}

View File

@@ -3,9 +3,9 @@ package com.ruoyi.gateway.service.impl;
import cn.hutool.captcha.AbstractCaptcha;
import cn.hutool.captcha.generator.CodeGenerator;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.IdUtil;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.exception.CaptchaException;
import com.ruoyi.common.core.utils.IdUtils;
import com.ruoyi.common.core.utils.SpringUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.reflect.ReflectUtils;
@@ -26,8 +26,7 @@ import java.util.concurrent.TimeUnit;
* @author ruoyi
*/
@Service
public class ValidateCodeServiceImpl implements ValidateCodeService
{
public class ValidateCodeServiceImpl implements ValidateCodeService {
@Autowired
private CaptchaProperties captchaProperties;
@@ -35,18 +34,16 @@ public class ValidateCodeServiceImpl implements ValidateCodeService
* 生成验证码
*/
@Override
public AjaxResult createCapcha() throws IOException, CaptchaException
{
public AjaxResult createCapcha() throws IOException, CaptchaException {
AjaxResult ajax = AjaxResult.success();
boolean captchaOnOff = captchaProperties.getEnabled();
ajax.put("captchaOnOff", captchaOnOff);
if (!captchaOnOff)
{
if (!captchaOnOff) {
return ajax;
}
// 保存验证码信息
String uuid = IdUtils.simpleUUID();
String uuid = IdUtil.simpleUUID();
String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
// 生成验证码
CaptchaType captchaType = captchaProperties.getType();
@@ -84,22 +81,18 @@ public class ValidateCodeServiceImpl implements ValidateCodeService
* 校验验证码
*/
@Override
public void checkCapcha(String code, String uuid) throws CaptchaException
{
if (StringUtils.isEmpty(code))
{
public void checkCapcha(String code, String uuid) throws CaptchaException {
if (StringUtils.isEmpty(code)) {
throw new CaptchaException("验证码不能为空");
}
if (StringUtils.isEmpty(uuid))
{
if (StringUtils.isEmpty(uuid)) {
throw new CaptchaException("验证码已失效");
}
String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
String captcha = RedisUtils.getCacheObject(verifyKey);
RedisUtils.deleteObject(verifyKey);
if (!code.equalsIgnoreCase(captcha))
{
if (!code.equalsIgnoreCase(captcha)) {
throw new CaptchaException("验证码错误");
}
}