security权限管理详解

Posted 程序三两行

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了security权限管理详解相关的知识,希望对你有一定的参考价值。

一、授权流程

用户登录成功后会将用户信息保存在Authencation对象中,Authencation接口中有一个getAuthorities()方法返回的是用户的权限

Collection<? extends GrantedAuthority> getAuthorities();

现有系统可以基于角色做权限管理也可以使用资源(权限字符串)做权限管理,这里的GrantedAuthority是角色还是资源呢?

  • 如果 业务是基于角色做的权限管理,即用户->角色->资源,那么返回的是用户的角色
  • 如果业务是基于资源(权限)做的权限管理,即用户->权限->资源,返回的是用户的权限
  • 如果基于角色+权限做的权限管理,即用户->角色->权限->资源,返回的是用户的权限

security在角色和权限的处理方式上基本一样的,唯一区别就是很多时候会自动给角色增加一个ROLE_前缀,而权限不会添加

 

二、权限管理策略

1、基于URL做权限管理(过滤器技术实现)

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter 
    //创建内存数据源
    public UserDetailsService userDetailsService()
        InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();
        //admin用户 具有ADMIN 和 USER角色
        inMemoryUserDetailsManager.createUser(User.withUsername("admin").password("noop123").roles("ADMIN","USER").build());
        //user用户 具有USER角色
        inMemoryUserDetailsManager.createUser(User.withUsername("user").password("noop123").roles("USER").build());
        //info用户具有READ_INFO权限操作
        inMemoryUserDetailsManager.createUser(User.withUsername("info").password("noop123").authorities("READ_INFO").build());
        return inMemoryUserDetailsManager;
    

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception 
        auth.userDetailsService(userDetailsService());
    

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http.authorizeRequests()
                //访问/admin必须有ADMIN角色
                .mvcMatchers("/admin").hasRole("ADMIN")
                //访问/user需要USER角色或者ADMIN角色
                .mvcMatchers("/user").hasAnyRole("ADMIN","USER")
                //访问/info必须有READ_INFO权限
                .mvcMatchers("/info").hasAuthority("READ_INFO")
                .anyRequest().authenticated()
                .and().formLogin()
                .and().csrf().disable();
    

备注1:上面的hasRole()、hasAuthority()称为权限表达式,类如下

 

备注2:mvcMatchers、antMatchers、regexMatchers区别是?

1、mvcMatchers是在antMatchers之后增加的,两个都可以传递请求方式以及多个路径,如下

.mvcMatchers(HttpMethod.GET,"/admin","/test").hasRole("ADMIN")
.antMatchers(HttpMethod.GET,"/admin","/test").hasRole("ADMIN")

2、mvcMatchers相对antMatchers更加强大一些,比如mvcMatchers("/admin")可以匹配“/admin"还可以匹配"/admin/" 、"/admin/a"、"/admin.html",但是.antMatchers("/admin")只能匹配"/admin"

3、regexMatchers则是可以通过正在表达式匹配

2、基于方法策略权限管理(基于AOP技术实现)

基于方法的权限管理是基于aop技术实现的,security中通过MethodSecurityInterceptor提供相关实现,不同在于FilterSecurityInterceptor只是请求前置进行处理,而MethodSecurityInterceptor除了前置请求还可以进行后置请求,前置是在请求之前判断是否具有相应的权限,后置则是对方法的执行结果进行二次过滤,前置和后置分别对应了不同的实现类,

/**
 * EnableGlobalMethodSecurity是开启全局方法的权限注解
 * prePostEnabled开启security提供的四个权限注解,这四个注解支持上面的权限表达式
 *      @PostFilter在目标方法执行之后对方法的返回结果进行过滤
 *      @PostAuthorize在目标方法执行之后进行权限校验
 *      @PreAuthorize在目标方法执行之前进行校验
 *      @PreFilter在目标方法执行之前对参数进行过滤
 * securedEnabled开启security提供的@secured,只支持角色,不支持权限表达式
 *      @secured访问目标方法必须具备相应的角色
 * jsr250Enabled开启JSR-250提供的三个权限注解,同样只支持角色不支持权限表达式
 *      @DenyAll拒绝所有访问
 *      @PermitAll允许所有访问
 *      @RolesAllowed访问目标方法必须具备相应的角色
 *
 *这些基于方法的权限注解,一般来说只要设置prePostEnabled=true就够了
 */
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true,jsr250Enabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter 
    //创建内存数据源
    @Bean
    public UserDetailsService userDetailsService()
        InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();
        //admin用户 具有ADMIN 和 USER角色
        inMemoryUserDetailsManager.createUser(User.withUsername("admin").password("noop123").roles("ADMIN","USER").build());
        //user用户 具有USER角色
        inMemoryUserDetailsManager.createUser(User.withUsername("user").password("noop123").roles("USER").build());
        //info用户具有READ_INFO权限操作
        inMemoryUserDetailsManager.createUser(User.withUsername("info").password("noop123").authorities("READ_INFO").build());
        return inMemoryUserDetailsManager;
    

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception 
        auth.userDetailsService(userDetailsService());
    

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and().formLogin()
                .and().csrf().disable();
    

 使用

@RestController
@RequestMapping("/demo")
public class DemoController 
    /**
    *可以使用权限表达式以及and or
    *除了角色还可以使用权限hasAuthority
    */
    @PreAuthorize("hasRole('ADMIN') and authentication.name=='admin'")
    @GetMapping("/user")
    public String user()
        return "user";
    
    /**
    * 传的参数如果和登录用户的账号相同才能访问
    */
    @PreAuthorize("authentication.name==#username")
    @GetMapping("/name")
    public String name(String username)
        return "name";
    
    /**
    * 请求方法前对参数过滤 参数必须是数组、集合
    */
    @PreFilter(value = "filterTarget.id%2!=0",filterTarget = "users")
    @GetMapping("/users")
    public String name(@RequestBody List<User> users)
        return "user";
    
    /**
    * 返回指定的对象
    */
    @PostAuthorize("returnObject.id==1")
    @GetMapping("/userId")
    public String userId(@RequestBody List<User> users)
        return "userId";
    
    /**
    * 过滤方法的返回值 返回值是数组或者集合
    */
    @PostFilter("filterTarget.id%2==0")
    @GetMapping("/all")
    public String all(@RequestBody List<User> users)
        return "all";
    
    
    /**
    * 只能判断角色,可以是多个 ,具有其中一个即可
    */
    @Secured("ROLE_USER,ROLE_ADMIN")
    @GetMapping("/Secured")
    public String secured(@RequestBody List<User> users)
        return "Secured";
    
    
    /**
    * 放行所有
    */
    @PermitAll
    @GetMapping("/PermitAll")
    public String permitAll(@RequestBody List<User> users)
        return "PermitAll";
    
    
    /**
    * 拒绝所有请求
    */
    @DenyAll
    @GetMapping("/denyall")
    public String denyAll()
        return "denyall";
    
    
    /**
    * 具有其中一个角色即可
    */
    @RolesAllowed("ROLE_ADMIN,ROLE_USER")
    @GetMapping("/rolseAll")
    public String rolseAll()
        return "rolseAll";
    

Java权限管理之Spring Security

1、技术目标

 

 

  • 了解并创建Security框架所需数据表
  • 为项目添加Spring Security框架
  • 掌握Security框架配置
  • 应用Security框架为项目的CRUD操作绑定权限

 

 

注意:本文所用项目为"影片管理",参看

http://hotstrong.iteye.com/blog/1156785

 

2、权限管理需求描述

 

  • 为系统中的每个操作定义权限,如定义4个权限:
     1)超级权限,可以使用所有操作
     2)添加影片权限
     3)修改影片权限
     4)删除影片权限
  • 为系统设置管理员帐号、密码
  • 为系统创建权限组,每个权限组可以配置多个操作权限,如创建2个权限组:
     1)"Administrator"权限组,具有超级权限
     2)"影片维护"权限组,具有添加影片、修改影片权限
  • 可将管理员加入权限组,管理员登录后具备权限组所对应操作权限
  • 管理员可不属于某权限组,可为管理员直接分配权限

 

 

3、使用准备

 

3.1)在数据库中创建6张表

 

t_admin        管理员帐号表

t_role权限表

t_group        权限组表

t_group_role权限组对应权限表

t_group_user管理员所属权限组表

t_user_role管理员对应权限表

 

建表SQL语句如下:

 

 

Sql代码  
  1. SET FOREIGN_KEY_CHECKS=0;  
  2.     ------------------------------  
  3.     -- 创建管理员帐号表t_admin  
  4.     -- ----------------------------  
  5.     CREATE TABLE `t_admin` (  
  6.       `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,  
  7.       `passwd` varchar(12) NOT NULL DEFAULT '' COMMENT '用户密码',  
  8.       `nickname` varchar(20) NOT NULL DEFAULT '' COMMENT '用户名字',  
  9.       `phoneno` varchar(32) NOT NULL DEFAULT '' COMMENT '电话号码',  
  10.       PRIMARY KEY (`id`)  
  11.     ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;  
  12.   
  13.     -- ----------------------------  
  14.     -- 添加3个管理帐号   
  15.     -- ----------------------------  
  16.     INSERT INTO `t_admin` VALUES ('1''admin''admin''');  
  17.     INSERT INTO `t_admin` VALUES ('4''123456''test''');  
  18.     INSERT INTO `t_admin` VALUES ('5''111111''111111''');  
  19.       
  20.     -- ----------------------------  
  21.     -- 创建权限表t_role  
  22.     -- ----------------------------  
  23.     CREATE TABLE `t_role` (  
  24.       `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,  
  25.       `role` varchar(40) NOT NULL DEFAULT '',  
  26.       `descpt` varchar(40) NOT NULL DEFAULT '' COMMENT '角色描述',  
  27.       `category` varchar(40) NOT NULL DEFAULT '' COMMENT '分类',  
  28.       PRIMARY KEY (`id`)  
  29.     ) ENGINE=InnoDB AUTO_INCREMENT=60 DEFAULT CHARSET=utf8;  
  30.   
  31.     -- ----------------------------  
  32.     -- 加入4个操作权限  
  33.     -- ----------------------------  
  34.     INSERT INTO `t_role` VALUES ('1''ROLE_ADMIN''系统管理员''系统管理员');  
  35.     INSERT INTO `t_role` VALUES ('2''ROLE_UPDATE_FILM''修改''影片管理');  
  36.     INSERT INTO `t_role` VALUES ('3''ROLE_DELETE_FILM''删除''影片管理');  
  37.     INSERT INTO `t_role` VALUES ('4''ROLE_ADD_FILM''添加''影片管理');  
  38.   
  39.     -- ----------------------------  
  40.     -- 创建权限组表  
  41.     -- ----------------------------  
  42.     CREATE TABLE `t_group` (  
  43.       `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,  
  44.       `groupname` varchar(50) NOT NULL DEFAULT '',  
  45.       PRIMARY KEY (`id`)  
  46.     ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;  
  47.   
  48.     -- ----------------------------  
  49.     -- 添加2个权限组  
  50.     -- ----------------------------  
  51.     INSERT INTO `t_group` VALUES ('1''Administrator');  
  52.     INSERT INTO `t_group` VALUES ('2''影片维护');  
  53.   
  54.     -- ----------------------------  
  55.     -- 创建权限组对应权限表t_group_role  
  56.     -- ----------------------------  
  57.     CREATE TABLE `t_group_role` (  
  58.       `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,  
  59.       `groupid` bigint(20) unsigned NOT NULL,  
  60.       `roleid` bigint(20) unsigned NOT NULL,  
  61.       PRIMARY KEY (`id`),  
  62.       UNIQUE KEY `groupid2` (`groupid`,`roleid`),  
  63.       KEY `roleid` (`roleid`),  
  64.       CONSTRAINT `t_group_role_ibfk_1` FOREIGN KEY (`groupid`) REFERENCES `t_group` (`id`),  
  65.       CONSTRAINT `t_group_role_ibfk_2` FOREIGN KEY (`roleid`) REFERENCES `t_role` (`id`)  
  66.     ) ENGINE=InnoDB AUTO_INCREMENT=83 DEFAULT CHARSET=utf8;  
  67.   
  68.     -- ----------------------------  
  69.     -- 加入权限组与权限的对应关系  
  70.     -- ----------------------------  
  71.     INSERT INTO `t_group_role` VALUES ('1''1''1');  
  72.     INSERT INTO `t_group_role` VALUES ('2''2''2');  
  73.     INSERT INTO `t_group_role` VALUES ('4''2''4');  
  74.   
  75.     -- ----------------------------  
  76.     -- 创建管理员所属权限组表t_group_user  
  77.     -- ----------------------------  
  78.     CREATE TABLE `t_group_user` (  
  79.       `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,  
  80.       `userid` bigint(20) unsigned NOT NULL,  
  81.       `groupid` bigint(20) unsigned NOT NULL,  
  82.       PRIMARY KEY (`id`),  
  83.       KEY `userid` (`userid`),  
  84.       KEY `groupid` (`groupid`),  
  85.       CONSTRAINT `t_group_user_ibfk_2` FOREIGN KEY (`groupid`) REFERENCES `t_group` (`id`),  
  86.       CONSTRAINT `t_group_user_ibfk_3` FOREIGN KEY (`userid`) REFERENCES `t_admin` (`id`)  
  87.     ) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;  
  88.   
  89.     -- ----------------------------  
  90.     -- 将管理员加入权限组  
  91.     -- ----------------------------  
  92.     INSERT INTO `t_group_user` VALUES ('1''1''1');  
  93.     INSERT INTO `t_group_user` VALUES ('2''4''2');  
  94.   
  95.     -- ----------------------------  
  96.     -- 创建管理员对应权限表t_user_role  
  97.     -- 设置该表可跳过权限组,为管理员直接分配权限  
  98.     -- ----------------------------  
  99.     CREATE TABLE `t_user_role` (  
  100.       `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,  
  101.       `userid` bigint(20) unsigned NOT NULL,  
  102.       `roleid` bigint(20) unsigned NOT NULL,  
  103.       PRIMARY KEY (`id`),  
  104.       KEY `userid` (`userid`),  
  105.       KEY `roleid` (`roleid`),  
  106.       CONSTRAINT `t_user_role_ibfk_1` FOREIGN KEY (`userid`) REFERENCES `t_admin` (`id`),  
  107.       CONSTRAINT `t_user_role_ibfk_2` FOREIGN KEY (`roleid`) REFERENCES `t_role` (`id`)  
  108.     ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;  
  109.       

 

3.2)在项目中新增如下jar包(security框架所需jar包):

 

    注意:以下jar包本文已提供下载

 

spring-security-config-3.1.0.RC2.jar

spring-security-core-3.1.0.RC2.jar

spring-security-taglibs-3.1.0.RC2.jar

spring-security-web-3.1.0.RC2.jar

 

3.3)创建如下包,放置登录验证过滤器代码:

 

com.xxx.security

安全框架Spring Security是什么?如何理解Spring Security的权限管理?

MySQL安全配置向导mysql_secure_installation详解

MySQL安全配置向导mysql_secure_installation详解

Spring Security权限管理

Spring Security 权限管理

Spring Security 权限管理