# springsecurity **Repository Path**: landashu/springsecurity ## Basic Information - **Project Name**: springsecurity - **Description**: 这是一个 springsecurity 的简单项目 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-08-18 - **Last Updated**: 2022-06-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 这是一个spring security的单项目 ## 流程如下 ![img.png](img/img.png) 1. 认证流程 UsernamePasswordAuthenticationFilter > 1. UsernamePasswordAuthenticationFilter 继承 AbstractAuthenticationProcessingFilter > 2. 实际会执行 AbstractAuthenticationProcessingFilter 的 doFilter 方法 > 3. 判断是否是 POST 提交,是则继续 > 4. 调用子类 UsernamePasswordAuthenticationFilter 实现的 attemptAuthentication 方法,该方法用于 得到表单的数据进行账号密码的认证或验证,并封装成 Authentication > 5. 进行session 的认证策略 > > this.sessionStrategy.onAuthentication(authenticationResult, request, response); > 6. 以上都成功会判断你是否还有成功之前的一些其他 filter,有则先继续其他的 filter,默认false,没有 > 7. 以上都成功则调用 successfulAuthentication > 8. 如果以上步骤发生异常会调用 unsucessfulAuthentication 2. 认证流程的第 4 步 attemptAuthentication 方法详解 > 1. UsernamePasswordAuthenticationFilter 详细描述了 attemptAuthentication 的实现流程,UsernamePasswordAuthenticationFilter 内部先描述了:\ > 定义了从 request 获取用户账号密码的关键字,默认 username,password \ > 定义了构造器,设置了默认的登录路径,AntPathRequestMatcher("/login","POST"); > 2. attemptAuthentication 先校验请求方式是否POST提交,不是则抛异常 > 3. 其次得到保单的用户名和密码,并去空校验 > 4. 把 账号和密码 封装到 UsernamePasswordAuthenticationToken > 5. 获取 AuthenticationManager 把 UsernamePasswordAuthenticationToken 封装成 Authentication a 3. 查看 UsernamePasswordAuthenticationToken 的构建过程,该方法就是标记,认证成功还是未认证成功,主要是 在构造器中设置 Authentication 接口的 setAuthenticated(true)方法,true代表认证成功。 4. AuthenticationManager 实现类为 ProviderManager,主要分析 authenticate 方法 > 1. 获取到 UsernamePasswordAuthenticationToken 的类型 > 2. 迭代 Providers 是否支持 UsernamePasswordAuthenticationToken 类型 > 3. 支持的话就调用 某个 Provider 的 authenticate 方法 > 4. Provider 的 authenticate 方法接收 UsernamePasswordAuthenticationToken,并从中得到 username 信息,然后从缓存中去 > 得到 UserDetails > 5. 如果缓存中没有,会调用 UserDetailsService 的 loadUserByUsername 中获取。 5. successfulAuthentication 方法详解 > 1. 认证成功后会把 Authentication 信息放到 SecurityContextHolder.getContext().setAuthentication(authResult); > 中 > 2. 其次调用 rememberMeServices 6. SecurityContextHolder.getContext().setAuthentication(authResult) 详解 > SecurityContext 对 Authentication进行封装 > SecurityContextHolder 使用 ThreadLocal 进行操作 7. SecurityContextPersistenceFilter 把你做的认证信息 和 session 绑定 > 1. 主要方法看 doFilter > 2. 从session中检查 SecurityContext 是否有这个对象,没有新建一个 SecurityContext 对象 > 3. 把 SecurityContext 放到 SecurityContextHolder中,然后执行其他过滤器 > 4. 在 SecurityContextHolder 取出 SecurityContext,在 SecurityContextHolder 移除 SecurityContext > 5. 再把 取出的 SecurityContext 放到 session 中