init framework
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
package org.wfc.gateway.config;
|
||||
|
||||
import java.util.Properties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import com.google.code.kaptcha.impl.DefaultKaptcha;
|
||||
import com.google.code.kaptcha.util.Config;
|
||||
import static com.google.code.kaptcha.Constants.*;
|
||||
|
||||
/**
|
||||
* 验证码配置
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Configuration
|
||||
public class CaptchaConfig
|
||||
{
|
||||
@Bean(name = "captchaProducer")
|
||||
public DefaultKaptcha getKaptchaBean()
|
||||
{
|
||||
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
|
||||
Properties properties = new Properties();
|
||||
// 是否有边框 默认为true 我们可以自己设置yes,no
|
||||
properties.setProperty(KAPTCHA_BORDER, "yes");
|
||||
// 验证码文本字符颜色 默认为Color.BLACK
|
||||
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black");
|
||||
// 验证码图片宽度 默认为200
|
||||
properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");
|
||||
// 验证码图片高度 默认为50
|
||||
properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");
|
||||
// 验证码文本字符大小 默认为40
|
||||
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38");
|
||||
// KAPTCHA_SESSION_KEY
|
||||
properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode");
|
||||
// 验证码文本字符长度 默认为5
|
||||
properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4");
|
||||
// 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
|
||||
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
|
||||
// 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy
|
||||
properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
|
||||
Config config = new Config(properties);
|
||||
defaultKaptcha.setConfig(config);
|
||||
return defaultKaptcha;
|
||||
}
|
||||
|
||||
@Bean(name = "captchaProducerMath")
|
||||
public DefaultKaptcha getKaptchaBeanMath()
|
||||
{
|
||||
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
|
||||
Properties properties = new Properties();
|
||||
// 是否有边框 默认为true 我们可以自己设置yes,no
|
||||
properties.setProperty(KAPTCHA_BORDER, "yes");
|
||||
// 边框颜色 默认为Color.BLACK
|
||||
properties.setProperty(KAPTCHA_BORDER_COLOR, "105,179,90");
|
||||
// 验证码文本字符颜色 默认为Color.BLACK
|
||||
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue");
|
||||
// 验证码图片宽度 默认为200
|
||||
properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");
|
||||
// 验证码图片高度 默认为50
|
||||
properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");
|
||||
// 验证码文本字符大小 默认为40
|
||||
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "35");
|
||||
// KAPTCHA_SESSION_KEY
|
||||
properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath");
|
||||
// 验证码文本生成器
|
||||
properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "org.wfc.gateway.config.KaptchaTextCreator");
|
||||
// 验证码文本字符间距 默认为2
|
||||
properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "3");
|
||||
// 验证码文本字符长度 默认为5
|
||||
properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "6");
|
||||
// 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
|
||||
properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
|
||||
// 验证码噪点颜色 默认为Color.BLACK
|
||||
properties.setProperty(KAPTCHA_NOISE_COLOR, "white");
|
||||
// 干扰实现类
|
||||
properties.setProperty(KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise");
|
||||
// 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy
|
||||
properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
|
||||
Config config = new Config(properties);
|
||||
defaultKaptcha.setConfig(config);
|
||||
return defaultKaptcha;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.wfc.gateway.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.wfc.gateway.handler.SentinelFallbackHandler;
|
||||
|
||||
/**
|
||||
* 网关限流配置
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Configuration
|
||||
public class GatewayConfig
|
||||
{
|
||||
@Bean
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
public SentinelFallbackHandler sentinelGatewayExceptionHandler()
|
||||
{
|
||||
return new SentinelFallbackHandler();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package org.wfc.gateway.config;
|
||||
|
||||
import java.util.Random;
|
||||
import com.google.code.kaptcha.text.impl.DefaultTextCreator;
|
||||
|
||||
/**
|
||||
* 验证码文本生成器
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class KaptchaTextCreator extends DefaultTextCreator
|
||||
{
|
||||
private static final String[] CNUMBERS = "0,1,2,3,4,5,6,7,8,9,10".split(",");
|
||||
|
||||
@Override
|
||||
public String getText()
|
||||
{
|
||||
Integer result = 0;
|
||||
Random random = new Random();
|
||||
int x = random.nextInt(10);
|
||||
int y = random.nextInt(10);
|
||||
StringBuilder suChinese = new StringBuilder();
|
||||
int randomoperands = random.nextInt(3);
|
||||
if (randomoperands == 0)
|
||||
{
|
||||
result = x * y;
|
||||
suChinese.append(CNUMBERS[x]);
|
||||
suChinese.append("*");
|
||||
suChinese.append(CNUMBERS[y]);
|
||||
}
|
||||
else if (randomoperands == 1)
|
||||
{
|
||||
if ((x != 0) && y % x == 0)
|
||||
{
|
||||
result = y / x;
|
||||
suChinese.append(CNUMBERS[y]);
|
||||
suChinese.append("/");
|
||||
suChinese.append(CNUMBERS[x]);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = x + y;
|
||||
suChinese.append(CNUMBERS[x]);
|
||||
suChinese.append("+");
|
||||
suChinese.append(CNUMBERS[y]);
|
||||
}
|
||||
}
|
||||
else if (randomoperands == 2)
|
||||
{
|
||||
if (x >= y)
|
||||
{
|
||||
result = x - y;
|
||||
suChinese.append(CNUMBERS[x]);
|
||||
suChinese.append("-");
|
||||
suChinese.append(CNUMBERS[y]);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = y - x;
|
||||
suChinese.append(CNUMBERS[y]);
|
||||
suChinese.append("-");
|
||||
suChinese.append(CNUMBERS[x]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = x + y;
|
||||
suChinese.append(CNUMBERS[x]);
|
||||
suChinese.append("+");
|
||||
suChinese.append(CNUMBERS[y]);
|
||||
}
|
||||
suChinese.append("=?@" + result);
|
||||
return suChinese.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package org.wfc.gateway.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
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.wfc.gateway.handler.ValidateCodeHandler;
|
||||
|
||||
/**
|
||||
* 路由配置信息
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Configuration
|
||||
public class RouterFunctionConfiguration
|
||||
{
|
||||
@Autowired
|
||||
private ValidateCodeHandler validateCodeHandler;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Bean
|
||||
public RouterFunction routerFunction()
|
||||
{
|
||||
return RouterFunctions.route(
|
||||
RequestPredicates.GET("/code").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)),
|
||||
validateCodeHandler);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package org.wfc.gateway.config;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import org.springdoc.core.AbstractSwaggerUiConfigProperties;
|
||||
import org.springdoc.core.SwaggerUiConfigProperties;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import com.alibaba.nacos.client.naming.event.InstancesChangeEvent;
|
||||
import com.alibaba.nacos.common.notify.Event;
|
||||
import com.alibaba.nacos.common.notify.NotifyCenter;
|
||||
import com.alibaba.nacos.common.notify.listener.Subscriber;
|
||||
import org.wfc.common.core.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* SpringDoc配置类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnProperty(value = "springdoc.api-docs.enabled", matchIfMissing = true)
|
||||
public class SpringDocConfig implements InitializingBean
|
||||
{
|
||||
@Autowired
|
||||
private SwaggerUiConfigProperties swaggerUiConfigProperties;
|
||||
|
||||
@Autowired
|
||||
private DiscoveryClient discoveryClient;
|
||||
|
||||
/**
|
||||
* 在初始化后调用的方法
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet()
|
||||
{
|
||||
NotifyCenter.registerSubscriber(new SwaggerDocRegister(swaggerUiConfigProperties, discoveryClient));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Swagger文档注册器
|
||||
*/
|
||||
class SwaggerDocRegister extends Subscriber<InstancesChangeEvent>
|
||||
{
|
||||
@Autowired
|
||||
private SwaggerUiConfigProperties swaggerUiConfigProperties;
|
||||
|
||||
@Autowired
|
||||
private DiscoveryClient discoveryClient;
|
||||
|
||||
private final static String[] EXCLUDE_ROUTES = new String[] { "wfc-gateway", "wfc-auth", "wfc-file", "wfc-monitor" };
|
||||
|
||||
public SwaggerDocRegister(SwaggerUiConfigProperties swaggerUiConfigProperties, DiscoveryClient discoveryClient)
|
||||
{
|
||||
this.swaggerUiConfigProperties = swaggerUiConfigProperties;
|
||||
this.discoveryClient = discoveryClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件回调方法,处理InstancesChangeEvent事件
|
||||
* @param event 事件对象
|
||||
*/
|
||||
@Override
|
||||
public void onEvent(InstancesChangeEvent event)
|
||||
{
|
||||
Set<AbstractSwaggerUiConfigProperties.SwaggerUrl> swaggerUrlSet = discoveryClient.getServices()
|
||||
.stream()
|
||||
.flatMap(serviceId -> discoveryClient.getInstances(serviceId).stream())
|
||||
.filter(instance -> !StringUtils.equalsAnyIgnoreCase(instance.getServiceId(), EXCLUDE_ROUTES))
|
||||
.map(instance -> {
|
||||
AbstractSwaggerUiConfigProperties.SwaggerUrl swaggerUrl = new AbstractSwaggerUiConfigProperties.SwaggerUrl();
|
||||
swaggerUrl.setName(instance.getServiceId());
|
||||
swaggerUrl.setUrl(String.format("/%s/v3/api-docs", instance.getServiceId()));
|
||||
return swaggerUrl;
|
||||
})
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
swaggerUiConfigProperties.setUrls(swaggerUrlSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订阅类型方法,返回订阅的事件类型
|
||||
* @return 订阅的事件类型
|
||||
*/
|
||||
@Override
|
||||
public Class<? extends Event> subscribeType()
|
||||
{
|
||||
return InstancesChangeEvent.class;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package org.wfc.gateway.config.properties;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 验证码配置
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Configuration
|
||||
@RefreshScope
|
||||
@ConfigurationProperties(prefix = "security.captcha")
|
||||
public class CaptchaProperties
|
||||
{
|
||||
/**
|
||||
* 验证码开关
|
||||
*/
|
||||
private Boolean enabled;
|
||||
|
||||
/**
|
||||
* 验证码类型(math 数组计算 char 字符)
|
||||
*/
|
||||
private String type;
|
||||
|
||||
public Boolean getEnabled()
|
||||
{
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(Boolean enabled)
|
||||
{
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public String getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type)
|
||||
{
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.wfc.gateway.config.properties;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 放行白名单配置
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Configuration
|
||||
@RefreshScope
|
||||
@ConfigurationProperties(prefix = "security.ignore")
|
||||
public class IgnoreWhiteProperties
|
||||
{
|
||||
/**
|
||||
* 放行白名单配置,网关不校验此处的白名单
|
||||
*/
|
||||
private List<String> whites = new ArrayList<>();
|
||||
|
||||
public List<String> getWhites()
|
||||
{
|
||||
return whites;
|
||||
}
|
||||
|
||||
public void setWhites(List<String> whites)
|
||||
{
|
||||
this.whites = whites;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package org.wfc.gateway.config.properties;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* XSS跨站脚本配置
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Configuration
|
||||
@RefreshScope
|
||||
@ConfigurationProperties(prefix = "security.xss")
|
||||
public class XssProperties
|
||||
{
|
||||
/**
|
||||
* Xss开关
|
||||
*/
|
||||
private Boolean enabled;
|
||||
|
||||
/**
|
||||
* 排除路径
|
||||
*/
|
||||
private List<String> excludeUrls = new ArrayList<>();
|
||||
|
||||
public Boolean getEnabled()
|
||||
{
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(Boolean enabled)
|
||||
{
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public List<String> getExcludeUrls()
|
||||
{
|
||||
return excludeUrls;
|
||||
}
|
||||
|
||||
public void setExcludeUrls(List<String> excludeUrls)
|
||||
{
|
||||
this.excludeUrls = excludeUrls;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user