ps:硅谷老师的笔记(代码背景白色)
SpringSecurity 基本流程
上:对应教程视频:36-尚硅谷-SpringSecurity-源码剖析-认证流程详解上_哔哩哔哩_bilibili
绿色部分是认证过滤器,需要我们自己配置,可以配置多个认证过滤器。认证过滤器可以使用 Spring Security 提供的认证过滤器,也可以自定义过滤器(例如:短信验证)。认证过滤器要在 **configure(HttpSecurity http)**方法中配置,没有配置不生效。下面会重点介绍以下三个过滤器:
UsernamePasswordAuthenticationFilter 过滤器:该过滤器会拦截前端提交的 POST 方式的登录表单请求,并进行身份认证。
ExceptionTranslationFilter 过滤器:该过滤器不需要我们配置,对于前端提交的请求会直接放行,捕获后续抛出的异常并进行处理(例如:权限访问限制)。
FilterSecurityInterceptor 过滤器:该过滤器是过滤器链的最后一个过滤器,根据资源权限配置来判断当前请求是否有权限访问对应的资源。如果访问受限会抛出相关异常,并由 ExceptionTranslationFilter 过滤器进行捕获和处理。
SpringSecurity 认证流程(源码剖析)
前端的post请求都会被UsernamePasswordAuthenticationFilter这个过滤器给拦截,并进行身份的认证
(1) 到父类AbstractAuthenticationProcessingFilter
第一步:过滤的方法doFilter,判断提交方式是否post提交
第二步:调用子类UsernamePasswordAuthenticationFilter的attemptAuthentication方法进行身份认证,认证成功之后,把认证信息封装到Authentication对象里面
Authentication用于封装认证信息的类对象
在post提交表单之后,得到表单提交过来的数据,然后这里调用子类里的attemptAuthentication方法去查数据库和进行验证,认证之后,那认证通过后的信息用Authentication进行封装
第三步:session策略处理
第四步:
1、认证失败抛出异常,执行认证失败的方法
认证成功后会进行封装,但认证失败会,会在catch里面调用unsuccessfulAuthentication方法,做认证失败处理,比如提示用户你没有权限
ps:网友的笔记(代码背景白色)
2、认证成功后,调用认证成功后的方法
ps:上面第二步:调用子类UsernamePasswordAuthenticationFilter的attemptAuthentication方法去查数据库和进行验证的源码剖析:
attemptAuthentication中的
第一步:判断前端是否是post提交
第二步:获取前端表单提交数据
第三步:
使用获取数据,构造成对象(UsernamePasswordAuthenticationToken),标记为未认证的状态
把请求一些属性信息设置到该对象里面( this.setDetails(request, authRequest); )
调用authenticate方法进行身份认证(调用我们自己编写的userDetailsService里面的方法进行查数据过程或认证过程)
(3)查看 UsernamePasswordAuthenticationToken 的构建过程
下:对应教程视频:37-尚硅谷-SpringSecurity-源码剖析-认证流程详解下_哔哩哔哩_bilibili
(4)查看ProviderManager源码,认证实现
上述过程中,UsernamePasswordAuthenticationFilter 过滤器的attemptAuthentication() 方法的身份认证过程将未认证的 Authentication 对象传入ProviderManager 类的 authenticate() 方法进行身份认证。
ProviderManager 是 AuthenticationManager 接口的实现类,该接口是认证相关的核心接口,也是认证的入口。在实际开发中,我们可能有多种不同的认证方式,例如:用户名+密码、邮箱+密码、手机号+验证码等,而这些认证方式的入口始终只有一个,那就是AuthenticationManager。在该接口的常用实现类 ProviderManager 内部会维护一个**List**列表,存放多种认证方式,实际上这是委托者模式(Delegate)的应用。每种认证方式对应着一个 AuthenticationProvider,AuthenticationManager 根据认证方式的不同(根据传入的 Authentication 类型判断)委托对应的 AuthenticationProvider 进行用户认证。
上述认证成功之后的(6)过程,调用 CredentialsContainer 接口定义的eraseCredentials() 方法去除敏感信息。查看
UsernamePasswordAuthenticationToken 实现的 eraseCredentials() 方法,该方法实现在其父类中:
上述过程就是认证流程的最核心部分,接下来重新回到
UsernamePasswordAuthenticationFilter 过滤器的 doFilter() 方法,查看认证成功/失败的处理:
查看successfulAuthentication() 和 unsuccessfulAuthentication() 方法源码:
———————————————————————————————————————————————————————————————————————