本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看 活动链接
之前在动态权限控制的教程中,我们通过自定义FilterInvocationSecurityMetadataSource
和AccessDecisionManager
两个接口实现了动态权限控制。这里需要我们做的事情比较多,有一定的学习成本。今天来介绍一种更加简单和容易理解的方法实现动态权限控制。
基于表达式的访问控制
1 | java复制代码httpSecurity.authorizeRequests() |
这种方式不用多说了吧,我们配置了表达式hasRole('admin')
后,Spring Security会调用SecurityExpressionRoot
的hasRole(String role)
方法来判断当前用户是否持有角色admin
,进而作出是否放行的决策。这种方式除了可以静态的权限控制之外还能够动态的权限控制。
基于Bean的访问控制表达式
Spring Security扩展了对表达式进行了扩展,支持引用任何公开的Spring Bean,假如我们有一个实现下列接口的Spring Bean:
1 | java复制代码/** |
基于JDBC的角色检查,最好这里做个缓存:
1 | java复制代码/** |
我们就可以这样配置HttpSecurity
:
1 | java复制代码httpSecurity.authorizeRequests() |
通过RoleChecker
中的Authentication
我们可以获得当前用户的信息,尤其是权限集。通过HttpServletRequest
我们可以获得当前请求的URI。该URI在系统中的权限集和用户的权限集进行交集判断就能作出正确的访问决策。
路径参数
有些时候我们的访问URI中还包含了路径参数,例如/foo/{id}
。我们也可以通过基于Bean的访问控制表达式结合具体的id
值来控制。这时应该这么写:
1 | java复制代码/** |
对应的配置为:
1 | java复制代码httpSecurity.authorizeRequests() |
这样当/foo/123
请求被拦截后,123
就会赋值给check
方法中的id
处理。
总结
这种表达式的动态权限控制比之前的方式更加容易掌握和理解。但是它也有它的局限性,比如表达式中的方法中的参数类型比较单一。而通过FilterInvocationSecurityMetadataSource
的方式则更加强大可以自定义一些访问决策,适合更加复杂的场景。我是:码农小胖哥,多多关注,分享更多原创编程干货。
本文转载自: 掘金