Browse Source

自定义xss校验注解实现

RuoYi 4 years ago
parent
commit
f91f931c0b

+ 4 - 3
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysUser.java

@@ -2,9 +2,7 @@ package com.ruoyi.system.api.domain;
2 2
 
3 3
 import java.util.Date;
4 4
 import java.util.List;
5
-import javax.validation.constraints.Email;
6
-import javax.validation.constraints.NotBlank;
7
-import javax.validation.constraints.Size;
5
+import javax.validation.constraints.*;
8 6
 import org.apache.commons.lang3.builder.ToStringBuilder;
9 7
 import org.apache.commons.lang3.builder.ToStringStyle;
10 8
 import com.fasterxml.jackson.annotation.JsonProperty;
@@ -13,6 +11,7 @@ import com.ruoyi.common.core.annotation.Excel.ColumnType;
13 11
 import com.ruoyi.common.core.annotation.Excel.Type;
14 12
 import com.ruoyi.common.core.annotation.Excels;
15 13
 import com.ruoyi.common.core.web.domain.BaseEntity;
14
+import com.ruoyi.common.core.xss.Xss;
16 15
 
17 16
 /**
18 17
  * 用户对象 sys_user
@@ -131,6 +130,7 @@ public class SysUser extends BaseEntity
131 130
         this.deptId = deptId;
132 131
     }
133 132
 
133
+    @Xss(message = "用户昵称不能包含脚本字符")
134 134
     @Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
135 135
     public String getNickName()
136 136
     {
@@ -142,6 +142,7 @@ public class SysUser extends BaseEntity
142 142
         this.nickName = nickName;
143 143
     }
144 144
 
145
+    @Xss(message = "用户账号不能包含脚本字符")
145 146
     @NotBlank(message = "用户账号不能为空")
146 147
     @Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符")
147 148
     public String getUserName()

+ 24 - 0
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/bean/BeanValidators.java

@@ -0,0 +1,24 @@
1
+package com.ruoyi.common.core.utils.bean;
2
+
3
+import java.util.Set;
4
+import javax.validation.ConstraintViolation;
5
+import javax.validation.ConstraintViolationException;
6
+import javax.validation.Validator;
7
+
8
+/**
9
+ * bean对象属性验证
10
+ * 
11
+ * @author ruoyi
12
+ */
13
+public class BeanValidators
14
+{
15
+    public static void validateWithException(Validator validator, Object object, Class<?>... groups)
16
+            throws ConstraintViolationException
17
+    {
18
+        Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
19
+        if (!constraintViolations.isEmpty())
20
+        {
21
+            throw new ConstraintViolationException(constraintViolations);
22
+        }
23
+    }
24
+}

+ 27 - 0
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/xss/Xss.java

@@ -0,0 +1,27 @@
1
+package com.ruoyi.common.core.xss;
2
+
3
+import javax.validation.Constraint;
4
+import javax.validation.Payload;
5
+import java.lang.annotation.ElementType;
6
+import java.lang.annotation.Retention;
7
+import java.lang.annotation.RetentionPolicy;
8
+import java.lang.annotation.Target;
9
+
10
+/**
11
+ * 自定义xss校验注解
12
+ * 
13
+ * @author ruoyi
14
+ */
15
+@Retention(RetentionPolicy.RUNTIME)
16
+@Target(value = { ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER })
17
+@Constraint(validatedBy = { XssValidator.class })
18
+public @interface Xss
19
+{
20
+    String message()
21
+
22
+    default "不允许任何脚本运行";
23
+
24
+    Class<?>[] groups() default {};
25
+
26
+    Class<? extends Payload>[] payload() default {};
27
+}

+ 29 - 0
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/xss/XssValidator.java

@@ -0,0 +1,29 @@
1
+package com.ruoyi.common.core.xss;
2
+
3
+import javax.validation.ConstraintValidator;
4
+import javax.validation.ConstraintValidatorContext;
5
+import java.util.regex.Matcher;
6
+import java.util.regex.Pattern;
7
+
8
+/**
9
+ * 自定义xss校验注解实现
10
+ * 
11
+ * @author ruoyi
12
+ */
13
+public class XssValidator implements ConstraintValidator<Xss, String>
14
+{
15
+    private final String HTML_PATTERN = "<(\\S*?)[^>]*>.*?|<.*? />";
16
+
17
+    @Override
18
+    public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext)
19
+    {
20
+        return !containsHtml(value);
21
+    }
22
+
23
+    public boolean containsHtml(String value)
24
+    {
25
+        Pattern pattern = Pattern.compile(HTML_PATTERN);
26
+        Matcher matcher = pattern.matcher(value);
27
+        return matcher.matches();
28
+    }
29
+}

+ 2 - 1
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysNotice.java

@@ -4,8 +4,8 @@ import javax.validation.constraints.NotBlank;
4 4
 import javax.validation.constraints.Size;
5 5
 import org.apache.commons.lang3.builder.ToStringBuilder;
6 6
 import org.apache.commons.lang3.builder.ToStringStyle;
7
-
8 7
 import com.ruoyi.common.core.web.domain.BaseEntity;
8
+import com.ruoyi.common.core.xss.Xss;
9 9
 
10 10
 /**
11 11
  * 通知公告表 sys_notice
@@ -46,6 +46,7 @@ public class SysNotice extends BaseEntity
46 46
         this.noticeTitle = noticeTitle;
47 47
     }
48 48
 
49
+    @Xss(message = "公告标题不能包含脚本字符")
49 50
     @NotBlank(message = "公告标题不能为空")
50 51
     @Size(min = 0, max = 50, message = "公告标题不能超过50个字符")
51 52
     public String getNoticeTitle()

+ 7 - 0
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java

@@ -3,6 +3,7 @@ package com.ruoyi.system.service.impl;
3 3
 import java.util.ArrayList;
4 4
 import java.util.List;
5 5
 import java.util.stream.Collectors;
6
+import javax.validation.Validator;
6 7
 import org.slf4j.Logger;
7 8
 import org.slf4j.LoggerFactory;
8 9
 import org.springframework.beans.factory.annotation.Autowired;
@@ -13,6 +14,7 @@ import com.ruoyi.common.core.constant.UserConstants;
13 14
 import com.ruoyi.common.core.exception.ServiceException;
14 15
 import com.ruoyi.common.core.utils.SpringUtils;
15 16
 import com.ruoyi.common.core.utils.StringUtils;
17
+import com.ruoyi.common.core.utils.bean.BeanValidators;
16 18
 import com.ruoyi.common.datascope.annotation.DataScope;
17 19
 import com.ruoyi.common.security.utils.SecurityUtils;
18 20
 import com.ruoyi.system.api.domain.SysRole;
@@ -56,6 +58,9 @@ public class SysUserServiceImpl implements ISysUserService
56 58
     @Autowired
57 59
     private ISysConfigService configService;
58 60
 
61
+    @Autowired
62
+    protected Validator validator;
63
+
59 64
     /**
60 65
      * 根据条件分页查询用户列表
61 66
      * 
@@ -513,6 +518,7 @@ public class SysUserServiceImpl implements ISysUserService
513 518
                 SysUser u = userMapper.selectUserByUserName(user.getUserName());
514 519
                 if (StringUtils.isNull(u))
515 520
                 {
521
+                    BeanValidators.validateWithException(validator, user);
516 522
                     user.setPassword(SecurityUtils.encryptPassword(password));
517 523
                     user.setCreateBy(operName);
518 524
                     this.insertUser(user);
@@ -521,6 +527,7 @@ public class SysUserServiceImpl implements ISysUserService
521 527
                 }
522 528
                 else if (isUpdateSupport)
523 529
                 {
530
+                    BeanValidators.validateWithException(validator, user);
524 531
                     user.setUpdateBy(operName);
525 532
                     this.updateUser(user);
526 533
                     successNum++;