Spring Security环境搭建
- Spring Boot
- Spring Security 
  - 认证:判断用户是否是用户合法用户的过程
- 授权:判断系统用户可以访问或访问哪些权限资源
 
环境搭建
创建springBoot项目并导入springsecurity相关的依赖。
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
spring-boot-starter-security:启动器
加入启动器之后默认对所有的请求进行管理,进入默认的登录页面进行认证。-----默认所有请求默认都需要认证进行访问
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0bzxoI3g-1682589063841)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20230422201819563.png)]](https://img-blog.csdnimg.cn/31756bafa1f54a6d8c38f6cffb738ab1.png)
认证方法:账号:user 密码:控制台
实现原理
思考
为什么引 Spring Security 之后 没有任何配置所有请求就要认证呢?
在项目中明明没有登录界面,登录界面 怎么来的呢?
为什么使用 user 和 控制台密码 能登陆,登录时验证数据源存在哪里呢?
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A68t5FY7-1682589063842)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20230422202926780.png)]](https://img-blog.csdnimg.cn/423dc5c30748438a942648a3a24c2a80.png)
DelegatingFilterProxy:代理
SecurityFilterChain:可以管理多个filter即filterChain(过滤器链)可以是一组也可以是多组
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wvznd145-1682589063843)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20230422203716476.png)]](https://img-blog.csdnimg.cn/7ad976786603421d9bbbc03cd5113040.png)
需要注意的是,默认过滤器并不是直接放在Web项目的原生过滤器链中,而是通过一个FilterChainProxy 来统一管理。SpringSecurity中的过滤器链通过 FilterChainProxy嵌入到Web项目的原生过滤器链中。FilterChainProxy 作为一个顶层的管理者,将统一管理 Security Filter。FilterChainProxy 本身是通过 Spring 框架提供的DelegatingFilterProxy 整合到原生的过滤器链中。
Security Filters
| 过滤器 | 过滤器作⽤ | 默认是否 加载 | 
|---|---|---|
| ChannelProcessingFilter | 过滤请求协议 HTTP 、 HTTPS | NO | 
| WebAsyncManagerIntegrationFilter | 将 WebAsyncManger 与 SpringSecurity 上下⽂进 ⾏集成 | YES | 
| SecurityContextPersistenceFilter | 在处理请求之前,将安全信息加载到 SecurityContextHolder 中 | YES | 
| HeaderWriterFilter | 处理头信息加⼊响应中 | YES | 
| CorsFilter | 处理跨域问题 | NO | 
| CsrfFilter | 处理 CSRF 攻击 | YES | 
| LogoutFilter | 处理注销登录 | YES | 
| OAuth2AuthorizationRequestRedirectFilter | 处理 OAuth2 认证重定向 | NO | 
| Saml2WebSsoAuthenticationRequestFilter | 处理 SAML 认证 | NO | 
| X509AuthenticationFilter | 处理 X509 认证 | NO | 
| AbstractPreAuthenticatedProcessingFilter | 处理预认证问题 | NO | 
| CasAuthenticationFilter | 处理 CAS 单点登录 | NO | 
| OAuth2LoginAuthenticationFilter | 处理 OAuth2 认证 | NO | 
| Saml2WebSsoAuthenticationFilter | 处理 SAML 认证 | NO | 
| UsernamePasswordAuthenticationFilter | 处理表单登录 | YES | 
| OpenIDAuthenticationFilter | 处理 OpenID 认证 | NO | 
| DefaultLoginPageGeneratingFilter | 配置默认登录⻚⾯ | YES | 
| DefaultLogoutPageGeneratingFilter | 配置默认注销⻚⾯ | YES | 
| ConcurrentSessionFilter | 处理 Session 有效期 | NO | 
| DigestAuthenticationFilter | 处理 HTTP 摘要认证 | NO | 
| BearerTokenAuthenticationFilter | 处理 OAuth2 认证的 Access Token | NO | 
| BasicAuthenticationFilter | 处理 HttpBasic 登录 | YES | 
| RequestCacheAwareFilter | 处理请求缓存 | YES | 
| SecurityContextHolderAwareRequestFilter | 包装原始请求 | YES | 
| JaasApiIntegrationFilter | 处理 JAAS 认证 | NO | 
| RememberMeAuthenticationFilter | 处理 RememberMe 登录 | NO | 
| AnonymousAuthenticationFilter | 配置匿名认证 | YES | 
| OAuth2AuthorizationCodeGrantFilter | 处理OAuth2认证中授权码 | NO | 
| SessionManagementFilter | 处理 session 并发问题 | YES | 
| ExceptionTranslationFilter | 处理认证/授权中的异常 | YES | 
| FilterSecurityInterceptor | 处理授权相关 | YES | 
| SwitchUserFilter | 处理账户切换 | NO | 
表格中给定的顺序就是过滤器加载的顺序
可以看出,Spring Security提供了30多个过滤器。默认情况下Spring Boot 在对Spring Security 进入自动化配置时,会创建一个名为 SpringSecurityFilerChairy的过滤器,并注入到Spring 容器中,这个过滤器将负责所有的安全管理,包括用户认证、授权、重定向到登录页面等。具体可以参考WebSecurityConfiguration的源码:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6Vf0qGTw-1682589063844)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20230422205709604.png)]](https://img-blog.csdnimg.cn/5346ac675c3446d18cb7c8db04b8f175.png)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l9ThDUMv-1682589063844)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20230422210346502.png)]](https://img-blog.csdnimg.cn/20b118dad5374c56907768e8a4397873.png)
自动配置分析
SpringBootWebSecurityConfiguration
这个类是 spring boot ⾃动配置类,通过这个源码得知,默认情况下对所有请求进⾏权限
 控制:
@Configuration(proxyBeanMethods = false)
@ConditionalOnDefaultWebSecurity
@ConditionalOnWebApplication(type = Type.SERVLET)
class SpringBootWebSecurityConfiguration {
@Bean
@Order(SecurityProperties.BASIC_AUTH_ORDER)
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity
http)
throws Exception {
http.authorizeRequests().anyRequest() //开启任何请求的权限认证
.authenticated().and().formLogin().and().httpBasic();
return http.build();
}
}
WebSecurityConfigurerAdapter
protected void configure(HttpSecurity http) throws Exception {
        this.logger.debug("Using default configure(HttpSecurity). If subclassed this will potentially override subclass configure(HttpSecurity).");
        http.authorizeRequests((requests) -> {
            ((AuthorizedUrl)requests.anyRequest()).authenticated();
        });
        http.formLogin();
        http.httpBasic();
    }
-  -条件⼀ classpath中存在 SecurityFilterChain.class, 
 HttpSecurity.class
-  条件⼆ 没有⾃定义 WebSecurityConfigurerAdapter.class, 
 SecurityFilterChain.class
默认情况下,条件都是满⾜的。 WebSecurityConfigurerAdapter 这个类极其重要,
 Spring Security 核⼼配置都在这个类中:
 如果要对 Spring Security 进⾏⾃定义配置,就要⾃定义这个类实例,通过覆盖类中⽅
 法达到修改默认配置的⽬的
默认登录页面
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ojiIGhYa-1682589063845)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20230427173807321.png)]](https://img-blog.csdnimg.cn/14b457b8ccff450db2e413c133ca6ce6.png)
\1. 请求 /hello 接⼝,在引⼊ spring security 之后会先经过⼀些列过滤器
 \2. 在请求到达 FilterSecurityInterceptor时,发现请求并未认证。请求拦截下来,
 并抛出 AccessDeniedException 异常。
 \3. 抛出 AccessDeniedException 的异常会被 ExceptionTranslationFilter 捕
 获,这个 Filter 中会调⽤ LoginUrlAuthenticationEntryPoint#commence
 ⽅法给客户端返回 302,要求客户端进⾏重定向到 /login ⻚⾯。
 \4. 客户端发送 /login 请求。
 \5. /login 请求会再次被拦截器中 DefaultLoginPageGeneratingFilter 拦截到,
 并在拦截器中返回⽣成登录⻚⾯。



















