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代码
- SET FOREIGN_KEY_CHECKS=0;
- ------------------------------
- -- 创建管理员帐号表t_admin
- -- ----------------------------
- CREATE TABLE `t_admin` (
- `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
- `passwd` varchar(12) NOT NULL DEFAULT '' COMMENT '用户密码',
- `nickname` varchar(20) NOT NULL DEFAULT '' COMMENT '用户名字',
- `phoneno` varchar(32) NOT NULL DEFAULT '' COMMENT '电话号码',
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
- -- ----------------------------
- -- 添加3个管理帐号
- -- ----------------------------
- INSERT INTO `t_admin` VALUES ('1', 'admin', 'admin', '');
- INSERT INTO `t_admin` VALUES ('4', '123456', 'test', '');
- INSERT INTO `t_admin` VALUES ('5', '111111', '111111', '');
- -- ----------------------------
- -- 创建权限表t_role
- -- ----------------------------
- CREATE TABLE `t_role` (
- `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
- `role` varchar(40) NOT NULL DEFAULT '',
- `descpt` varchar(40) NOT NULL DEFAULT '' COMMENT '角色描述',
- `category` varchar(40) NOT NULL DEFAULT '' COMMENT '分类',
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=60 DEFAULT CHARSET=utf8;
- -- ----------------------------
- -- 加入4个操作权限
- -- ----------------------------
- INSERT INTO `t_role` VALUES ('1', 'ROLE_ADMIN', '系统管理员', '系统管理员');
- INSERT INTO `t_role` VALUES ('2', 'ROLE_UPDATE_FILM', '修改', '影片管理');
- INSERT INTO `t_role` VALUES ('3', 'ROLE_DELETE_FILM', '删除', '影片管理');
- INSERT INTO `t_role` VALUES ('4', 'ROLE_ADD_FILM', '添加', '影片管理');
- -- ----------------------------
- -- 创建权限组表
- -- ----------------------------
- CREATE TABLE `t_group` (
- `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
- `groupname` varchar(50) NOT NULL DEFAULT '',
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
- -- ----------------------------
- -- 添加2个权限组
- -- ----------------------------
- INSERT INTO `t_group` VALUES ('1', 'Administrator');
- INSERT INTO `t_group` VALUES ('2', '影片维护');
- -- ----------------------------
- -- 创建权限组对应权限表t_group_role
- -- ----------------------------
- CREATE TABLE `t_group_role` (
- `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
- `groupid` bigint(20) unsigned NOT NULL,
- `roleid` bigint(20) unsigned NOT NULL,
- PRIMARY KEY (`id`),
- UNIQUE KEY `groupid2` (`groupid`,`roleid`),
- KEY `roleid` (`roleid`),
- CONSTRAINT `t_group_role_ibfk_1` FOREIGN KEY (`groupid`) REFERENCES `t_group` (`id`),
- CONSTRAINT `t_group_role_ibfk_2` FOREIGN KEY (`roleid`) REFERENCES `t_role` (`id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=83 DEFAULT CHARSET=utf8;
- -- ----------------------------
- -- 加入权限组与权限的对应关系
- -- ----------------------------
- INSERT INTO `t_group_role` VALUES ('1', '1', '1');
- INSERT INTO `t_group_role` VALUES ('2', '2', '2');
- INSERT INTO `t_group_role` VALUES ('4', '2', '4');
- -- ----------------------------
- -- 创建管理员所属权限组表t_group_user
- -- ----------------------------
- CREATE TABLE `t_group_user` (
- `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
- `userid` bigint(20) unsigned NOT NULL,
- `groupid` bigint(20) unsigned NOT NULL,
- PRIMARY KEY (`id`),
- KEY `userid` (`userid`),
- KEY `groupid` (`groupid`),
- CONSTRAINT `t_group_user_ibfk_2` FOREIGN KEY (`groupid`) REFERENCES `t_group` (`id`),
- CONSTRAINT `t_group_user_ibfk_3` FOREIGN KEY (`userid`) REFERENCES `t_admin` (`id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;
- -- ----------------------------
- -- 将管理员加入权限组
- -- ----------------------------
- INSERT INTO `t_group_user` VALUES ('1', '1', '1');
- INSERT INTO `t_group_user` VALUES ('2', '4', '2');
- -- ----------------------------
- -- 创建管理员对应权限表t_user_role
- -- 设置该表可跳过权限组,为管理员直接分配权限
- -- ----------------------------
- CREATE TABLE `t_user_role` (
- `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
- `userid` bigint(20) unsigned NOT NULL,
- `roleid` bigint(20) unsigned NOT NULL,
- PRIMARY KEY (`id`),
- KEY `userid` (`userid`),
- KEY `roleid` (`roleid`),
- CONSTRAINT `t_user_role_ibfk_1` FOREIGN KEY (`userid`) REFERENCES `t_admin` (`id`),
- CONSTRAINT `t_user_role_ibfk_2` FOREIGN KEY (`roleid`) REFERENCES `t_role` (`id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
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详解