自定义xss校验注解实现

master
RuoYi 2021-12-15 10:44:40 +08:00
parent ae8f069cbc
commit 5587d39d42
7 changed files with 97 additions and 3 deletions

View File

@ -5,6 +5,7 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
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.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -68,7 +69,7 @@ public class SysNoticeController extends BaseController
@Log(title = "通知公告", businessType = BusinessType.INSERT) @Log(title = "通知公告", businessType = BusinessType.INSERT)
@PostMapping("/add") @PostMapping("/add")
@ResponseBody @ResponseBody
public AjaxResult addSave(SysNotice notice) public AjaxResult addSave(@Validated SysNotice notice)
{ {
notice.setCreateBy(getLoginName()); notice.setCreateBy(getLoginName());
return toAjax(noticeService.insertNotice(notice)); return toAjax(noticeService.insertNotice(notice));
@ -92,7 +93,7 @@ public class SysNoticeController extends BaseController
@Log(title = "通知公告", businessType = BusinessType.UPDATE) @Log(title = "通知公告", businessType = BusinessType.UPDATE)
@PostMapping("/edit") @PostMapping("/edit")
@ResponseBody @ResponseBody
public AjaxResult editSave(SysNotice notice) public AjaxResult editSave(@Validated SysNotice notice)
{ {
notice.setUpdateBy(getLoginName()); notice.setUpdateBy(getLoginName());
return toAjax(noticeService.updateNotice(notice)); return toAjax(noticeService.updateNotice(notice));

View File

@ -11,6 +11,7 @@ import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.annotation.Excel.Type; import com.ruoyi.common.annotation.Excel.Type;
import com.ruoyi.common.annotation.Excels; import com.ruoyi.common.annotation.Excels;
import com.ruoyi.common.core.domain.BaseEntity; import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.xss.Xss;
/** /**
* sys_user * sys_user
@ -160,6 +161,7 @@ public class SysUser extends BaseEntity
this.roleId = roleId; this.roleId = roleId;
} }
@Xss(message = "登录账号不能包含脚本字符")
@NotBlank(message = "登录账号不能为空") @NotBlank(message = "登录账号不能为空")
@Size(min = 0, max = 30, message = "登录账号长度不能超过30个字符") @Size(min = 0, max = 30, message = "登录账号长度不能超过30个字符")
public String getLoginName() public String getLoginName()
@ -172,6 +174,7 @@ public class SysUser extends BaseEntity
this.loginName = loginName; this.loginName = loginName;
} }
@Xss(message = "用户昵称不能包含脚本字符")
@Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符") @Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
public String getUserName() public String getUserName()
{ {

View File

@ -0,0 +1,24 @@
package com.ruoyi.common.utils.bean;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
/**
* bean
*
* @author ruoyi
*/
public class BeanValidators
{
public static void validateWithException(Validator validator, Object object, Class<?>... groups)
throws ConstraintViolationException
{
Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
if (!constraintViolations.isEmpty())
{
throw new ConstraintViolationException(constraintViolations);
}
}
}

View File

@ -0,0 +1,27 @@
package com.ruoyi.common.xss;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* xss
*
* @author ruoyi
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(value = { ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER })
@Constraint(validatedBy = { XssValidator.class })
public @interface Xss
{
String message()
default "不允许任何脚本运行";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}

View File

@ -0,0 +1,29 @@
package com.ruoyi.common.xss;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* xss
*
* @author ruoyi
*/
public class XssValidator implements ConstraintValidator<Xss, String>
{
private final String HTML_PATTERN = "<(\\S*?)[^>]*>.*?|<.*? />";
@Override
public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext)
{
return !containsHtml(value);
}
public boolean containsHtml(String value)
{
Pattern pattern = Pattern.compile(HTML_PATTERN);
Matcher matcher = pattern.matcher(value);
return matcher.matches();
}
}

View File

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

View File

@ -3,6 +3,7 @@ package com.ruoyi.system.service.impl;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.validation.Validator;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -17,6 +18,7 @@ import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.ShiroUtils; import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanValidators;
import com.ruoyi.common.utils.security.Md5Utils; import com.ruoyi.common.utils.security.Md5Utils;
import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.system.domain.SysPost; import com.ruoyi.system.domain.SysPost;
@ -58,6 +60,9 @@ public class SysUserServiceImpl implements ISysUserService
@Autowired @Autowired
private ISysConfigService configService; private ISysConfigService configService;
@Autowired
protected Validator validator;
/** /**
* *
* *
@ -489,6 +494,7 @@ public class SysUserServiceImpl implements ISysUserService
SysUser u = userMapper.selectUserByLoginName(user.getLoginName()); SysUser u = userMapper.selectUserByLoginName(user.getLoginName());
if (StringUtils.isNull(u)) if (StringUtils.isNull(u))
{ {
BeanValidators.validateWithException(validator, user);
user.setPassword(Md5Utils.hash(user.getLoginName() + password)); user.setPassword(Md5Utils.hash(user.getLoginName() + password));
user.setCreateBy(operName); user.setCreateBy(operName);
this.insertUser(user); this.insertUser(user);
@ -497,6 +503,7 @@ public class SysUserServiceImpl implements ISysUserService
} }
else if (isUpdateSupport) else if (isUpdateSupport)
{ {
BeanValidators.validateWithException(validator, user);
user.setUpdateBy(operName); user.setUpdateBy(operName);
this.updateUser(user); this.updateUser(user);
successNum++; successNum++;