`
LoveLZY
  • 浏览: 57734 次
  • 性别: Icon_minigender_1
博客专栏
Group-logo
从零编写RPC框架
浏览量:0
社区版块
存档分类
最新评论

基于用户角色的细粒度validate

阅读更多
  今天群里小伙伴有个需求,希望通过role来控制pojo字段校验。采用方式为spirng securtity+
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 <br/>
 * Function: TODO ADD FUNCTION. <br/>
 * Reason:	 TODO ADD REASON. <br/>
 * Date:     2016年8月26日 上午10:42:53 <br/>
 * @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:(角色列表). <br/>
	 * 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 <br/>
 * Function: TODO ADD FUNCTION. <br/>
 * Reason: TODO ADD REASON. <br/>
 * Date: 2016年8月26日 上午10:39:29 <br/>
 * 
 * @author 陈勋
 * @version
 * @since JDK 1.7
 * @see
 */
public class RoleConstraintValidator implements
		ConstraintValidator<Annotation, Object> {

	@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 <br/>
 * Function: TODO ADD FUNCTION. <br/>
 * Reason:	 TODO ADD REASON. <br/>
 * Date:     2016年8月26日 下午12:59:12 <br/>
 * @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 <br/>
 * Function: TODO ADD FUNCTION. <br/>
 * Reason:	 TODO ADD REASON. <br/>
 * Date:     2016年8月26日 下午1:04:18 <br/>
 * @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 <br/>
 * Function: TODO ADD FUNCTION. <br/>
 * Reason:	 TODO ADD REASON. <br/>
 * Date:     2016年8月26日 下午1:37:41 <br/>
 * @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 <br/>
 * Function: TODO ADD FUNCTION. <br/>
 * Reason: TODO ADD REASON(可选). <br/>
 * date: 2016年8月26日 下午12:58:23 <br/>
 *
 * @author 陈勋
 * @version 
 * @since JDK 1.7
 */
@RestController
public class ProdudctController {
	
	@PostMapping("/product")
	public ResponseEntity<String> product(@Valid  @RequestBody Product product,BindingResult result){
		if(result.hasErrors()){
			return ResponseEntity.ok(result.getFieldError().getDefaultMessage());
		}
		return ResponseEntity.ok("SUCCESS");
	}
	
	
	
	

}


  页面测试
 <!DOCTYPE html>
<html >

<head>
<meta charset="utf-8">
<title>index</title>
<script type="text/javascript" src="jquery.min.js"></script>
</head>
<body >
    <h1>Hello world</h1>
    
    <input type="button" value="testRoleUser" id="add1">
     <input type="button" value="testRoleAdmin" id="add2">
     
     
     <a href="/logout">重新登陆</a>

	<script type="text/javascript">
		$(function(){
			
			$("#add1").on("click",function(){
				
				var values={
	    				name:"abc",
	    				password:"pass"
	    		}
				
				 $.ajax({
		    			url:"product",
		    			type:"post",
		    			contentType:"application/json",
		    			data:JSON.stringify(values) ,		    			
		    			success:function(res){
		    				alert(res);
		    			}
		    		}); 
			});
			
			$("#add2").on("click",function(){
				
				var values={
	    				name:"abc",
	    				desc:"pass"
	    		}
				
				 $.ajax({
		    			url:"product",
		    			type:"post",
		    			contentType:"application/json",
		    			data:JSON.stringify(values) ,		    			
		    			success:function(res){
		    				alert(res);
		    			}
		    		}); 
			});
    		
		});
	
	</script>
</body>
</html>



分享到:
评论

相关推荐

    LigerRM权限管理系统v1.0源码

    在权限管理系统中,这两个模块是核心,它们允许管理员分配和管理用户与角色的权限,实现细粒度的访问控制。用户权限列表允许管理员查看和修改单个用户的权限,而角色权限列表则集中管理角色所包含的一系列权限,便于...

    详解ABP框架的参数有效性验证和权限验证_.docx

    在ABP中,权限管理通常与角色和用户关联,允许细粒度地控制谁可以访问哪些资源。权限验证通常在应用服务层进行,通过检查当前登录用户的权限来决定是否允许执行某个操作。 在上述`TaskAppService`示例中,虽然没有...

    详解ABP框架的参数有效性验证和权限验证

    权限管理是ABP的核心特性之一,它允许细粒度的控制,比如基于角色、基于功能或基于业务实体的权限。 #### 基于角色的权限 ABP支持角色系统,每个角色可以拥有多个权限。用户可以分配给一个或多个角色,从而继承...

    Laravel开发-laravel-blog

    还可以结合角色和权限插件,如`spatie/laravel-permission`,实现更细粒度的访问控制。 ### 9. API集成与响应式设计 为了让博客功能更加强大,可以考虑集成第三方服务,如社交媒体分享按钮、评论系统或SEO优化工具...

    Laravel开发-project

    - 权限与角色:使用 Laravel 的 Gate 或政策类实现细粒度的访问控制。 10. **错误处理与日志** - 错误处理:Laravel 自动处理 PHP 错误和异常,提供友好的错误页面。 - 日志:Laravel 使用 Monolog 库记录日志,...

    经典:《网站系统安全开发手册》

    - **细粒度权限管理**: 为不同类型的用户分配不同的权限。 - **角色模型**: 依据用户的角色来授予不同的访问权限。 - **访问控制列表(ACL)**: 明确指定哪些用户可以访问哪些资源。 #### 第七节 IO操作安全 本节...

    关于HttpHandler与HttpModule的理解和应用方法

    而HttpHandler 更加具体,只处理特定类型的HTTP请求,提供更加细粒度的控制。 在实际应用中,HttpModule 可以用于实现以下功能: 1. 自定义身份验证:例如,实现基于OAuth或JWT的身份验证逻辑。 2. 日志记录:记录...

Global site tag (gtag.js) - Google Analytics