1.主要作用是 认证和授权
2.底层是过滤器链
3.导入 springSecurity 场景启动器后,spring启动,自动配置生效
1.SecurityFilterAutoConfiguration @bean Delegating FilterProxyRegistrationBean(注册了 DelegatingFilterproxy(filter)) 执行它的 doFilter() delegateTouse = this.initDelegate(webApplcaiitonContext) Filter delegate = wac.getBean(filterChainproxy,Filterclass) 创建 filterchainProxy实例并获得 delegate.init(this.getFilterconfig()) 执行filterchainproxy的 dofilter() filterchainproxy里面有个 list重要的三个过滤器里面有关于security的全部过滤器 filterchainProxy.doFilter() doFilterInternal() List filters = this.getFilters() 遍历List if(chain.matches(request)){ return chain.getFilters() }能匹配 request的 filter全部 返回 后将这些 filter全部 加到我们的 filterchain中 ====================================================== delegatingFilter 的 doFilter 就是获得 filterchain(里面包含那10几个 security的 filter) 注意,这个delegatingFilter的 doFilter是 在springboot容器启动就执行的,目的就是 将Filter全部加到 filterchain中,便于后面过滤请求
1.FilterSecurityInterceptor
是一个方法级的 权限过滤器,基本位于 过滤器的 最底部
1 dofilter() fi = new FilterInvocation() invoke(fi) 判断上一个 filter的 doFilter是否 执行了 chain.doFilter() 执行了 fi.getchain().doFilter() 它的doFilter的意思,就是判断上一个 filter的 chain.doFilter()是否执行 执行了,那么这个filter 直接 执行下一个filter 的 doFilter()
2.ExceptionTranslationFilter
是一个异常过滤器,用来处理在认证过程中抛出的异常
1. doFilter()
try{
chain.doFilter()
}catch(Exp e){
throw e;抛出异常
}
在下面过滤中,认证和授权,是在下面的过滤链中完成的,
只要下面的过滤出现了异常,那么在这一层捕捉
3.usernamePasswordAuthenticationFilter
对 /login 的 post请求 做拦截,检验表单的 用户名密码 是否
正确
1.dofilter()
authResult = attemptAuthentication(req,resp)'
if authResult = null return filterchain直接结束
else sessionStrategy.onAuthentication(authResult,req,resp)
2.所以,我们这里 关注 attemptAuthentication()即可
但是,这里的是默认的校验,我们需要 写一个 usernamePasswordAuthenticationFilter的 子类
并且 重写 attemptAuthentication()方法,完成自定义username,password校验
3.重写的 attempAuthentication()
1. 判断 是否是 post请求 不是 直接 return
2. 得到 request中的 username和 password
3. 注意:前端传过来的 参数名 必须是 username和 password
因为,我们这过滤器已经写死了
4.UserDetaliService接口实现类loadUserByUsername() 查询 datebase 中的 username和password
如果查询得到,那么封装成 User(Security提供的)返回
5.用passwordEncoder接口 将前端的password加密后,和user的 password作比较
如果相等,那么这个user就是正确的
两个重要接口
1.UserDetialsService接口 UserDetalis loadUserByUsername(String name) 在这个方法里面查用户,并判断调用 PasswordEncoder的matchs方法 判断密码是否正确,最后 return User(user) 2.PasswordEncoder接口 encode(password) 将密码加密 mathces(password)方法,将加密的方法,和 user的password作比较 相等,return true BCryptPasswordEncoder 是 Spring Security 官方推荐的密码解析器,平时多使用这个解析器。 重点:userDetailService的作用,就是返回 一个User,它的调用不用我们管 返回User后,再跟前端传来的做比较,这一步也不归我们管 同样PasswordEncode给前端 密码加密,也不归我们管,我们只用在 auth里面提供,userDetailService,和passwordEncode就行 3.就算我们不 重写 一个 usernamepasswordAuthenticationFilter 我们就写注册 一个 passwordEncoder的实现类,重写里面里面的方法 在默认的 filter中也会,调用 它的 encode方法,给密码加密 然后再比较web权限方案
1.用户授权
这三种方式本质都是在 auth里面设置用户名密码,角色
或者设置,userDetailService,PasswordEncoder,
真正 拿User 和 前端的 作比较…不用我们管
1.配置文件,修改默认username 和 password spring.security.user.name=username spring.security.user.password=password 这样默认用户名密码就改了,这样执行到 filter的时候,就会用 前端的用户名和密码 和 这个改了的 去比较 2.配置类 在springbootWebSecurityCOnfiguration中 默认支持 DefaultConfigurerAdapter 前提是在 缺少 WebSecurityConfigureAdapter的情况下 现在我们自己注册一个,WebSecurityConfigurerAdapter的实现类 就可以用我们自己的 重写 void configure(AuthenticationManagerBullder auth)方法 这个方法,可以设置我们的 默认用户名,密码,roles auth.inMemoryAuthentication().writerUser().password().roles(); 3.spring实现自动登入(浏览器关闭,也能自动登入)
技术点:cookie+springSecurity机制实现自动登入
注意:在登入页面添加 自动登入复选框,name必须是 remember-mc
我们只需要完成上述配置,其他的springSecurity帮我们做了
自动登入底层原理
若我们没有配置自动登入,没有数据库,那么不会走 RememberMeService的方法
下一次访问也不会走RememberMeAuthenticationFilter的方法(若方法成功,那么不会再继续认证,否则还是会 继续走UsernamePasswordAuthenticationFilter 认证)
或者说,走了但是,没有效果
1.添加复选框,我们勾选了,传了 remember-me,参数,代表可以走下面的 自动登入的流程了 2.在配置类中配置,PersisterTokenReposity组件,因为SpirngSecurity底层在



