Spring Security是一个强大且高度可定制的身份验证和访问控制框架。天然与Spring整合,易扩展,引入jar包就可以用了,在boot自动装载下,不需要任何配置就可以控制资源访问。那么默认登录页是如何生产的呢?
版本信息
内容 | 版本 |
---|---|
JDK | 17 |
spring-boot-starter-web | 3.2.2 |
spring-boot-starter-security | 3.2.2 |
spring-security | 6.2.1 |
项目搭建步骤
-
访问 https://start.spring.io/ 自动生成项目
-
添加依赖 Spring Web、Spring Security
-
生成项目, 点击 GENERATE,会下载一个压缩包
-
添加 controller 代码
package com.example.security.controller;import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class HelloController {@GetMapping(value = "/hello")public String hello() {return "Hello Security";}
}
- 启动项目, 访问 http://localhost:8080/hello,会重定向到登录页面
为啥为重定向到登录页面?登录页面如何生成的?
源码解析
- 先找一下 spring-boot-test-autoconfigure jar 包,找到文件org.springframework.boot.autoconfigure.AutoConfiguration.imports,检索 security, 发现有如下类
过滤器链是通过 SecurityAutoConfiguration 导入的类SpringBootWebSecurityConfiguration 配置的 org.springframework.boot.autoconfigure.security.servlet.SpringBootWebSecurityConfiguration.WebSecurityEnablerConfiguration
打印出默认过滤器链
2024-02-01T23:19:18.288+08:00 INFO 15696 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@748ac6f3, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@68f6e55d, org.springframework.security.web.context.SecurityContextHolderFilter@3238e2aa, org.springframework.security.web.header.HeaderWriterFilter@71adfedd, org.springframework.web.filter.CorsFilter@6fff46bf, org.springframework.security.web.csrf.CsrfFilter@5f36c8e3, org.springframework.security.web.authentication.logout.LogoutFilter@217bf99e, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@67022ea, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@38b3f208, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@1835dc92, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@7ec95456, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@2577a95d, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@1668919e, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@3aaa3c39, org.springframework.security.web.access.ExceptionTranslationFilter@17e9bc9e, org.springframework.security.web.access.intercept.AuthorizationFilter@7327a447]
/*** Adds the {@link EnableWebSecurity @EnableWebSecurity} annotation if Spring Security* is on the classpath. This will make sure that the annotation is present with* default security auto-configuration and also if the user adds custom security and* forgets to add the annotation. If {@link EnableWebSecurity @EnableWebSecurity} has* already been added or if a bean with name* {@value BeanIds#SPRING_SECURITY_FILTER_CHAIN} has been configured by the user, this* will back-off.*/@Configuration(proxyBeanMethods = false)@ConditionalOnMissingBean(name = BeanIds.SPRING_SECURITY_FILTER_CHAIN)@ConditionalOnClass(EnableWebSecurity.class)@EnableWebSecuritystatic class WebSecurityEnablerConfiguration {}
核心的注解类 org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
org.springframework.security.config.annotation.web.builders.WebSecurity#performBuild
在类org.springframework.security.web.FilterChainProxy.VirtualFilterChain#doFilter 加一个断点, 看每个过滤器做了啥
经过调试,发现默认页面在 org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter 这个类生成的,方法 generateLoginPageHtml