spring validate 实现
spring4.0+ 默认支持jsr303。spring validate 也支持自定义valdiate注解。因此采用自定义validate注解实现
代码地址:https://github.com/ChenXun1989/role-validate
自定义validate注解
/** * Project Name:chenxun-cros * File Name:RoleConstraint.java * Package Name:com.chenxun.validate * Date:2016年8月26日上午10:42:53 * Copyright (c) 2016, www midaigroup com Technology Co., Ltd. All Rights Reserved. * */ package com.chenxun.example.validate; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.CONSTRUCTOR; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.PARAMETER; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import javax.validation.Constraint; import javax.validation.Payload; import javax.validation.constraints.NotNull; /** * ClassName:RoleConstraint
* Function: TODO ADD FUNCTION.
* Reason: TODO ADD REASON.
* Date: 2016年8月26日 上午10:42:53
* @author 陈勋 * @version * @since JDK 1.7 * @see */ @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy=RoleConstraintValidator.class) public @interface RoleConstraint { String message() default "ACCESS DENIED !"; Class>[] groups() default { }; Class extends Payload>[] payload() default { }; /** * * values:(角色列表).
* ROLE_ADMIN,ROLE_USER * @author 陈勋 * @return * @since JDK 1.7 */ String[] value(); }
实现constraintValidator 接口
/** * Project Name:chenxun-cros * File Name:RoleConstraintValidator.java * Package Name:com.chenxun.validate * Date:2016年8月26日上午10:39:29 * Copyright (c) 2016, www midaigroup com Technology Co., Ltd. All Rights Reserved. * */ package com.chenxun.example.validate; import java.lang.annotation.Annotation; import java.util.Collection; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorContextImpl; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; /** * ClassName:RoleConstraintValidator
* Function: TODO ADD FUNCTION.
* Reason: TODO ADD REASON.
* Date: 2016年8月26日 上午10:39:29
* * @author 陈勋 * @version * @since JDK 1.7 * @see */ public class RoleConstraintValidator implements ConstraintValidator{ @Override public void initialize(Annotation constraintAnnotation) { // 初始化动作 可以提升性能。缓存用户的 所有字段。 优化下个方法调用 } @Override public boolean isValid(Object value, ConstraintValidatorContext context) { //默认值处理 if (value == null) { return true; } if (value instanceof Number) { Number num = (Number) value; if (num.byteValue() == 0) { return true; } } // 获取当前用户的角色列表 ConstraintValidatorContextImpl cvci = (ConstraintValidatorContextImpl) context; RoleConstraint rc = (RoleConstraint) cvci.getConstraintDescriptor() .getAnnotation(); String[] roles = rc.value(); // 执行相关逻辑 角色和资源的关系(是否拥有资源权限) // 注意该校验与 value值无关 Collection extends GrantedAuthority> auths = SecurityContextHolder .getContext().getAuthentication().getAuthorities(); for (GrantedAuthority auth : auths) { // 简单原则,有其中一个角色即可 for (String role : roles) { if (role.equals(auth.getAuthority())) { return true; } } } return false; } }
表单对象
/** * Project Name:validate-role * File Name:Product.java * Package Name:com.chenxun.example.entity * Date:2016年8月26日下午12:59:12 * Copyright (c) 2016, www midaigroup com Technology Co., Ltd. All Rights Reserved. * */ package com.chenxun.example.entity; import lombok.Data; import com.chenxun.example.validate.RoleConstraint; /** * ClassName:Product
* Function: TODO ADD FUNCTION.
* Reason: TODO ADD REASON.
* Date: 2016年8月26日 下午12:59:12
* @author 陈勋 * @version * @since JDK 1.7 * @see */ @Data public class Product { private String name; @RoleConstraint("ROLE_USER") private String password; @RoleConstraint("ROLE_ADMIN") private String desc; }
权限控制
/** * Project Name:validate-role * File Name:SecurityConfig.java * Package Name:com.chenxun.example.config * Date:2016年8月26日下午1:04:18 * Copyright (c) 2016, www midaigroup com Technology Co., Ltd. All Rights Reserved. * */ package com.chenxun.example.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; /** * ClassName:SecurityConfig
* Function: TODO ADD FUNCTION.
* Reason: TODO ADD REASON.
* Date: 2016年8月26日 下午1:04:18
* @author 陈勋 * @version * @since JDK 1.7 * @see */ @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("admin").password("admin").roles("USER","ADMIN") .and().withUser("user").password("user").roles("USER"); } @Override protected void configure(HttpSecurity http) throws Exception { http.formLogin().defaultSuccessUrl("/index.html"); http.csrf().disable(); http.authorizeRequests().antMatchers("/**").hasRole("USER"); } }
/** * Project Name:validate-role * File Name:SecurityWebApplicationInitializer.java * Package Name:com.chenxun.example.config * Date:2016年8月26日下午1:37:41 * Copyright (c) 2016, www midaigroup com Technology Co., Ltd. All Rights Reserved. * */ package com.chenxun.example.config; import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer; /** * ClassName:SecurityWebApplicationInitializer
* Function: TODO ADD FUNCTION.
* Reason: TODO ADD REASON.
* Date: 2016年8月26日 下午1:37:41
* @author 陈勋 * @version * @since JDK 1.7 * @see */ public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer{ }
controler配置
package com.chenxun.example.controller; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import org.springframework.core.io.Resource; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.security.access.annotation.Secured; import org.springframework.util.FileCopyUtils; import org.springframework.validation.BindingResult; 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.servlet.ModelAndView; import org.springframework.web.servlet.View; import com.chenxun.example.entity.Product; /** * * ClassName: ProdudctController
* Function: TODO ADD FUNCTION.
* Reason: TODO ADD REASON(可选).
* date: 2016年8月26日 下午12:58:23
* * @author 陈勋 * @version * @since JDK 1.7 */ @RestController public class ProdudctController { @PostMapping("/product") public ResponseEntityproduct(@Valid @RequestBody Product product,BindingResult result){ if(result.hasErrors()){ return ResponseEntity.ok(result.getFieldError().getDefaultMessage()); } return ResponseEntity.ok("SUCCESS"); } }
页面测试
index Hello world
重新登陆