You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Security 3.1.x并发控制:ConcurrentSessionFilter配置疑问

Hey there! Since you're new to Spring Security, let me walk you through the key implementation points for setting up ConcurrentSessionFilter (as covered in the 3.1.x concurrency control chapter) clearly. This setup relies on a few core components working together, so I'll break it down step by step:

1. Core Components to Understand

First, let's recap the key pieces you'll need to make this work:

  • SessionRegistryImpl: The default implementation of SessionRegistry, which tracks all active user sessions in your application. It's the backbone for monitoring concurrent logins.
  • ConcurrentSessionFilter: The filter that checks if a user's session has expired (due to exceeding concurrent login limits) on every request, and redirects to your expiredUrl if so.
  • ConcurrentSessionControlStrategy: Handles concurrency rules during authentication (e.g., how many concurrent logins are allowed per user, what happens when the limit is hit).

2. Step-by-Step Configuration (XML, since 3.1.x relies heavily on it)

a. Define the SessionRegistry Bean

You need a single, shared instance of SessionRegistryImpl across your app—this ensures all session data is tracked in one place:

<bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />

b. Configure the ConcurrentSessionFilter

Inject the sessionRegistry and set your expiredUrl (the page users land on when their session is expired due to concurrency):

<bean id="concurrentSessionFilter" class="org.springframework.security.web.session.ConcurrentSessionFilter">
    <!-- Constructor args: first is the SessionRegistry, second is your expired page URL -->
    <constructor-arg ref="sessionRegistry" />
    <constructor-arg value="/session-expired" /> <!-- Replace with your actual expired page path -->
</bean>

c. Add the Filter to the Security Filter Chain

Filter order is critical here—use Spring's built-in position constant to ensure the filter is placed correctly in the chain:

<http auto-config="false" use-expressions="true">
    <!-- Your existing URL access rules -->
    <intercept-url pattern="/session-expired" access="permitAll" /> <!-- Ensure expired page is accessible anonymously -->
    <intercept-url pattern="/**" access="isAuthenticated()" />

    <!-- Insert ConcurrentSessionFilter into the chain at the correct position -->
    <custom-filter ref="concurrentSessionFilter" position="CONCURRENT_SESSION_FILTER" />

    <!-- Link session management to your concurrency control strategy -->
    <session-management session-authentication-strategy-ref="concurrentSessionControlStrategy" />
</http>

d. Set Up the ConcurrentSessionControlStrategy

This bean enforces your concurrency rules when a user logs in. Define how many concurrent sessions are allowed and what happens when the limit is exceeded:

<bean id="concurrentSessionControlStrategy" class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
    <constructor-arg ref="sessionRegistry" />
    <property name="maximumSessions" value="1" /> <!-- Allow only 1 concurrent login per user -->
    <property name="exceptionIfMaximumExceeded" value="true" /> <!-- Reject new login if limit is hit (instead of expiring old session) -->
</bean>

e. Add HttpSessionEventPublisher to web.xml

This listener ensures Spring Security is notified when sessions are destroyed (e.g., via timeout or logout), so the SessionRegistry stays updated with accurate session data:

<web-app>
    <!-- Other web.xml configuration -->
    <listener>
        <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
    </listener>
</web-app>

3. Critical Implementation Notes

  • Filter Order: Using position="CONCURRENT_SESSION_FILTER" guarantees the filter runs after SecurityContextPersistenceFilter (so it can access the current user's security context) and before authentication filters like UsernamePasswordAuthenticationFilter—this is the correct order for it to function as intended.
  • Anonymous Access for expiredUrl: Always configure your expiredUrl path to allow unauthenticated access (via access="permitAll"), otherwise users will hit an access denied error instead of your expired page.
  • Concurrency Rule Flexibility:
    • If you set exceptionIfMaximumExceeded="false", new logins will expire the oldest existing session for the user instead of being rejected.
    • Adjust maximumSessions to match your app's needs (e.g., 2 if you allow users to log in from two devices at once).
  • Single SessionRegistry Instance: Never create multiple SessionRegistryImpl beans—this will break session tracking, as each instance would maintain separate session data.

内容的提问来源于stack exchange,提问作者Abdu Manas C A

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:41:50