跳至主要內容

SessionManagementFilter

Jin大约 5 分钟

SessionManagementFilter

1、概述

SessionManagementFilter 主要用于管理和控制与用户会话相关的安全策略。它的核心职责是确保会话的管理符合安全要求,比如防止会话固定攻击(Session Fixation)以及对会话的并发访问进行限制。

2、作用

SessionManagementFilter 主要用于:

  • 会话固定攻击防护:在用户登录后,确保会话 ID 不会被攻击者利用(比如通过恶意链接获得)。
  • 并发会话控制:限制每个用户的并发会话数,防止用户在多个设备或浏览器中同时登录。
  • 会话超时处理:配置会话的有效期,控制用户的会话过期时间。

3、工作流程

SessionManagementFilter 的工作流程可以分为以下几个步骤:

3.1、Session Fixation Protection

  • 会话固定攻击是指攻击者通过操控用户的会话 ID 来冒充用户登录。攻击者可能在用户登录之前就将会话 ID 设为已知的某个值,从而在用户登录后接管会话。
  • 为了防止这种攻击,SessionManagementFilter 默认启用了会话固定攻击保护。它会在用户认证成功后,强制改变会话 ID,确保用户的会话 ID 在认证后不可预测。
  • 默认情况下,Spring Security 使用 SessionFixationProtectionStrategy 作为防护策略,常见的做法是执行会话重定向(例如,通过 HttpServletRequest.changeSessionId() 来改变会话 ID)。

3.2、Session Timeout Management

  • 会话超时是指当用户长时间未活动时,Spring Security 会终止用户会话。
  • SessionManagementFilter 可以根据配置的会话过期时间,自动检测并管理会话的生命周期。当会话过期时,用户的会话会被销毁,用户将被迫重新认证。
  • 配置 sessionTimeout 可以通过 HttpSecurity 配置,例如设置会话的最大空闲时间。
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .sessionManagement()
                .invalidSessionUrl("/session-invalid") // 会话失效后重定向的 URL
                .maximumSessions(1)  // 限制并发会话数
                .maxSessionsPreventsLogin(true);  // 如果达到最大会话数,禁止登录新会话
    }
}

SpringSecurity6.x

package com.example.security;

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.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.InMemoryUserDetailsManager;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public UserDetailsService userDetailsService() {
        return new InMemoryUserDetailsManager(
                User.withUsername("user")
                    .password("{noop}password")
                    .roles("USER")
                    .build()
        );
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()
            .and()
            .formLogin()
            .and()
            .sessionManagement()
                .maximumSessions(1)  // 限制同一时间只有一个会话
                .maxSessionsPreventsLogin(true);  // 达到最大会话数时阻止登录

        return http.build();
    }
}

3.3、Concurrent Session Control

  • 通过 SessionManagementFilter,可以配置并发会话控制,例如限制同一用户在多个地方的登录数量。
  • 配置 maximumSessions 可以指定同一个用户最多允许多少个并发会话。比如,如果你不希望一个用户在多个设备上同时登录,可以通过 maximumSessions(1) 来限制每个用户最多只能有一个会话。
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .sessionManagement()
                .maximumSessions(1)  // 限制并发会话数为 1
                .maxSessionsPreventsLogin(true);  // 如果达到最大会话数,则禁止新会话登录
    }
}
  • maximumSessions:设置最大允许并发会话数。
  • maxSessionsPreventsLogin:如果该参数为 true,则在达到最大会话数时,新的会话无法登录。如果为 false,则新会话会被创建,旧会话会被踢出。

3.4、Session Invalidity Handling

  • 当会话无效时(例如会话超时或手动注销时),SessionManagementFilter 会重定向用户到配置的 invalidSessionUrl 或执行适当的会话失效处理。
  • 你可以通过 invalidSessionUrl("/session-invalid") 配置一个 URL,当会话失效时,用户会被重定向到这个 URL。
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .sessionManagement()
                .invalidSessionUrl("/session-invalid");  // 会话失效后跳转到该 URL
    }
}

4、配置

SessionManagementFilter 的配置通常通过 HttpSecuritysessionManagement() 方法进行。常见的配置选项包括:

  • invalidSessionUrl():设置会话无效时的跳转 URL。
  • maximumSessions():设置并发会话数限制。
  • maxSessionsPreventsLogin():配置达到最大会话数时的行为。
  • sessionFixation():设置会话固定攻击的保护策略。常见的值包括:
    • SessionFixationProtectionStrategy:通过改变会话 ID 防止会话固定攻击(默认策略)。
    • newSession():创建新的会话 ID,防止攻击者利用固定会话 ID。
    • none():不进行会话固定保护。

4.1、配置示例

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
   
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .sessionManagement()
                .invalidSessionUrl("/session-invalid")  // 会话失效后的跳转 URL
                .maximumSessions(1)  // 限制并发会话数为 1
                .maxSessionsPreventsLogin(true)  // 达到最大会话数时禁止新会话登录
                .sessionFixation().newSession()  // 使用新会话防止会话固定攻击
                .and()
            .authorizeRequests()
                .antMatchers("/login", "/register").permitAll()
                .anyRequest().authenticated();
    }
}

4.2、SpringSecurity 6.x 并发会话控制

package com.example.security;

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.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.InMemoryUserDetailsManager;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public UserDetailsService userDetailsService() {
        return new InMemoryUserDetailsManager(
                User.withUsername("user")
                    .password("{noop}password")
                    .roles("USER")
                    .build()
        );
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()
            .and()
            .formLogin()
            .and()
            .sessionManagement()
                .maximumSessions(1)  // 限制同一时间只有一个会话
                .maxSessionsPreventsLogin(true);  // 达到最大会话数时阻止登录

        return http.build();
    }
}

4.2、SpringSecurity 6.x 会话超时控制

package com.example.security;

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.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.InMemoryUserDetailsManager;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public UserDetailsService userDetailsService() {
        return new InMemoryUserDetailsManager(
                User.withUsername("user")
                    .password("{noop}password")
                    .roles("USER")
                    .build()
        );
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()
            .and()
            .formLogin()
            .and()
            .sessionManagement()
                .invalidSessionUrl("/session-invalid")  // 会话失效后跳转的 URL
                .sessionFixation().newSession()  // 会话固定攻击防护
                .maximumSessions(1)  // 限制并发会话数
                .maxSessionsPreventsLogin(true)  // 达到最大会话数时禁止登录新会话
                .and()
            .and()
            .httpBasic();  // 启用 HTTP 基本认证

        return http.build();
    }
}

5、核心类和接口

  1. SessionManagementFilter:核心过滤器,负责管理会话的生命周期,包括会话固定攻击保护、会话超时、并发会话控制等。
  2. SessionFixationProtectionStrategy:默认的会话固定攻击保护策略,负责在认证后更换会话 ID。
  3. ConcurrentSessionControlStrategy:用于控制并发会话数的策略。
  4. InvalidSessionStrategy:当会话无效时执行的策略,通常是重定向到指定的 URL。
  5. SessionAuthenticationStrategy:处理用户会话的策略,用于确保用户会话的一致性和安全性。

总结

  • SessionManagementFilter 是 Spring Security 中负责会话管理的核心过滤器,提供了防止会话固定攻击、并发会话控制和会话超时等功能。
  • 通过 HttpSecurity 配置,你可以细粒度地控制会话的行为,确保用户会话的安全性。
  • 主要功能包括会话 ID 更换、并发会话数限制、会话失效处理等。
  • 对于需要加强会话管理的应用,SessionManagementFilter 提供了多种防护机制,能够有效提升系统的安全性。
贡献者: Jin