solon-security-validation
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-security-validation</artifactId>
</dependency>
1、描述
基础扩展插件,为 solon 提供完整的数据校验能力。支持:
- 动作注解校验
- 支持 Context::paramMap 数据校验
- 支持行为验证,比如重复提交(需要对接)
- 支持身份验证,比如白名单(需要对接)
- 参数注解校验
- 实体注解校验
默认策略,有校验不通过的会马上返回。如果校验所有,需加配置申明(返回的信息结构会略不同):
solon.validation.validateAll: true
能力实现与说明:
加注位置 | 能力实现基础 | 说明 |
---|---|---|
函数 | 基于 @Addition(Filter.class) 实现 | 对请求上下文里的值做校验(header, param..) |
参数 | 基于 @Around(Interceptor.class) 实现 | 对函数的参数值本身做校验 |
2、校验注解清单
注解 | 作用范围 | 说明 |
---|---|---|
Valid | 控制器类 | 启用校验能力(加在控制器或者控制器基类上) |
Validated | 参数 或 字段 | 校验(参数或字段的类型)实体类上的字段 |
Date | 参数 或 字段 | 校验注解的值为日期格式 |
DecimalMax(value) | 参数 或 字段 | 校验注解的值小于等于@ DecimalMax指定的value值 |
DecimalMin(value) | 参数 或 字段 | 校验注解的值大于等于@ DecimalMin指定的value值 |
参数 或 字段 | 校验注解的值为电子邮箱格式 | |
Length(min, max) | 参数 或 字段 | 校验注解的值长度在min和max区间内(对字符串有效) |
Logined | 控制器 或 动作 | 校验本次请求主体已登录 |
Max(value) | 参数 或 字段 | 校验注解的值小于等于@Max指定的value值 |
Min(value) | 参数 或 字段 | 校验注解的值大于等于@Min指定的value值 |
NoRepeatSubmit | 控制器 或 动作 | 校验本次请求没有重复提交 |
NotBlacklist | 控制器 或 动作 | 校验本次请求主体不在黑名单 |
NotBlank | 动作 或 参数 或 字段 | 校验注解的值不是空白 |
NotEmpty | 动作 或 参数 或 字段 | 校验注解的值不是空 |
NotNull | 动作 或 参数 或 字段 | 校验注解的值不是null |
NotZero | 动作 或 参数 或 字段 | 校验注解的值不是0 |
Null | 动作 或 参数 或 字段 | 校验注解的值是null |
Numeric | 动作 或 参数 或 字段 | 校验注解的值为数字格式 |
Pattern(value) | 参数 或 字段 | 校验注解的值与指定的正则表达式匹配 |
Size | 参数 或 字段 | 校验注解的集合大小在min和max区间内(对集合有效) |
Whitelist | 控制器 或 动作 | 校验本次请求主体在白名单范围内 |
3、@Valid
与 @Validated
的区别
- Valid
用于启用校验能力。加在控制器或者控制器基类上。
- Validated
校验(参数或字段的类型)实体类上的字段。加在参数或字段上。
4、应用示例
//可以加在方法上、或控制器类上(或者控制器基类上)
@Valid
@Controller
public class UserController {
//
//这里只是演示,用时别乱加
//
@NoRepeatSubmit //重复提交验证
@Whitelist //白名单验证
@Mapping("/user/add")
public void addUser(
@NotNull String name,
@Pattern("^http") String icon, //注解在参数或字段上时,不需要加 value 属性
@Validated User user) //实体校验,需要加 @Validated
{
//...
}
//分组校验
@Mapping("/user/update")
public void updateUser(@Validated(UpdateLabel.class) User user){
//...
}
}
@Data
public class User {
@NotNull(groups = UpdateLabel.class) //用于分组校验
private Long id;
@NotNull
private String nickname;
@Email //注解在参数或字段上时,不需要加 value 属性
private String email;
}
5、需要业务检测对接的四个注解
- @NoRepeatSubmit 不能重复提交注解
//示例:通过组件模式定义检测器(或通过配置器生产Bean)
@Component
public class NoRepeatSubmitCheckerImpl implements NoRepeatSubmitChecker {
@Override
public boolean check(NoRepeatSubmit anno, Context ctx, String submitHash, int limitSeconds) {
//借用分布式锁,挡住 submitHash 在一定时间内多次进入
return LockUtils.tryLock(Solon.cfg().appName(), submitHash, limitSeconds);
}
}
- @Whitelist 白名单注解(即在一个名单里)
//示例:通过组件模式定义检测器(或通过配置器生产Bean)
@Component
public class WhitelistCheckerImpl implements WhitelistChecker {
@Override
public boolean check(Whitelist anno, Context ctx) {
String ip = ctx.realIp(); //此处以ip为例,其实也可以是任何东西
//借用业务系统的名单列表,进行检测
return CloudClient.list().inListOfIp("whitelist",ip);
}
}
- @NotBlacklist 非黑名单注解(即不在一个名单里)
//示例:通过组件模式定义检测器(或通过配置器生产Bean)
@Component
public class NotBlacklistCheckerImpl implements NotBlacklistChecker {
@Override
public boolean check(NotBlacklist anno, Context ctx) {
String ip = ctx.realIp(); //此处以ip为例,其实也可以是任何东西
//借用业务系统的名单列表,进行检测
return CloudClient.list().inListOfIp("blacklist",ip) == false;
}
}
- @Logined 已登录注解
//示例:通过组件模式定义检测器(或通过配置器生产Bean)
@Component
public class LoginedCheckerImpl implements LoginedChecker {
@Override
public boolean check(Logined anno, Context ctx, String userKeyName) {
return ctx.sessionAsLong(Constants.SESSION_USER_ID) > 0;
}
}