一 、认证
UsernamePasswordAuthenticationFilter.attemptAuthentication(req, res) 用户的参数拦截最终实现者
UserDetailsService .loadUserByUsername(String username) 系统用户信息的最终实现者
上述两class分别为认证过程中一个用户的信息拦截,一个从系统中拿用户。
SimpleUrlAuthenticationSuccessHandler.onAuthenticationSuccess(req, res)
AuthenticationFailureHandler.onAuthenticationFailure(req, res)
上述两class分别为认证成功和失败后的跳转过程。
所以如果想自定义,继承他们,重写相关方法,然后在xml里面做下配置即可。
配置如下:
[crayon-584d49a2984ea900042627/] [crayon-584d49a2984f5773134295/]二、授权
仍然根据Spring Security实现权限的原理,我们可知在授权中起重要class为:AbstractSecurityInterceptor.doFilter(req, res): 拦截url并走到授权的filter
根据其类中的成员变量,可知还有:
authenticationManager(默认实现是UserDetailService),见认证第二部分代码,这里是提供系统用户信息。
securityMetadataSource (默认实现是FilterInvocationSecurityMetadataSource),提供url的角色
accessDecisionManager(默认实现是AccessDecisionManager.decide),对上两个类中用户角色和url角色进行比对,如果角色符合,则向下走,否则抛出AccessDeniedException
配置如下:
[crayon-584d49a2984fc203251749/]所以这就很明显了,当系统有自定义需求时,(如我们的用户信息不能直接配置在xml里面,也有可能没有数据源,只有接口的时候,我们就需要重继承authenticationManager类[有文章写ss4的第四种用法为重改这些class,我强烈建议继承之]),需要实现这三个class(authenticationManager我们已经在认证实现)
说下一般自定义场景
自定义认证
继承UsernamePasswordAuthenticationFilter的意义
可以看这个类的属性可知,当我们获取request里面的用户,密码不是username,password时(Spring Security默认是这两个),我们可以自定义之
当我们有密码加密,需要在之后做校验时,我们也需要在这里进行对密码进行加密。
本文http://www.paymoon.com:8001/index.php/2016/12/07/spring-security-4-principle-some-important-class/ 如果转载请联系i@paymoon.com继承authenticationManager的意义
刚刚也说过,如我们的用户信息不能直接配置在xml里面,也有可能没有数据源,只有接口的时候,我们就需要重继承authenticationManager类
继承认证通过的跳转类
SimpleUrlAuthenticationSuccessHandler.onAuthenticationSuccess(req, res)
AuthenticationFailureHandler.onAuthenticationFailure(req, res)
目的在于我们login后,可能不想返回到某个jsp,或者此jsp我们根本不在本项目中,或根本不在一个机器中,我们只能返回统一的标准json接口,这时候就要用这两个class重写跳转,方便我们返回接口,跳转时可能还会涉及到跨域,到实战会讲。
自定义授权
继承AbstractSecurityInterceptor
有人会想这就是一个filter, 我继承它干嘛呢,其实我们看到Spring Security实现的多细致多深,可是别忘了,SS4只能做到URL的控制粒度,如果我们想做数据粒度的控制,比如leader可以看到整个team的数据,当前team player只能看到他自己的数据,我们怎么做呢,我们需要自己写实现,在url的授权通过后,走我们自己的实现,这时候继承这个filter就非常重要了。
继承authenticationManager,这个就不用再说了,用户信息和角色,btw一般在比对角色的时候,都会从redis里面拿数据
继承securityMetadataSource,这个是url的角色,当我们要汇全当前url所有角色时,还有可能是我们的角色有自己的继承关系,如admin是manager的上级,我们需要继承这个,写自己的实现,以方便拿到所有的角色。
继承AccessDecisionManager,这个类的存在意义就不用再多说,比对角色是否符合就在这里决定,符合向后走[有可能就会走到我们刚说的数据权限],不符合throw exception,
[crayon-584d49a298505470128246/] 其实这是一个总的比较类,在Spring Security里面,对于角色匹配,还有投票机制,即如果全部通过投票,则有权访问,也有一票决定权,不过因为那种细的粒度一般难以遇到,所以这里先不表。