现有配置如下:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/sayHello").hasRole("ADMIN")
.antMatchers("/say").hasAnyAuthority("user:read")
.antMatchers("/addUser").hasRole("ADMIN")
.anyRequest().authenticated()
.and().addFilterAt(customAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.exceptionHandling().accessDeniedHandler(customAccessDeniedHandler());
//.and().csrf().disable();
http.sessionManagement().maximumSessions(1).expiredUrl("/userLogin");
}
这这个配置中我们设置了
.antMatchers("/sayHello").hasRole("ADMIN")
.antMatchers("/say").hasAnyAuthority("user:read")
.antMatchers("/addUser").hasRole("ADMIN")
这三个访问位置需要的权限和角色
我们的UserDetailsService 中如下配置(现在还未把权限联系到数据库中)
@Override
public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {
User u=userService.findUserByName(name);
if (u==null){
throw new UsernameNotFoundException(null);
}
MyUserDetails MyUserDetails=new MyUserDetails(u,getGrantedAuthority(u));
return MyUserDetails;
}
public List<GrantedAuthority> getGrantedAuthority(User user){
List<GrantedAuthority> list = new ArrayList<>();
list.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
//权限
// list.add(new SimpleGrantedAuthority("user:read"));
return list;
}
我们默认再当前用户登录的时候(用户数据连接到了数据库),但是我们再这里只设置了当前用户角色为:RORE_ADMIN,此时每个登录成功的用户都拥有这个角色权限
测试我们写的几个handle
@GetMapping("/sayHello")
JsonResult sayHello()throws Exception{
return new JsonResult(ResultCode.SUCCESS,"hello world");
}
@GetMapping("/admin/say")
JsonResult sayAd()throws Exception{
return new JsonResult(ResultCode.SUCCESS,"admin");
}
@GetMapping("/say")
JsonResult say()throws Exception{
return new JsonResult(ResultCode.SUCCESS,"say");
}
@GetMapping("addUser")
JsonResult addUser()throws Exception{
return new JsonResult(ResultCode.SUCCESS,"addUser");
}
当我们访问sayHello、addUser的时候会正常访问,但是当我们访问say路径的时候会提示我们
因为再我们之前的配置中配置为
.antMatchers("/say").hasAnyAuthority("user:read")
而我们再上述赋权位置没有给user:read这个权限,所以没有权限访问
创建数据库角色权限表:
CREATE TABLE `Sys_Role`(
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(200) NOT NULL,
`description` VARCHAR(200) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
创建用户与角色对应表
CREATE TABLE `Sys_role_user`(
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` BIGINT UNSIGNED NOT NULL,
`sys_role_id` BIGINT UNSIGNED NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
再角色表新增角色如下
这里新增了一个管理员和销售部门管理员
调整权限位置:
.antMatchers("/sayHello").hasRole("ADMIN")
.antMatchers("/addUser").hasRole("SALE_ADMIN")
新增用户zhangsan id为2
分别设置admin和zhangsan的权限如下图
我们修改我们之前写死的权限加载为:
public List<GrantedAuthority> getGrantedAuthority(User user){
List<GrantedAuthority> list = new ArrayList<>();
List<String> roles=userService.findUserRoleByUserId(user.getId());
for (String role:roles){
list.add(new SimpleGrantedAuthority("ROLE_"+role));
}
//list.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
return list;
}
现在当前用户登录的时候动态通过findUserRoleByUserId方法去数据库加载该用户所有的角色,就完成了动态赋值角色的操作了
但是控制操作节点在角色上有点粗糙,比如同样是经理,我想赋值某个经理额外的操作特权的时候就很难搞了,这个时候我们再细化一下我们的系统,我们加入权限的概念,关系为:一个角色包含多个权限
创建权限表:
CREATE TABLE `Sys_permission`(
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(200) NOT NULL,
`description` VARCHAR(200) DEFAULT NULL,
`url` VARCHAR(200) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
新权限如下:
以及和角色的对应表:
CREATE TABLE `Sys_permission_role`(
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`role_id` BIGINT UNSIGNED NOT NULL,
`permission_id` BIGINT UNSIGNED NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
新增对应关系如下:
其中管理员拥有新增用户、删除用户、修改用户的权限,而销售管理员拥有 新增用户、修改用户的权限
新建权限类(前边的角色类偷懒没有创建实体类)
@Entity
@Data
public class Permission {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private String description;
private String url;
}
这样就可以达到用户-权限-角色的控制了