hello云胜

技术与生活

0%

权限控制设计

流程图

一站式权限流程

说明

  1. 对iam的token的解析问题。

    此处有2种方案

    1.本地解析jwt,目前看iam的token是jwt

    2.远程调用iam接口解析

框架

JWT

spring-security

数据库表设计

  • ums_admin:后台用户表。基于IDM工号,不需要了。
  • ums_role:后台用户角色表
  • ums_admin_role_relation:工号和角色对应关系
  • ums_menu:菜单表。控制前台侧边来菜单显示
  • ums_role_memu_relation。角色和菜单对应关系

页面&api接口

  1. 根据工号获取菜单列表
  2. 创建角色
  3. 配置工号角色关系
  4. 配置菜单
  5. 配置角色菜单对应关系

拦截器

通过对请求进行拦截,解析jwt,获取权限信息,组装security-context

1
2
3
4
5
6
7
8
9
public class AuthenticationInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception {
// 获取paas-token
// 解析token,得到工号
// 查询权限信息
// 组装security-context
}
}

后台接口

后台接口开启基于角色的权限控制

  • 实现UserDetailService,获取用户角色和权限列表

  • 启用Spring Security开启注解@EnableWebSecurity

  • 开启注解 @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)

    @PreAuthorize, @PostAuthorize, @Secured这三个注解可以使用了

  • @Secured:专门判断用户是否具有角色,可以写在方法或类上,参数以 ROLE_ 开头

    1
    2
    3
    4
    5
    @GetMapping("/helloUser")
    @Secured({"ROLE_normal","ROLE_admin"}) //拥有normal或者admin角色的用户都可以方法helloUser()方法
    public String helloUser() {
    return "hello,user";
    }

​ 如果我们要求,只有同时拥有admin & noremal的用户才能方法helloUser()方法,这时候@Secured就无能为力了

  • @PreAuthorize更适合方法级的安全,也支持Spring 表达式语言,提供了基于表达式的访问控制

    PreAuthorize 访问的类或方法执行前判断权限。PostAuthorize 在执行之后,基本不用。

1
2
3
4
5
6
@GetMapping("/helloUser")
@PreAuthorize("hasAnyRole('normal','admin')")
// 拥有normal或者admin角色的用户都可以方法helloUser()方法。
public String helloUser() {
return "hello,user";
}
1
2
3
4
5
6
@GetMapping("/helloUser")
@PreAuthorize("hasRole('normal') AND hasRole('admin')")
// 用户必须同时拥有normal和admin的角色
public String helloUser() {
return "hello,user";
}

除了hasRole判断角色,还可用hasAuthority类别判断权限信息。

  • @RolesAllowed。还有一个@RolesAllowed注解。用法和@Secured很像。区别是@Secured是spring-security的注解,而@RolesAllowed是JSR的标准注解,不止在spring中可用。