springcurity权限控制系列教程:1⼊门
springcurity的执⾏过程,⽆⾮就是拦截器的执⾏流程,⽹上有很多资料可供学习。新⼿学习后实际去做权限控制时,感觉对springcurity的理解还是雾⾥看花,如何快速学透权限控制?看完
我这篇博客就⾏了。拦截器⾥⾯的实现需要⼀些组件来实现,在这些组件中有三个最重要接⼝or⽅法
1UrDetailsService处理⽤户和⽤户可以访问的url(可以在数据库中配置⽤户,⾓⾊)
2FilterInvocationSecurityMetadataSource
的⽅法来获取被拦截url所需的全部权限Role⾓⾊,
这个接⼝中要注意两个接⼝:RequestMatcher访问的url,ConfigAttribute访问的url需要的对应的Role⾓⾊)
3AccessDecisionManager投票器
三种策略,分别对应那个策略类:
只要有⼀个Voter不能完全通过权限要求,就禁⽌访问。
只要有⼀个Voter可以通过权限要求,就可以访问。
只要通过的Voter⽐禁⽌的Voter数⽬多就可以访问了。
主要流程:⽤户访问url,FilterInvocationSecurityMetadataSource的⽅法获取被拦截url所需的全部权限Role⾓⾊,把这些权限Role⾓⾊去和数据库中配置的所有权限Role⾓⾊⽐对(查询数据
库中配置的所有权限Role⾓⾊主要由接⼝UrDetailsService完成),如果"访问此url需要的权限Role⾓⾊"是"⽤户数据库中配置的权限Role⾓⾊"的⼦集,就允许访问。这个⽐对过程由
AccessDecisionManager去完成。
附:
1我上⾯使⽤的是⽤⾓⾊作为中转站,通过⽐较⾓⾊确定是否有权限。其实也可以⽤其他的模型作为中转站。
如把权限作为中转表:
/blog/2161648链接⾥也提到了两种⽅式的关联:1.5.1FilterSecurityInterceptor---FilterSecurityInterceptor是⽤于保护Http资源的,它需要⼀个AccessDecisionManager和⼀个AuthenticationManager的引⽤。
它会从SecurityContextHolder获取Authentication,然后通过SecurityMetadataSource(对应jaune161⾥FilterInvocationSecurityMetadataSource,是SecurityMetadataSource的实现类)可以得知当前请求是否在请求受保护
的资源。
elim⾥在UrnamePasswordAuthenticationFilter的henticationManager().authenticate(authRequest);代码⾥getAuthenticationManager()就是获得AuthenticationManager)
好了,有了我上⽂的铺垫,再看完那两篇⽂章,你再学习springcurity就很容易就学了。
-----看完后是不是更迷惑了---囧
⼩结:整个流程是什么样的呢?介绍三种⽅式:
⽅式1假设⽤户ur--->⾓⾊role1---->权限abcUrl。在UrDetailsService中去数据库中查询⽤户时,根据⽤户的⾓⾊查询对应的权限,
并把权限放在ur对象⾥。⽤户访问urlBcd时,在投票器中校验,这⾥要⾃⼰写个⾃定义投票器,投票器⾥逻辑这样写,根据request获得
⽤户请求的url:urlBcd,取出ur对象⾥⽤户所有权限,看是否包含urlBcd。发现⽤户只有⼀个权限abcUrl,没有urlBcd,拒绝访问。
⽅式2:假设⽤户ur--->⾓⾊role1---->权限abcUrl。在UrDetailsService中去数据库中查询⽤户时,根据⽤户的⾓⾊查询对应的权限,并把权限放
在ur对象⾥。在⽤户访问的controller的⽅法加上注解:PreAuthorize
@PreAuthorize("hasAuthority('query-demo')")
publicStringgetDemo(){
return"good";
}
⽤户不包含query-demo权限,拒绝访问。
⽅式3:见下图流程
注意这个表和前⾯两个有点不同,⽤户---⾓⾊---权限role_admin---资源url见。在UrDetailsService中去数据库中查询⽤户时,根据⽤
户的⾓⾊查询对应的权限,并把权限放在ur对象⾥。
:在投票器中鉴权处理。Authentication中是⽤户及⽤户权限信息,attributes是访问资源需要的权限,然后循环判断⽤户是否有访问资
源需要的权限,如果有就返回ACCESS_GRANTED,通俗的说就是有权限。
:查询⽤户权限role_xx,根据请求的资源url,根据数据库中配置资源url和权限role_xx的关系,去获取访问当前资源url需要哪些权限
role_xx
通过查询数据库获得资源与权限的对应列表RequestMap,。
具体的逻辑见getURLResourceMapping---->
loadResuorce()⾥key为resourcePath,vlue为权限,⼀个资源对应多个权限,则把所有权限⽤逗号拼接组成vlaue,如
map("resourcePath","aaa,bbb,c")--->
最后在bindRequestMap()⾥组合为Map
getAllConfigAttributes:获取所有权限集合
getAttributes:根据request请求获取访问资源所需权限
上⾯两个链接其实就是使⽤⾃定义的curityMetadataSource⾥的代码,在FilterInvocationSecurityMetadataSource实现类⾥重写。
⽅式3流程图
springcurity默认的提供了三种决策器,AffirmativeBad⼀票通过,只要有⼀个投票器通过就允许访问ConnsusBad有⼀半以上投票器通过才允许访问资源
UnanimousBad。决策器⾥再调⽤投票器去投票判断是否有权限,有⽆权限访问的最终觉得权是由投票器来决定的,最常见的投票器为RoleVoter。例如作者⽤的是投票器⾥鉴权。
禅师,决策器和投票器什么关系?⾮得调⽤投票器才能鉴权吗?当然不是,其实决策器就是判断⽤户有⽆权限,不去调⽤投票器去判断也可以,⾃⼰写逻辑判断也⾏。打个⽐⽅我们项⽬
⾥controller层会调⽤ip⼯具类去获取访问者的ip地址,⾮得调⽤ip⼯具类才可以获得ip地址吗,没必要,我不⽤ip⼯具类直接在controller中写个if判断获取ip地址也⾏。禅师,我懂了,你
的意思是说ip⼯具类抽出来有利于复⽤,修改,或者把ip⼯具类抽象成接⼝,然后开发地球ip,⽕星ip多个实现类,⽅便调⽤,虽然有这么多好处,但是我可以不⽤,我就是爱⾃⼰写,毕
竟葛⼤爷说过,有⼩孩这事我还是喜欢⾃⼒更⽣。。。禅师:⼤郎,注意看好莲莲。
作者写的⾃定义决策器⾥就不使⽤投票器,直接返回有⽆权限。
xml中:access-decision-manager-ref="accessDecisionManager"
然后类MyAccessDecisionManagerextendsAbstractAccessDecisionManager重写decide⽅法
还有点要注意,前⽂提到:去获取访问当前资源url需要哪些权限role_xx。容器启动时会操作⼀次,如果后来管理员重新授权,访问当前
url对应的需要的权限变了怎么办。即系统会在初始化时⼀次将所有资源加载到内存中,即使在数据库中修改了资源信息,系统也不会再次
去从数据库中读取资源信息。这就造成了每次修改完数据库后,都需要重启系统才能时资源配置⽣效。我们只要想办法在管理员修改数据
后,更新内存中数据map即可。
解决⽅案是,有⽹友提出1如果数据库中的资源出现的变化,需要刷新内存中已加载的资源信息时。
ApplicationContextctx=WebApplicationContextUtils.
getWebApplicationContext(sion().getServletContext());
xxSecurityMetadataSourcecs=(CustomInvocationSecurityMetadataSource)ctx.
getBean("xxxSecurityMetadataSource",);
sourceDefine();
loadResourceDefine()重新查数据库,资源url需要哪些权限role_xx。
2放资源的map⽤static。
这个解决的办法也⾏,就是多个管理员并发修改时会有点问题。我现在想的是⽤定时器做。
源码:对⽐xml和springboot配置⽅式
SpringSecurity
SpringSecurity是如何完成⾝份认证的?
1⽤户名和密码被过滤器获取到,封装成Authentication,通常情况下是UrnamePasswordAuthenticationToken这个实现类。
2AuthenticationManager⾝份管理器负责验证这个Authentication
3认证成功后,AuthenticationManager⾝份管理器返回⼀个被填充满了信息的(包括上⾯提到的权限信息,⾝份信息,细节信息,但密码通常
会被移除)Authentication实例。
4SecurityContextHolder安全上下⽂容器将第3步填充了信息的Authentication,通过text().tAuthentication(…)
⽅法,设置到其中。
本文发布于:2022-11-27 08:52:15,感谢您对本站的认可!
本文链接:http://www.wtabcd.cn/fanwen/fan/90/29996.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |