Spring Security 深度学习(四): 会话管理与CSRF防护
目录
- 1. 引言:Session与Web安全
- 2. 会话管理 (Session Management)
- 2.1 理解HTTP Session
- 2.2 Spring Security会话策略
- 2.3 配置并发会话控制
- 2.4 会话固定攻击防护
- 2.5 “记住我” (Remember-Me) 功能
- 2.6 安全登出 (Logout)
- 3. CSRF (Cross-Site Request Forgery) 攻击与防护
- 3.1 什么是CSRF攻击?
- 3.2 CSRF攻击原理与危害
- 3.3 Spring Security的CSRF防护机制
- 3.4 CSRF Token的集成与使用
- 3.5 CSRF防护的定制与注意事项
- 4. 实战演练:配置会话管理与CSRF防护
- 4.1 延续第三阶段项目
- 4.2 配置并发会话
- 4.3 实现“记住我”功能
- 4.4 完善登出功能
- 4.5 确保CSRF防护生效
- 5. 常见陷阱与注意事项
- 6. 阶段总结与进阶展望
1. 引言:Session与Web安全
在Web应用中,HTTP协议是无状态的,这意味着服务器无法自动识别连续的请求是否来自同一个用户。为了在多个请求之间保持用户状态(例如登录状态、购物车内容等),我们通常使用会话 (Session) 机制。
然而,Session的引入也带来了新的安全挑战:
- Session劫持: 如果攻击者获得了一个合法用户的Session ID,他就可能冒充该用户。
- Session固定攻击: 攻击者试图为用户设置一个已知的Session ID,然后劫持该Session。
- CSRF攻击: 跨站请求伪造,是利用用户在已登录状态下的权限,诱骗用户(在不知情的情况下)发送恶意请求。
Spring Security提供了强大的工具来管理这些会话相关的安全问题。本阶段,我们将深入挖掘这些功能。
2. 会话管理 (Session Management)
Spring Security的会话管理功能主要通过http.sessionManagement()
进行配置。
2.1 理解HTTP Session
当用户首次访问Web应用时,服务器会创建一个唯一的Session,并生成一个Session ID(如JSESSIONID)。这个Session ID通常以Cookie的形式发送给浏览器,浏览器在后续请求中携带该Session ID,服务器从而识别出是同一个用户。Session信息存储在服务器端。
2.2 Spring Security会话策略
Spring Security允许你配置会话的创建和管理策略。通过sessionCreationPolicy()
方法,你可以指定:
ALWAYS
(默认): 始终创建HTTP Session。IF_REQUIRED
: 只有在需要时才创建HTTP Session(例如用户登录时)。NEVER
: Spring Security不会创建HTTP Session,但如果应用其他地方创建了,它会使用。STATELESS
: Spring Security将永远不会创建HTTP会话,也不会使用现有会话。此选项对于构建无状态REST API非常有用(通常与JWT或OAuth2结合使用),在这种情况下,每个请求都应包含自己的认证凭据,并且不依赖服务器端会话。
2.3 配置并发会话控制
在许多应用中,我们希望限制同一个用户不能在多个地方同时登录,或者在新的登录发生时强制旧的登录失效。这可以通过并发会话控制来实现。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.session.HttpSessionEventPublisher; // 需要导入这个类@Configuration
@EnableWebSecurity
public class CustomSecurityConfig {// ... 其他 Bean 定义,如 passwordEncoder, userDetailsService@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http// ... 之前的 authorizeHttpRequests, formLogin, logout ....sessionManagement(session -> session.maximumSessions(1) // 限制单个用户只能有一个会话// .maxSessionsPreventsLogin(true) // 当达到最大会话数时,新登录将被阻止.maxSessionsPreventsLogin(false) // 当达到最大会话数时,旧的会话失效.expiredUrl("/login?expired") // 会话过期后跳转的URL)// ... 其他配置.csrf(Customizer.withDefaults()); // 保持CSRF默认开启return http.build();}// 监听HttpSession事件,Spring Security需要这个Bean来管理会话的最大并发数@Beanpublic HttpSessionEventPublisher httpSessionEventPublisher() {return new HttpSessionEventPublisher();}
}
maximumSessions(1)
: 设置单个用户允许的最大并发会话数为1。maxSessionsPreventsLogin(true)
: 如果设置为true
,当达到最大会话数时,新的登录请求会被阻止。maxSessionsPreventsLogin(false)
: 如果设置为false
(推荐),当达到最大会话数时,最旧的会话将失效,允许新登录成功。expiredUrl("/login?expired")
: 当会话因并发登录失效或过期时,用户会被重定向到这个URL。HttpSessionEventPublisher
: 这个Bean是启用并发会话控制所必需的。它会发布Servlet容器的HttpSession
事件到Spring的ApplicationContext
,Spring Security通过监听这些事件来跟踪会话。
2.4 会话固定攻击防护
会话固定攻击 (Session Fixation Attack) 是一种攻击手段,攻击者尝试让用户使用攻击者预设的Session ID登录,从而在用户登录后劫持其会话。
Spring Security默认提供了会话固定攻击防护。当用户成功认证后,Spring Security会改变其Session ID。即使攻击者在用户登录前设法获取了Session ID,登录后该ID也会失效,从而阻止攻击。
Spring Security提供以下会话固定防护策略,通过sessionManagement().sessionFixation()
进行配置:
newSession()
(默认,Spring Security 5.x+): 创建一个新的Session,并将所有原Session的属性复制到新Session中。旧Session会被销毁。migrateSession()
(Spring Security 4.x 默认): 创建一个新Session,并复制原Session的属性,旧Session会被销毁。与newSession()
类似,但在某些Servlet容器中,newSession()
可能更彻底。changeSessionId()
(Servlet 3.1+ 默认,推荐): Spring Security会调用Servlet容器的HttpServletRequest.changeSessionId()
方法,直接改变当前Session的ID,而不会创建新的Session。这是最推荐、最有效且对Session数据影响最小的方式。none()
: 不做任何处理。不推荐在生产环境中使用。
在Spring Boot 3.x / Spring Security 6.x+ 中,changeSessionId()
通常是默认行为,你通常无需手动配置,除非你有特殊需求。
2.5 “记住我” (Remember-Me) 功能
“记住我”功能允许用户在关闭浏览器后,无需再次输入凭证即可自动登录。这通过在客户端存储一个持久化的Token(通常在Cookie中)来实现。
Spring Security提供了两种实现方式:
- 简单基于哈希Token (不推荐): 在Cookie中存储用户名、密码过期时间和一个哈希值。安全性较低,因为如果Cookie被截获,攻击者可以轻易使用。
- 持久化Token (更安全,推荐): 在Cookie中存储一个随机生成的Token(
series
)和一个令牌(token
),并在数据库中持久化username
,series
,token
,last_used
等信息。每次使用remember-me
登录时,token
都会更新,从而避免了重放攻击。
我们将使用持久化Token方案。
A. 数据库表准备 (用于持久化Token)
CREATE TABLE `persistent_logins` (`username` VARCHAR(64) NOT NULL,`series` VARCHAR(64) NOT NULL PRIMARY KEY,`token` VARCHAR(64) NOT NULL,`last_used` TIMESTAMP NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用于Spring Security Remember-Me功能的持久化Token表';
B. 配置RememberMeServices
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl; // 导入
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository; // 导入
import org.springframework.security.web.session.HttpSessionEventPublisher; // 导入import javax.sql.DataSource; // 导入@Configuration
@EnableWebSecurity
public class CustomSecurityConfig {private final DataSource dataSource; // 注入数据源private final UserDetailsService userDetailsService; // 注入UserDetailsServiceprivate final PasswordEncoder passwordEncoder; // 注入PasswordEncoderpublic CustomSecurityConfig(DataSource dataSource, UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) {this.dataSource = dataSource;this.userDetailsService = userDetailsService;this.passwordEncoder = passwordEncoder;}// ... PasswordEncoder 的 Bean (已在前面阶段定义)// ... UserDetailsService 的 Bean (已在前面阶段定义)// Remember-Me 持久化Token仓库@Beanpublic PersistentTokenRepository persistentTokenRepository() {JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();tokenRepository.setDataSource(dataSource);// tokenRepository.setCreateTableOnStartup(true); // 首次运行时自动创建表,生产环境建议手动创建return tokenRepository;}@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authorize -> authorize// ... URL 权限配置.requestMatchers("/css/**", "/js/**", "/images/**", "/login", "/register", "/public/**").permitAll().requestMatchers("/admin/**").hasAnyAuthority("ROLE_ADMIN", "USER_MANAGE").requestMatchers("/user/**").hasAnyAuthority("ROLE_USER", "ROLE_ADMIN", "USER_VIEW").anyRequest().authenticated()).formLogin(form -> form.loginPage("/login").defaultSuccessUrl("/user/profile", true).permitAll()).logout(logout -> logout.logoutUrl("/logout").logoutSuccessUrl("/login?logout").invalidateHttpSession(true).deleteCookies("JSESSIONID", "remember-me") // 登出时删除remember-me cookie.permitAll()).rememberMe(remember -> remember // 配置Remember-Me功能.key("myUniqueSecretKey") // 安全密钥,用于签名remember-me token,生产环境务必复杂.tokenRepository(persistentTokenRepository()) // 使用持久化Token仓库.tokenValiditySeconds(86400 * 30) // token有效期,默认为14天,这里设为30天.userDetailsService(userDetailsService) // 提供UserDetailsService加载用户).sessionManagement(session -> session.maximumSessions(1).maxSessionsPreventsLogin(false).expiredUrl("/login?expired")).exceptionHandling(exception -> exception.accessDeniedPage("/access-denied")).csrf(Customizer.withDefaults());return http.build();}@Beanpublic HttpSessionEventPublisher httpSessionEventPublisher() {return new HttpSessionEventPublisher();}
}
@PersistenceTokenRepository
: 注入DataSource
来配置数据库。setCreateTableOnStartup(true)
可以在首次运行时自动创建persistent_logins
表(生产环境通常手动创建以避免权限问题)。rememberMe()
:key("myUniqueSecretKey")
:一个安全密钥,用于HMAC签名Remember-Me Token。这个密钥非常重要,必须是复杂且保密的。tokenRepository(persistentTokenRepository())
:指定使用持久化Token的方式。tokenValiditySeconds()
:设置Token的有效期。userDetailsService()
:提供Spring Security用来加载用户详情的UserDetailsService
。
logout().deleteCookies("JSESSIONID", "remember-me")
: 在登出时,确保清除remember-me
的Cookie,以彻底失效持久化登录。
在你的login.html
中,需要添加一个remember-me
的复选框:
<div><input type="checkbox" id="remember-me" name="remember-me" /><label for="remember-me">Remember me</label></div><!-- CSRF token ... -->
2.6 安全登出 (Logout)
登出功能是结束用户会话、清除认证信息的重要步骤。Spring Security提供了开箱即用的登出支持。
.logout(logout -> logout.logoutUrl("/logout") // 登出请求的URL,默认是 /logout.logoutSuccessUrl("/login?logout") // 登出成功后重定向的URL.invalidateHttpSession(true) // 登出时使HTTP Session失效.deleteCookies("JSESSIONID", "remember-me") // 登出时删除相关Cookie.permitAll() // 确保 /logout 路径可以被所有用户访问 (包括未认证用户或已认证用户))
重要:
logoutUrl()
:可以自定义登出URL。logoutSuccessUrl()
:登出成功后的跳转页面。invalidateHttpSession(true)
:这是非常重要的一步,它会销毁当前用户的HTTP Session。deleteCookies()
:清除与会话和Remember-Me相关的Cookie。permitAll()
:确保登出URL对所有用户都可访问,防止未认证用户无法登出(例如,Session过期后)。
3. CSRF (Cross-Site Request Forgery) 攻击与防护
3.1 什么是CSRF攻击?
CSRF (Cross-Site Request Forgery),即跨站请求伪造,是一种通过伪装来自受信任用户的请求,来利用受信任网站的弱点和用户对网站的信赖,最终达到攻击目的的攻击手法。
简而言之,攻击者诱骗你(在已登录某网站A的情况下)点击一个链接或访问一个页面(攻击者精心构造的页面),这个页面上的恶意代码会以你的名义向网站A发送请求,而网站A会误认为这是你本人发出的合法请求,从而执行恶意操作(如转账、修改密码、更改个人信息等)。
3.2 CSRF攻击原理与危害
攻击原理:
- 用户在网站A(例如银行网站)登录,并保持登录状态(Session Cookie保存在浏览器)。
- 攻击者诱骗用户访问攻击页面。
- 攻击页面包含一个自动提交的表单或JavaScript代码,向网站A发送一个请求,例如:
<form action="http://bank.com/transfer" method="POST"><input type="hidden" name="account" value="attacker_account_id" /><input type="hidden" name="amount" value="1000" /><input type="submit" value="Click me to win a prize!" /> <!-- 或自动提交 --> </form>
- 浏览器会携带网站A的Session Cookie自动发送这个请求。
- 网站A收到请求,发现Session Cookie有效,认为这是用户本人发出的请求,遂执行转账操作。
危害: CSRF攻击可能导致用户在不知情的情况下执行各种敏感操作,造成财产损失、隐私泄露或帐户被劫持。
3.3 Spring Security的CSRF防护机制
Spring Security默认开启了强大的CSRF防护。其核心思想是:“不同源的网站不应该发送带有我cookies的请求”。
它通过在每个(非GET)请求中引入一个CSRF Token来工作:
- Token生成: 当用户首次访问应用时,Spring Security会在服务器端生成一个唯一的、随机的CSRF Token,并将其存储在HTTP Session中。
- Token嵌入: 这个CSRF Token被发送给客户端,通常嵌入到HTML表单的隐藏字段中,或者作为HTTP响应头发送给JavaScript。
- Token回传: 当客户端发起一个修改操作的请求(POST, PUT, DELETE等)时,它必须将这个CSRF Token一并发送回服务器(通常在请求参数或请求头中)。
- Token验证: 服务器端Spring Security过滤器会拦截请求,比较请求中携带的Token与Session中存储的Token是否一致。
- 一致: 请求被认为是合法的。
- 不一致: 请求被认为是CSRF攻击,Spring Security会拒绝该请求。
因为攻击者无法从受害者浏览器获取这个服务器生成的随机CSRF Token,所以攻击者就无法伪造带有正确Token的请求。
3.4 CSRF Token的集成与使用
A. 对于传统Thymeleaf/JSP表单:
在表单中添加一个隐藏字段,Thymeleaf或JSP会自动填充。
<form th:action="@{/login}" method="post"><!-- ... 其他输入字段 ... --><input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" /><!-- ... -->
</form>
_csrf.parameterName
和_csrf.token
是Spring Security在SecurityContext
中提供的属性,Thymeleaf会自动解析。- 默认情况下,
parameterName
是_csrf
,token
是实际的CSRF值。
B. 对于JavaScript (AJAX) 请求:
如果你使用JavaScript(如Axios, Fetch API, jQuery AJAX)发送POST
, PUT
, DELETE
等请求,你需要手动将CSRF Token包含在请求中。
-
从HTML页面获取Token:
可以从一个隐藏的meta标签或者JavaScript变量中获取。<!-- 在HTML head中添加 --> <meta name="_csrf" th:content="${_csrf.token}"/> <meta name="_csrf_header" th:content="${_csrf.headerName}"/>
-
在JavaScript中发送Token:
const token = document.querySelector('meta[name="_csrf"]').content; const header = document.querySelector('meta[name="_csrf_header"]').content;// Axios 示例 axios.post('/api/some-action', { /* data */ }, {headers: {[header]: token // 'X-CSRF-TOKEN': 'your_token_value'} }) .then(response => console.log(response)) .catch(error => console.error(error));// jQuery AJAX 示例 $.ajax({type: 'POST',url: '/api/some-action',data: JSON.stringify({ /* data */ }),contentType: 'application/json',beforeSend: function(xhr) {xhr.setRequestHeader(header, token);},success: function(response) {console.log(response);},error: function(error) {console.error(error);} });
Spring Security默认希望CSRF Token放在请求头
X-CSRF-TOKEN
中。
3.5 CSRF防护的定制与注意事项
- 默认开启: Spring Security默认对所有非GET请求开启CSRF防护。
- 禁用CSRF (仅限特定场景): 对于纯粹的RESTful API,如果你的认证机制是无状态的(例如JWT Token),并且没有使用Session,那么客户端就不会存储Session Cookie,CSRF攻击也就无从谈起。在这种情况下,你可以考虑禁用CSRF防护:
警告: 禁用CSRF防护意味着你的应用更容易受到攻击。除非你对安全性模型有清晰的理解,并且有其他措施来防止CSRF,否则不建议禁用。http.csrf(csrf -> csrf.disable()); // 慎用!只有在确定不使用基于Session的认证时
- CSRF Token Repository: 默认情况下,CSRF Token存储在
HttpSessionCsrfTokenRepository
中。你也可以定制。例如,CookieCsrfTokenRepository
可以将Token存储在HTTP Only的Cookie中,方便前端使用(但会暴露到浏览器存储,有一定风险)。 - 安全最佳实践:
- 所有修改数据的
POST
、PUT
、DELETE
请求都应受CSRF保护。 GET
请求通常是幂等的,不应该执行修改操作,因此无需CSRF Token校验。- 始终在HTTPS下运行应用,以保护Cookie和CSRF Token在传输过程中的安全。
- 如果使用SPA(单页应用),需要前端配合获取并发送CSRF Token。
- 所有修改数据的
4. 实战演练:配置会话管理与CSRF防护
我们将继续在第三阶段的项目基础上进行改造和验证。
4.1 延续第三阶段项目
确保你的项目已包含第三阶段的所有配置:数据库连接、CustomUserDetailsService
、PasswordEncoder
、SecurityFilterChain
(包含URL和方法授权)、login.html
、register.html
以及测试Controller。
4.2 配置并发会话
在CustomSecurityConfig
中添加sessionManagement
和HttpSessionEventPublisher
的Bean。
// CustomSecurityConfig.java
// ... 省略 imports@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class CustomSecurityConfig {private final DataSource dataSource;private final UserDetailsService userDetailsService;private final PasswordEncoder passwordEncoder;public CustomSecurityConfig(DataSource dataSource, UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) {this.dataSource = dataSource;this.userDetailsService = userDetailsService;this.passwordEncoder = passwordEncoder;}@Beanpublic PasswordEncoder passwordEncoder() { /* ... */ return new BCryptPasswordEncoder(); }@Beanpublic UserDetailsService userDetailsService() { /* ... */ return new CustomUserDetailsService(sysUserMapper); } // 假设sysUserMapper已注入@Beanpublic PersistentTokenRepository persistentTokenRepository() { /* ... */ return tokenRepository; }@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authorize -> authorize// ... url authorize config).formLogin(form -> form.loginPage("/login").defaultSuccessUrl("/user/profile", true).permitAll()).logout(logout -> logout.logoutUrl("/logout").logoutSuccessUrl("/login?logout").invalidateHttpSession(true).deleteCookies("JSESSIONID", "remember-me") // 登出时删除remember-me cookie.permitAll()).rememberMe(remember -> remember.key("myUniqueSecretKey").tokenRepository(persistentTokenRepository()).tokenValiditySeconds(86400 * 30).userDetailsService(userDetailsService)).sessionManagement(session -> session // <<-- HERE: 配置会话管理.maximumSessions(1) // 限制单个用户只有一个会话.maxSessionsPreventsLogin(false) // 新登录使旧会话失效.expiredUrl("/login?expired") // 会话过期或被踢出后跳转).exceptionHandling(exception -> exception.accessDeniedPage("/access-denied")).csrf(Customizer.withDefaults());return http.build();}@Bean // <<-- HERE: 必须添加这个Bean来启用并发会话控制public HttpSessionEventPublisher httpSessionEventPublisher() {return new HttpSessionEventPublisher();}
}
4.3 实现“记住我”功能
在CustomSecurityConfig
中添加rememberMe()
的配置和PersistentTokenRepository
的Bean。同时,在login.html
中添加remember-me
复选框。
测试步骤:
- 启动应用。
- 访问
/login
,使用user/password
登录,并勾选“Remember me”。 - 登录成功后,关闭浏览器(但不要登出)。
- 重新打开浏览器,再次访问
/user/profile
。你应该会发现直接进入了用户页面,无需再次登录,说明“记住我”功能生效。 - 查看浏览器Cookie,应该能看到一个名为
remember-me
的Cookie。 - 再次访问
/logout
,观察remember-me
Cookie是否被清除。
4.4 完善登出功能
logout()
配置已经在CustomSecurityConfig
中详细设置。确保deleteCookies
包含了JSESSIONID
和remember-me
。
测试步骤:
- 登录一个用户。
- 访问
http://localhost:8080/logout
。 - 你应该被重定向到
/login?logout
页面。 - 尝试访问任何受保护资源,应该会被重定向到登录页。
- 检查浏览器Cookie,确认
JSESSIONID
(如果存在的话)和remember-me
Cookie已被删除。
4.5 确保CSRF防护生效
- 表单提交: 确保
login.html
和register.html
都包含了th:name="${_csrf.parameterName}" th:value="${_csrf.token}"
。 - 测试 CSRF 攻击:
- 运行应用,登录用户
user/password
。 - 打开Postman或类似的HTTP客户端。复制用户的Session Cookie(通常是
JSESSIONID
)。 - 尝试向
/api/products
发送一个POST
请求,携带复制的Session Cookie,但不携带CSRF Token。 - 你应该会收到Spring Security返回的
403 Forbidden
响应,提示CSRF token无效。这表明CSRF防护已生效。 - 现在,尝试从登录成功的页面获取CSRF Token(例如,查看源代码),并将其作为
X-CSRF-TOKEN
请求头或_csrf
请求参数发送到/api/products
的POST请求中。 - 请求应该成功,返回200 OK,表明带有正确CSRF Token的请求被允许。
- 运行应用,登录用户
5. 常见陷阱与注意事项
- 并发会话死循环: 如果
expiredUrl()
指向的页面也需要认证,会导致重定向死循环。确保/login?expired
,/login
和logout
是permitAll()
。 - Remember-Me密钥安全:
rememberMe().key()
中的密钥必须足够复杂且保密,泄露后会带来严重安全风险。生产环境应从安全配置中心获取。 - Remember-Me数据库表:
persistent_logins
表必须严格按照Spring Security的要求设计,字段名、长度、类型都不能错。 - CSRF与无状态API: 对于JWT或OAuth2等无状态认证的RESTful API,通常会禁用CSRF防护。但对于基于Session的Web应用,务必启用。
- CSRF Token获取: 在SPA应用中,前端需要通过特定的API(例如,自定义一个
/csrf
端点返回Token,或者从响应头中获取)来获取CSRF Token。 - Logout清除Cookie: 确保登出时清理所有相关的敏感Cookie,防止残留。
- HTTP Only Cookie: Session ID和Remember-Me Token的Cookie默认应该是HttpOnly的,防止JavaScript访问,降低XSS攻击风险。Spring Security和Servlet容器会默认设置。
- Always HTTPS: 会话管理和CSRF防护都应在HTTPS环境下运行,以防止中间人攻击窃取Session ID或CSRF Token。
6. 阶段总结与进阶展望
至此,你已经完成了Spring Security深度学习的第四阶段!你现在已经掌握了:
- 全面的会话管理: 包括并发会话控制、会话固定攻击防护、“记住我”功能和安全登出。
- 深入理解CSRF攻击: 知晓其原理、危害以及Spring Security的防护机制。
- 实战集成: 能够将上述功能整合到你的Spring Boot应用中。
你现在构建的Web应用已经具备了相当完善的认证、授权和会话/CSRF防护能力。这为你后续深入探索Spring Security的过滤器链、JWT、OAuth2等高级主题奠定了坚实的基础。
在下一阶段,我们将深入研究过滤器链与自定义过滤器。我们将揭开Spring Security内部过滤器链的神秘面纱,了解各个核心过滤器的职责,并学习如何创建和集成自定义安全过滤器,以实现更复杂的安全逻辑和个性化需求。这将让你对Spring Security的执行机制有更底层、更深入的理解。