重构系统项目结构, 将 tianai-captcha

tianai-captcha-springboot-starter
   tianai-captcha-web-sdk
   tianai-captcha-solon-plugin
   整合到一块
This commit is contained in:
天爱有情
2025-10-27 15:14:10 +08:00
parent af2df2c7e2
commit 5eb258215b
156 changed files with 16688 additions and 99 deletions
@@ -0,0 +1,63 @@
package cloud.tianai.captcha.spring.autoconfiguration;
import cloud.tianai.captcha.cache.CacheStore;
import cloud.tianai.captcha.cache.impl.LocalCacheStore;
import cloud.tianai.captcha.spring.store.impl.RedisCacheStore;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.StringRedisTemplate;
/**
* 缓存存储器的自动配置类
*
* @author Hccake
*/
@AutoConfigureAfter({RedisAutoConfiguration.class})
@Configuration(proxyBeanMethods = false)
public class CacheStoreAutoConfiguration {
/**
* RedisCacheStoreConfiguration
*
* @author 天爱有情
* @since 2020/10/27 14:06
*/
@Order(1)
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(StringRedisTemplate.class)
public static class RedisCacheStoreConfiguration {
@Bean
@ConditionalOnBean(StringRedisTemplate.class)
@ConditionalOnMissingBean(CacheStore.class)
public CacheStore redis(StringRedisTemplate redisTemplate) {
return new RedisCacheStore(redisTemplate);
}
}
/**
* LocalCacheStoreConfiguration
*
* @author 天爱有情
* @since 2020/10/27 14:06
*/
@Order(2)
@Configuration(proxyBeanMethods = false)
public static class LocalCacheStoreConfiguration {
@Bean
@ConditionalOnMissingBean(CacheStore.class)
public CacheStore local() {
return new LocalCacheStore();
}
}
}
@@ -0,0 +1,130 @@
package cloud.tianai.captcha.spring.autoconfiguration;
import cloud.tianai.captcha.application.ImageCaptchaApplication;
import cloud.tianai.captcha.application.TACBuilder;
import cloud.tianai.captcha.cache.CacheStore;
import cloud.tianai.captcha.common.util.CollectionUtils;
import cloud.tianai.captcha.generator.ImageCaptchaGenerator;
import cloud.tianai.captcha.generator.ImageTransform;
import cloud.tianai.captcha.generator.impl.transform.Base64ImageTransform;
import cloud.tianai.captcha.interceptor.CaptchaInterceptor;
import cloud.tianai.captcha.interceptor.CaptchaInterceptorGroup;
import cloud.tianai.captcha.interceptor.impl.ParamCheckCaptchaInterceptor;
import cloud.tianai.captcha.resource.ImageCaptchaResourceManager;
import cloud.tianai.captcha.resource.ResourceProviders;
import cloud.tianai.captcha.resource.ResourceStore;
import cloud.tianai.captcha.resource.impl.DefaultImageCaptchaResourceManager;
import cloud.tianai.captcha.resource.impl.LocalMemoryResourceStore;
import cloud.tianai.captcha.spring.plugins.SpringMultiImageCaptchaGenerator;
import cloud.tianai.captcha.spring.plugins.secondary.SecondaryVerificationApplication;
import cloud.tianai.captcha.validator.ImageCaptchaValidator;
import cloud.tianai.captcha.validator.impl.SimpleImageCaptchaValidator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Role;
import org.springframework.core.annotation.Order;
/**
* @Author: 天爱有情
* @Date 2020/5/29 9:49
* @Description 滑块验证码自动装配
*/
@Slf4j
@Order
@Configuration
@AutoConfigureAfter(CacheStoreAutoConfiguration.class)
@EnableConfigurationProperties({SpringImageCaptchaProperties.class})
public class ImageCaptchaAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public ResourceStore resourceStore() {
return new LocalMemoryResourceStore();
}
@Bean
@ConditionalOnMissingBean
public ImageCaptchaResourceManager imageCaptchaResourceManager(ResourceStore resourceStore) {
ResourceProviders resourceProviders = new ResourceProviders();
return new DefaultImageCaptchaResourceManager(resourceStore,resourceProviders);
}
@Bean
@ConditionalOnMissingBean
public ImageTransform imageTransform() {
return new Base64ImageTransform();
}
@Bean
@ConditionalOnMissingBean
public ImageCaptchaGenerator imageCaptchaTemplate(SpringImageCaptchaProperties prop,
ImageCaptchaResourceManager captchaResourceManager,
ImageTransform imageTransform,
BeanFactory beanFactory) {
return new SpringMultiImageCaptchaGenerator(captchaResourceManager, imageTransform, beanFactory);
}
@Bean
@ConditionalOnMissingBean
public ImageCaptchaValidator imageCaptchaValidator() {
return new SimpleImageCaptchaValidator();
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@ConditionalOnMissingBean
public CaptchaInterceptor captchaInterceptor() {
CaptchaInterceptorGroup group = new CaptchaInterceptorGroup();
group.addInterceptor(new ParamCheckCaptchaInterceptor());
// group.addInterceptor(new BasicTrackCaptchaInterceptor());
return group;
}
@Bean
@ConditionalOnMissingBean
public ImageCaptchaApplication imageCaptchaApplication(ImageCaptchaGenerator captchaGenerator,
ImageCaptchaValidator imageCaptchaValidator,
CacheStore cacheStore,
ResourceStore resourceStore,
SpringImageCaptchaProperties prop,
CaptchaInterceptor captchaInterceptor,
ApplicationContext applicationContext) {
TACBuilder tacBuilder = TACBuilder.builder(resourceStore)
.setGenerator(captchaGenerator)
.setValidator(imageCaptchaValidator)
.setCacheStore(cacheStore)
.setProp(prop)
.setInterceptor(captchaInterceptor);
if (prop.getInitDefaultResource()) {
tacBuilder.addDefaultTemplate(prop.getDefaultResourcePrefix());
}
if (!CollectionUtils.isEmpty(prop.getFontPath())) {
// 读取字体包
for (String fontPath : prop.getFontPath()) {
int index = fontPath.indexOf(":");
String[] split = index > 0 ? new String[]{fontPath.substring(0, index), fontPath.substring(index + 1)} : new String[]{"", fontPath};
String type = split[0];
String path = split[1];
tacBuilder.addFont(new cloud.tianai.captcha.resource.common.model.dto.Resource(type, path));
}
}
ImageCaptchaApplication target = tacBuilder.build();
if (prop.getSecondary() != null && Boolean.TRUE.equals(prop.getSecondary().getEnabled())) {
// 一个简单的二次验证
target = new SecondaryVerificationApplication(target, prop.getSecondary());
}
return target;
}
}
@@ -0,0 +1,12 @@
package cloud.tianai.captcha.spring.autoconfiguration;
import lombok.Data;
@Data
public class SecondaryVerificationProperties {
private Boolean enabled = false;
private Long expire = 120000L;
private String keyPrefix = "captcha:secondary";
}
@@ -0,0 +1,30 @@
package cloud.tianai.captcha.spring.autoconfiguration;
import cloud.tianai.captcha.application.ImageCaptchaProperties;
import cloud.tianai.captcha.resource.DefaultBuiltInResources;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import java.util.List;
/**
* @Author: 天爱有情
* @date 2020/10/19 18:41
* @Description 滑块验证码属性
*/
@Data
@EqualsAndHashCode(callSuper = true)
@ConfigurationProperties(prefix = "captcha")
public class SpringImageCaptchaProperties extends ImageCaptchaProperties {
/** 是否初始化默认资源. */
private Boolean initDefaultResource = false;
/** 默认资源的位置. */
private String defaultResourcePrefix = DefaultBuiltInResources.PATH_PREFIX;
/** 字体包路径. */
private List<String> fontPath;
/** 二次验证配置. */
@NestedConfigurationProperty
private SecondaryVerificationProperties secondary;
}