feat 接入tianai行为验证码
This commit is contained in:
parent
552e543471
commit
4ec0812066
2
pom.xml
2
pom.xml
@ -51,6 +51,8 @@
|
|||||||
<anyline.version>8.7.2-20241022</anyline.version>
|
<anyline.version>8.7.2-20241022</anyline.version>
|
||||||
<!--工作流配置-->
|
<!--工作流配置-->
|
||||||
<flowable.version>7.0.1</flowable.version>
|
<flowable.version>7.0.1</flowable.version>
|
||||||
|
<!-- 行为验证码配置 -->
|
||||||
|
<tianai-captcha.version>1.5.1</tianai-captcha.version>
|
||||||
|
|
||||||
<!-- 插件版本 -->
|
<!-- 插件版本 -->
|
||||||
<maven-jar-plugin.version>3.2.2</maven-jar-plugin.version>
|
<maven-jar-plugin.version>3.2.2</maven-jar-plugin.version>
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
package org.dromara.web.controller;
|
package org.dromara.web.controller;
|
||||||
|
|
||||||
|
import cloud.tianai.captcha.application.ImageCaptchaApplication;
|
||||||
|
import cloud.tianai.captcha.application.vo.CaptchaResponse;
|
||||||
|
import cloud.tianai.captcha.application.vo.ImageCaptchaVO;
|
||||||
|
import cloud.tianai.captcha.common.constant.CaptchaTypeConstant;
|
||||||
|
import cloud.tianai.captcha.common.response.ApiResponse;
|
||||||
import cn.dev33.satoken.annotation.SaIgnore;
|
import cn.dev33.satoken.annotation.SaIgnore;
|
||||||
import cn.hutool.captcha.AbstractCaptcha;
|
import cn.hutool.captcha.AbstractCaptcha;
|
||||||
import cn.hutool.captcha.generator.CodeGenerator;
|
import cn.hutool.captcha.generator.CodeGenerator;
|
||||||
@ -11,6 +16,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.dromara.common.core.constant.Constants;
|
import org.dromara.common.core.constant.Constants;
|
||||||
import org.dromara.common.core.constant.GlobalConstants;
|
import org.dromara.common.core.constant.GlobalConstants;
|
||||||
import org.dromara.common.core.domain.R;
|
import org.dromara.common.core.domain.R;
|
||||||
|
import org.dromara.common.core.exception.ServiceException;
|
||||||
import org.dromara.common.core.utils.SpringUtils;
|
import org.dromara.common.core.utils.SpringUtils;
|
||||||
import org.dromara.common.core.utils.StringUtils;
|
import org.dromara.common.core.utils.StringUtils;
|
||||||
import org.dromara.common.core.utils.reflect.ReflectUtils;
|
import org.dromara.common.core.utils.reflect.ReflectUtils;
|
||||||
@ -21,19 +27,26 @@ import org.dromara.common.ratelimiter.enums.LimitType;
|
|||||||
import org.dromara.common.redis.utils.RedisUtils;
|
import org.dromara.common.redis.utils.RedisUtils;
|
||||||
import org.dromara.common.web.config.properties.CaptchaProperties;
|
import org.dromara.common.web.config.properties.CaptchaProperties;
|
||||||
import org.dromara.common.web.enums.CaptchaType;
|
import org.dromara.common.web.enums.CaptchaType;
|
||||||
|
import org.dromara.common.web.enums.InputCaptchaType;
|
||||||
import org.dromara.sms4j.api.SmsBlend;
|
import org.dromara.sms4j.api.SmsBlend;
|
||||||
import org.dromara.sms4j.api.entity.SmsResponse;
|
import org.dromara.sms4j.api.entity.SmsResponse;
|
||||||
import org.dromara.sms4j.core.factory.SmsFactory;
|
import org.dromara.sms4j.core.factory.SmsFactory;
|
||||||
|
import org.dromara.web.domain.bo.CaptchaBo;
|
||||||
import org.dromara.web.domain.vo.CaptchaVo;
|
import org.dromara.web.domain.vo.CaptchaVo;
|
||||||
import org.springframework.expression.Expression;
|
import org.springframework.expression.Expression;
|
||||||
import org.springframework.expression.ExpressionParser;
|
import org.springframework.expression.ExpressionParser;
|
||||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证码操作处理
|
* 验证码操作处理
|
||||||
@ -50,6 +63,8 @@ public class CaptchaController {
|
|||||||
private final CaptchaProperties captchaProperties;
|
private final CaptchaProperties captchaProperties;
|
||||||
private final MailProperties mailProperties;
|
private final MailProperties mailProperties;
|
||||||
|
|
||||||
|
private final ImageCaptchaApplication imageCaptchaApplication;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 短信验证码
|
* 短信验证码
|
||||||
*
|
*
|
||||||
@ -109,15 +124,20 @@ public class CaptchaController {
|
|||||||
captchaVo.setCaptchaEnabled(false);
|
captchaVo.setCaptchaEnabled(false);
|
||||||
return R.ok(captchaVo);
|
return R.ok(captchaVo);
|
||||||
}
|
}
|
||||||
|
captchaVo.setType(captchaProperties.getType());
|
||||||
|
if (CaptchaType.ACT.getType().equalsIgnoreCase(captchaProperties.getType())) {
|
||||||
|
return R.ok(captchaVo);
|
||||||
|
}
|
||||||
// 保存验证码信息
|
// 保存验证码信息
|
||||||
String uuid = IdUtil.simpleUUID();
|
String uuid = IdUtil.simpleUUID();
|
||||||
String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + uuid;
|
String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + uuid;
|
||||||
// 生成验证码
|
// 生成验证码
|
||||||
CaptchaType captchaType = captchaProperties.getType();
|
CaptchaProperties.InputCaptchaProperties inputCaptchaProperties = captchaProperties.getInput();
|
||||||
boolean isMath = CaptchaType.MATH == captchaType;
|
InputCaptchaType inputCaptchaType = inputCaptchaProperties.getType();
|
||||||
Integer length = isMath ? captchaProperties.getNumberLength() : captchaProperties.getCharLength();
|
boolean isMath = InputCaptchaType.MATH == inputCaptchaType;
|
||||||
CodeGenerator codeGenerator = ReflectUtils.newInstance(captchaType.getClazz(), length);
|
Integer length = isMath ? inputCaptchaProperties.getNumberLength() : inputCaptchaProperties.getCharLength();
|
||||||
AbstractCaptcha captcha = SpringUtils.getBean(captchaProperties.getCategory().getClazz());
|
CodeGenerator codeGenerator = ReflectUtils.newInstance(inputCaptchaType.getClazz(), length);
|
||||||
|
AbstractCaptcha captcha = SpringUtils.getBean(inputCaptchaProperties.getCategory().getClazz());
|
||||||
captcha.setGenerator(codeGenerator);
|
captcha.setGenerator(codeGenerator);
|
||||||
captcha.createCode();
|
captcha.createCode();
|
||||||
// 如果是数学验证码,使用SpEL表达式处理验证码结果
|
// 如果是数学验证码,使用SpEL表达式处理验证码结果
|
||||||
@ -133,4 +153,33 @@ public class CaptchaController {
|
|||||||
return R.ok(captchaVo);
|
return R.ok(captchaVo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成行为验证码
|
||||||
|
*/
|
||||||
|
@RateLimiter(time = 60, count = 10, limitType = LimitType.IP)
|
||||||
|
@PostMapping("/auth/captcha")
|
||||||
|
public CaptchaResponse<ImageCaptchaVO> getCaptcha() {
|
||||||
|
if (!captchaProperties.getEnable() || !CaptchaType.ACT.getType().equalsIgnoreCase(captchaProperties.getType())) {
|
||||||
|
throw new ServiceException("验证码未开启");
|
||||||
|
}
|
||||||
|
String type = captchaProperties.getAct().getType();
|
||||||
|
if ("RANDOM".equalsIgnoreCase(type)) {
|
||||||
|
type = Arrays.asList(CaptchaTypeConstant.SLIDER, CaptchaTypeConstant.CONCAT, CaptchaTypeConstant.ROTATE, CaptchaTypeConstant.WORD_IMAGE_CLICK)
|
||||||
|
.get(ThreadLocalRandom.current().nextInt(4));
|
||||||
|
}
|
||||||
|
return imageCaptchaApplication.generateCaptcha(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验行为验证码
|
||||||
|
*/
|
||||||
|
@PostMapping("/auth/verify")
|
||||||
|
public ApiResponse<?> verify(@RequestBody CaptchaBo data) {
|
||||||
|
ApiResponse<?> response = imageCaptchaApplication.matching(data.getId(), data.getData());
|
||||||
|
if (response.isSuccess()) {
|
||||||
|
return ApiResponse.ofSuccess(Collections.singletonMap("id", data.getId()));
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
package org.dromara.web.domain.bo;
|
||||||
|
|
||||||
|
import cloud.tianai.captcha.validator.common.model.dto.ImageCaptchaTrack;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class CaptchaBo {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
private ImageCaptchaTrack data;
|
||||||
|
|
||||||
|
}
|
@ -15,6 +15,11 @@ public class CaptchaVo {
|
|||||||
*/
|
*/
|
||||||
private Boolean captchaEnabled = true;
|
private Boolean captchaEnabled = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证码类型
|
||||||
|
*/
|
||||||
|
private String type;
|
||||||
|
|
||||||
private String uuid;
|
private String uuid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package org.dromara.web.service.impl;
|
package org.dromara.web.service.impl;
|
||||||
|
|
||||||
|
import cloud.tianai.captcha.application.ImageCaptchaApplication;
|
||||||
|
import cloud.tianai.captcha.spring.plugins.secondary.SecondaryVerificationApplication;
|
||||||
import cn.dev33.satoken.secure.BCrypt;
|
import cn.dev33.satoken.secure.BCrypt;
|
||||||
import cn.dev33.satoken.stp.SaLoginModel;
|
import cn.dev33.satoken.stp.SaLoginModel;
|
||||||
import cn.dev33.satoken.stp.StpUtil;
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
@ -24,6 +26,7 @@ import org.dromara.common.redis.utils.RedisUtils;
|
|||||||
import org.dromara.common.satoken.utils.LoginHelper;
|
import org.dromara.common.satoken.utils.LoginHelper;
|
||||||
import org.dromara.common.tenant.helper.TenantHelper;
|
import org.dromara.common.tenant.helper.TenantHelper;
|
||||||
import org.dromara.common.web.config.properties.CaptchaProperties;
|
import org.dromara.common.web.config.properties.CaptchaProperties;
|
||||||
|
import org.dromara.common.web.enums.CaptchaType;
|
||||||
import org.dromara.system.domain.SysUser;
|
import org.dromara.system.domain.SysUser;
|
||||||
import org.dromara.system.domain.vo.SysClientVo;
|
import org.dromara.system.domain.vo.SysClientVo;
|
||||||
import org.dromara.system.domain.vo.SysUserVo;
|
import org.dromara.system.domain.vo.SysUserVo;
|
||||||
@ -43,6 +46,8 @@ import org.springframework.stereotype.Service;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class PasswordAuthStrategy implements IAuthStrategy {
|
public class PasswordAuthStrategy implements IAuthStrategy {
|
||||||
|
|
||||||
|
private final ImageCaptchaApplication imageCaptchaApplication;
|
||||||
|
|
||||||
private final CaptchaProperties captchaProperties;
|
private final CaptchaProperties captchaProperties;
|
||||||
private final SysLoginService loginService;
|
private final SysLoginService loginService;
|
||||||
private final SysUserMapper userMapper;
|
private final SysUserMapper userMapper;
|
||||||
@ -95,6 +100,13 @@ public class PasswordAuthStrategy implements IAuthStrategy {
|
|||||||
* @param uuid 唯一标识
|
* @param uuid 唯一标识
|
||||||
*/
|
*/
|
||||||
private void validateCaptcha(String tenantId, String username, String code, String uuid) {
|
private void validateCaptcha(String tenantId, String username, String code, String uuid) {
|
||||||
|
if (CaptchaType.ACT.getType().equalsIgnoreCase(captchaProperties.getType()) && imageCaptchaApplication instanceof SecondaryVerificationApplication) {
|
||||||
|
if (!((SecondaryVerificationApplication) imageCaptchaApplication).secondaryVerification(uuid)) {
|
||||||
|
loginService.recordLogininfor(tenantId, username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"));
|
||||||
|
throw new CaptchaException();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + StringUtils.blankToDefault(uuid, "");
|
String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + StringUtils.blankToDefault(uuid, "");
|
||||||
String captcha = RedisUtils.getCacheObject(verifyKey);
|
String captcha = RedisUtils.getCacheObject(verifyKey);
|
||||||
RedisUtils.deleteObject(verifyKey);
|
RedisUtils.deleteObject(verifyKey);
|
||||||
|
@ -7,18 +7,6 @@ ruoyi:
|
|||||||
# 版权年份
|
# 版权年份
|
||||||
copyrightYear: 2024
|
copyrightYear: 2024
|
||||||
|
|
||||||
captcha:
|
|
||||||
enable: true
|
|
||||||
# 页面 <参数设置> 可开启关闭 验证码校验
|
|
||||||
# 验证码类型 math 数组计算 char 字符验证
|
|
||||||
type: MATH
|
|
||||||
# line 线段干扰 circle 圆圈干扰 shear 扭曲干扰
|
|
||||||
category: CIRCLE
|
|
||||||
# 数字验证码位数
|
|
||||||
numberLength: 1
|
|
||||||
# 字符验证码长度
|
|
||||||
charLength: 4
|
|
||||||
|
|
||||||
# 开发环境配置
|
# 开发环境配置
|
||||||
server:
|
server:
|
||||||
# 服务器的HTTP端口,默认为8080
|
# 服务器的HTTP端口,默认为8080
|
||||||
@ -109,6 +97,24 @@ sa-token:
|
|||||||
|
|
||||||
# security配置
|
# security配置
|
||||||
security:
|
security:
|
||||||
|
#验证码
|
||||||
|
captcha:
|
||||||
|
# 是否开启验证码
|
||||||
|
enable: true
|
||||||
|
# 验证码类型 input 输入验证码 act 行为验证码
|
||||||
|
type: act
|
||||||
|
input:
|
||||||
|
# 验证码类型 math 数组计算 char 字符验证
|
||||||
|
type: char
|
||||||
|
# line 线段干扰 circle 圆圈干扰 shear 扭曲干扰 random 随机行为验证码
|
||||||
|
category: line
|
||||||
|
# 数字验证码位数
|
||||||
|
numberLength: 1
|
||||||
|
# 字符验证码长度
|
||||||
|
charLength: 4
|
||||||
|
act:
|
||||||
|
# RANDOM 随机 SLIDER 滑块验证 ROTATE 旋转验证 CONCAT 滑动还原 WORD_IMAGE_CLICK 文字点选
|
||||||
|
type: RANDOM
|
||||||
# 排除路径
|
# 排除路径
|
||||||
excludes:
|
excludes:
|
||||||
- /*.html
|
- /*.html
|
||||||
@ -120,6 +126,37 @@ security:
|
|||||||
- /*/api-docs
|
- /*/api-docs
|
||||||
- /*/api-docs/**
|
- /*/api-docs/**
|
||||||
|
|
||||||
|
# 滑块验证码配置, 详细请看 cloud.tianai.captcha.autoconfiguration.ImageCaptchaProperties 类
|
||||||
|
captcha:
|
||||||
|
# 如果项目中使用到了redis,滑块验证码会自动把验证码数据存到redis中, 这里配置redis的key的前缀,默认是captcha:slider
|
||||||
|
prefix: "captcha_act:"
|
||||||
|
# 验证码过期时间,默认是2分钟,单位毫秒, 可以根据自身业务进行调整
|
||||||
|
expire:
|
||||||
|
# 默认缓存时间 2分钟
|
||||||
|
default: 20000
|
||||||
|
# 针对 点选验证码 过期时间设置为 2分钟, 因为点选验证码验证比较慢,把过期时间调整大一些
|
||||||
|
WORD_IMAGE_CLICK: 30000
|
||||||
|
# 使用加载系统自带的资源, 默认是 false(这里系统的默认资源包含 滑动验证码模板/旋转验证码模板,如果想使用系统的模板,这里设置为true)
|
||||||
|
init-default-resource: true
|
||||||
|
# 缓存控制, 默认为false不开启
|
||||||
|
local-cache-enabled: true
|
||||||
|
# 验证码会提前缓存一些生成好的验证数据, 默认是20
|
||||||
|
local-cache-size: 20
|
||||||
|
# 缓存拉取失败后等待时间 默认是 5秒钟
|
||||||
|
local-cache-wait-time: 5000
|
||||||
|
# 缓存检查间隔 默认是2秒钟
|
||||||
|
local-cache-period: 2000
|
||||||
|
# 配置字体包,供文字点选验证码使用,可以配置多个,不配置使用默认的字体
|
||||||
|
font-path:
|
||||||
|
# - classpath:font/SimHei.ttf
|
||||||
|
secondary:
|
||||||
|
# 二次验证, 默认false 不开启
|
||||||
|
enabled: true
|
||||||
|
# 二次验证过期时间, 默认 2分钟
|
||||||
|
expire: 120000
|
||||||
|
# 二次验证缓存key前缀,默认是 captcha:secondary
|
||||||
|
keyPrefix: "captcha_secondary:"
|
||||||
|
|
||||||
# 多租户配置
|
# 多租户配置
|
||||||
tenant:
|
tenant:
|
||||||
# 是否开启
|
# 是否开启
|
||||||
|
BIN
ruoyi-admin/src/main/resources/bgimages/1.jpg
Normal file
BIN
ruoyi-admin/src/main/resources/bgimages/1.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 71 KiB |
BIN
ruoyi-admin/src/main/resources/bgimages/2.jpg
Normal file
BIN
ruoyi-admin/src/main/resources/bgimages/2.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 106 KiB |
BIN
ruoyi-admin/src/main/resources/bgimages/3.jpg
Normal file
BIN
ruoyi-admin/src/main/resources/bgimages/3.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 158 KiB |
BIN
ruoyi-admin/src/main/resources/bgimages/4.jpg
Normal file
BIN
ruoyi-admin/src/main/resources/bgimages/4.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 46 KiB |
BIN
ruoyi-admin/src/main/resources/bgimages/5.jpg
Normal file
BIN
ruoyi-admin/src/main/resources/bgimages/5.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 55 KiB |
@ -57,6 +57,12 @@
|
|||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-crypto</artifactId>
|
<artifactId>hutool-crypto</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>cloud.tianai.captcha</groupId>
|
||||||
|
<artifactId>tianai-captcha-springboot-starter</artifactId>
|
||||||
|
<version>${tianai-captcha.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
package org.dromara.common.web.config;
|
||||||
|
|
||||||
|
import cloud.tianai.captcha.common.constant.CaptchaTypeConstant;
|
||||||
|
import cloud.tianai.captcha.resource.ResourceStore;
|
||||||
|
import cloud.tianai.captcha.resource.common.model.dto.Resource;
|
||||||
|
import jakarta.annotation.PostConstruct;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class CaptchaResourceConfig {
|
||||||
|
|
||||||
|
private final ResourceStore resourceStore;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
// 添加自定义背景图片
|
||||||
|
resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "bgimages/1.jpg", "default"));
|
||||||
|
resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "bgimages/2.jpg", "default"));
|
||||||
|
resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "bgimages/3.jpg", "default"));
|
||||||
|
resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "bgimages/4.jpg", "default"));
|
||||||
|
resourceStore.addResource(CaptchaTypeConstant.SLIDER, new Resource("classpath", "bgimages/5.jpg", "default"));
|
||||||
|
|
||||||
|
resourceStore.addResource(CaptchaTypeConstant.ROTATE, new Resource("classpath", "bgimages/1.jpg", "default"));
|
||||||
|
resourceStore.addResource(CaptchaTypeConstant.ROTATE, new Resource("classpath", "bgimages/2.jpg", "default"));
|
||||||
|
resourceStore.addResource(CaptchaTypeConstant.ROTATE, new Resource("classpath", "bgimages/3.jpg", "default"));
|
||||||
|
resourceStore.addResource(CaptchaTypeConstant.ROTATE, new Resource("classpath", "bgimages/4.jpg", "default"));
|
||||||
|
resourceStore.addResource(CaptchaTypeConstant.ROTATE, new Resource("classpath", "bgimages/5.jpg", "default"));
|
||||||
|
|
||||||
|
resourceStore.addResource(CaptchaTypeConstant.CONCAT, new Resource("classpath", "bgimages/1.jpg", "default"));
|
||||||
|
resourceStore.addResource(CaptchaTypeConstant.CONCAT, new Resource("classpath", "bgimages/2.jpg", "default"));
|
||||||
|
resourceStore.addResource(CaptchaTypeConstant.CONCAT, new Resource("classpath", "bgimages/3.jpg", "default"));
|
||||||
|
resourceStore.addResource(CaptchaTypeConstant.CONCAT, new Resource("classpath", "bgimages/4.jpg", "default"));
|
||||||
|
resourceStore.addResource(CaptchaTypeConstant.CONCAT, new Resource("classpath", "bgimages/5.jpg", "default"));
|
||||||
|
|
||||||
|
resourceStore.addResource(CaptchaTypeConstant.WORD_IMAGE_CLICK, new Resource("classpath", "bgimages/1.jpg", "default"));
|
||||||
|
resourceStore.addResource(CaptchaTypeConstant.WORD_IMAGE_CLICK, new Resource("classpath", "bgimages/2.jpg", "default"));
|
||||||
|
resourceStore.addResource(CaptchaTypeConstant.WORD_IMAGE_CLICK, new Resource("classpath", "bgimages/3.jpg", "default"));
|
||||||
|
resourceStore.addResource(CaptchaTypeConstant.WORD_IMAGE_CLICK, new Resource("classpath", "bgimages/4.jpg", "default"));
|
||||||
|
resourceStore.addResource(CaptchaTypeConstant.WORD_IMAGE_CLICK, new Resource("classpath", "bgimages/5.jpg", "default"));
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
package org.dromara.common.web.config.properties;
|
package org.dromara.common.web.config.properties;
|
||||||
|
|
||||||
import org.dromara.common.web.enums.CaptchaCategory;
|
import org.dromara.common.web.enums.CaptchaCategory;
|
||||||
import org.dromara.common.web.enums.CaptchaType;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import org.dromara.common.web.enums.InputCaptchaType;
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -11,7 +11,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
|||||||
* @author Lion Li
|
* @author Lion Li
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@ConfigurationProperties(prefix = "captcha")
|
@ConfigurationProperties(prefix = "security.captcha")
|
||||||
public class CaptchaProperties {
|
public class CaptchaProperties {
|
||||||
|
|
||||||
private Boolean enable;
|
private Boolean enable;
|
||||||
@ -19,10 +19,28 @@ public class CaptchaProperties {
|
|||||||
/**
|
/**
|
||||||
* 验证码类型
|
* 验证码类型
|
||||||
*/
|
*/
|
||||||
private CaptchaType type;
|
private String type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证码类别
|
* 输入验证码的相关配置
|
||||||
|
*/
|
||||||
|
private InputCaptchaProperties input;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 行为验证码的相关配置
|
||||||
|
*/
|
||||||
|
private ActCaptchaProperties act;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class InputCaptchaProperties {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证码类型 math 数组计算, char 字符验证
|
||||||
|
*/
|
||||||
|
private InputCaptchaType type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证码类别 line 线段干扰, circle 圆圈干扰, shear 扭曲干扰, random 随机行为验证码
|
||||||
*/
|
*/
|
||||||
private CaptchaCategory category;
|
private CaptchaCategory category;
|
||||||
|
|
||||||
@ -35,4 +53,14 @@ public class CaptchaProperties {
|
|||||||
* 字符验证码长度
|
* 字符验证码长度
|
||||||
*/
|
*/
|
||||||
private Integer charLength;
|
private Integer charLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class ActCaptchaProperties {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 行为验证码类型 random 随机行为验证码
|
||||||
|
*/
|
||||||
|
private String type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
package org.dromara.common.web.enums;
|
package org.dromara.common.web.enums;
|
||||||
|
|
||||||
import cn.hutool.captcha.generator.CodeGenerator;
|
|
||||||
import cn.hutool.captcha.generator.RandomGenerator;
|
|
||||||
import org.dromara.common.web.utils.UnsignedMathGenerator;
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@ -18,12 +15,12 @@ public enum CaptchaType {
|
|||||||
/**
|
/**
|
||||||
* 数字
|
* 数字
|
||||||
*/
|
*/
|
||||||
MATH(UnsignedMathGenerator.class),
|
INPUT("INPUT"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字符
|
* 字符
|
||||||
*/
|
*/
|
||||||
CHAR(RandomGenerator.class);
|
ACT("ACT");
|
||||||
|
|
||||||
private final Class<? extends CodeGenerator> clazz;
|
private final String type;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
package org.dromara.common.web.enums;
|
||||||
|
|
||||||
|
import cn.hutool.captcha.generator.CodeGenerator;
|
||||||
|
import cn.hutool.captcha.generator.RandomGenerator;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.dromara.common.web.utils.UnsignedMathGenerator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证码类型
|
||||||
|
*
|
||||||
|
* @author Lion Li
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum InputCaptchaType {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数字
|
||||||
|
*/
|
||||||
|
MATH(UnsignedMathGenerator.class),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字符
|
||||||
|
*/
|
||||||
|
CHAR(RandomGenerator.class);
|
||||||
|
|
||||||
|
private final Class<? extends CodeGenerator> clazz;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user