spring Security工作原理总括
对于请求的拦截使用的技术一般采用Filter或者AOP的技术,spring Security就是采用的Filter进行拦截。
当初始化spring Security时,会创建一个名为SpringSecurityFilterChain的Servlet过滤器,
类型为org.springframework.security.web.FilterChainProxy,他实现了javax.servlet.Filter,因此外部的请求会进过此类。
spring Security过滤器链的结果大致为:
FilterChainProxy ----->FIlter1----->FIlter2----->FIlter...----->system resource
其中认证的FIlter调用的是AuthenticationManger干活
其中授权的FIlter调用的是accessDesionManager干活
首先请求过来后传入到第一个Filter,为SecurityContextPersistenceFilter,接着会到判断用户身份的Filter,为
UsernamePasswordAuthencationFIlter,来校验用户身份,当然这会委托AuthenticationManager来校验。
然后再传入其他Filter进行处理。
SecurityContextPersistenceFIlter是整个过滤器链的第一个Filter(入出口)主要做一些上下文的初始化工作,
授权的Filter由FilterSecurityInterceptor来做,当然这是委托AccessDesionManager来做。
如果抛出异常,则由ExceptionTransationFilter来进行处理。
================================================================================
认证流程(大致)
首先用户提交用户名密码后,将封装用户密码的请求会发送到UsernamePasswordAuthenticationFilter中,然后
调用authenticate()交给认证器AuthenticationManager来进行处理,AuthenticationManager也不是最终干活的,
他会调用authenticate()方法交给DaoAutnenticationProvider来最终干活,DaoAutnenticationProvider通过调用
loadUserByUsername()方法访问UserDetailsServer服务获取用户信息,返回的UserDetails对象,包含了数据库中的用户信息。
DaoAutnenticationProvider拿到了用户信息后,会调用以前讲过的PasswordEncoder对比UserDetails中的密码是否一致,
认证通过会将用户信息填充到Authentication中并且返回到UsernamePasswordAuthenticationFilter,
UsernamePasswordAuthenticationFilter通过SecurityContextHolder.getcontext().setAuthentication()将Authentication
的认证信息保存到上下文中。认证就结束了。其中的UsernamePasswordAuthenticationFilter,
DaoAutnenticationProvider等组件都是可以自定义的,但是一般不需要改这些类。但是有一点可以改UserDetailsServer服务,
通过查数据库等方式来获取用户信息。
创建一个service包,在下面作如下
@service
public class SpringDataUserDetailService implements UserDetailsService{
@Override
public UserDetails loadUserByUsername(String s)throws UsernameNotFoundException{
//链接数据库 查询数据库
//模拟
UserDteails userDteails= User.withUsername("xxx").password("xxx").authorties("xxx").build();
return userDteails;
}
}
然后将原来SecurityConfig里面的UserDetailsService的配置Bean去掉。就可以执行这个自定义的方法了。
另外,SecurityConfig中的PasswordEncoder需要修改,建议采用BCriptPasswordEncoder来进行编码
好处是,每次编码的字符串不一样,安全性高,并且都可以验证通过。
================================================================================
授权流程(大致)
认证后的用户访问受保护的资源会进入到FilterSecurityInterceptor过滤器中,FilterSecurityInterceptor通过
SecurityMetaDataSource类的getAttribute()获取资源权限,并且返回权限集合Collection<ConfigAttribute>到
FilterSecurityInterceptor,FilterSecurityInterceptor再通过AccessDesionManage的deside()方法进行授权决策
判断,通过决策则允许访问资源,请求放行。
原文:https://www.cnblogs.com/dengw125792/p/12285530.html