Make max-session configurable

Closes gh-9202
This commit is contained in:
Mazen Aissa 2021-01-05 22:05:01 +01:00 committed by Josh Cummings
parent 6d59b1044a
commit c907838440
No known key found for this signature in database
GPG Key ID: 49EF60DD7FF83443
5 changed files with 51 additions and 4 deletions

View File

@ -387,7 +387,8 @@ class HttpConfigurationBuilder {
concurrentSessionStrategy = BeanDefinitionBuilder concurrentSessionStrategy = BeanDefinitionBuilder
.rootBeanDefinition(ConcurrentSessionControlAuthenticationStrategy.class); .rootBeanDefinition(ConcurrentSessionControlAuthenticationStrategy.class);
concurrentSessionStrategy.addConstructorArgValue(this.sessionRegistryRef); concurrentSessionStrategy.addConstructorArgValue(this.sessionRegistryRef);
String maxSessions = sessionCtrlElt.getAttribute("max-sessions"); String maxSessions = this.pc.getReaderContext().getEnvironment()
.resolvePlaceholders(sessionCtrlElt.getAttribute("max-sessions"));
if (StringUtils.hasText(maxSessions)) { if (StringUtils.hasText(maxSessions)) {
concurrentSessionStrategy.addPropertyValue("maximumSessions", maxSessions); concurrentSessionStrategy.addPropertyValue("maximumSessions", maxSessions);
} }

View File

@ -714,7 +714,7 @@ concurrency-control =
concurrency-control.attlist &= concurrency-control.attlist &=
## The maximum number of sessions a single authenticated user can have open at the same time. Defaults to "1". A negative value denotes unlimited sessions. ## The maximum number of sessions a single authenticated user can have open at the same time. Defaults to "1". A negative value denotes unlimited sessions.
attribute max-sessions {xsd:integer}? attribute max-sessions {xsd:token}?
concurrency-control.attlist &= concurrency-control.attlist &=
## The URL a user will be redirected to if they attempt to use a session which has been "expired" because they have logged in again. ## The URL a user will be redirected to if they attempt to use a session which has been "expired" because they have logged in again.
attribute expired-url {xsd:token}? attribute expired-url {xsd:token}?

View File

@ -2161,7 +2161,7 @@
</xs:attributeGroup> </xs:attributeGroup>
<xs:attributeGroup name="concurrency-control.attlist"> <xs:attributeGroup name="concurrency-control.attlist">
<xs:attribute name="max-sessions" type="xs:integer"> <xs:attribute name="max-sessions" type="xs:token">
<xs:annotation> <xs:annotation>
<xs:documentation>The maximum number of sessions a single authenticated user can have open at the same time. <xs:documentation>The maximum number of sessions a single authenticated user can have open at the same time.
Defaults to "1". A negative value denotes unlimited sessions. Defaults to "1". A negative value denotes unlimited sessions.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -79,6 +79,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* @author Rob Winch * @author Rob Winch
* @author Josh Cummings * @author Josh Cummings
* @author Onur Kagan Ozcan * @author Onur Kagan Ozcan
* @author Mazen Aissa
*/ */
public class SessionManagementConfigTests { public class SessionManagementConfigTests {
@ -356,6 +357,18 @@ public class SessionManagementConfigTests {
// @formatter:on // @formatter:on
} }
@Test
public void requestWhenMaxSessionsIsSetWithPlaceHolderThenErrorsWhenExceeded() throws Exception {
System.setProperty("sessionManagement.maxSessions", "1");
this.spring.configLocations(xml("ConcurrencyControlMaxSessionsPlaceHolder")).autowire();
// @formatter:off
this.mvc.perform(get("/auth").with(httpBasic("user", "password")))
.andExpect(status().isOk());
this.mvc.perform(get("/auth").with(httpBasic("user", "password")))
.andExpect(redirectedUrl("/max-exceeded"));
// @formatter:on
}
@Test @Test
public void autowireWhenSessionFixationProtectionIsNoneAndCsrfDisabledThenSessionManagementFilterIsNotWired() { public void autowireWhenSessionFixationProtectionIsNoneAndCsrfDisabledThenSessionManagementFilterIsNotWired() {
this.spring.configLocations(xml("NoSessionManagementFilter")).autowire(); this.spring.configLocations(xml("NoSessionManagementFilter")).autowire();

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- ~ Copyright 2002-2020 the original author or authors. ~ ~ Licensed under
the Apache License, Version 2.0 (the "License"); ~ you may not use this file
except in compliance with the License. ~ You may obtain a copy of the License
at ~ ~ https://www.apache.org/licenses/LICENSE-2.0 ~ ~ Unless required by
applicable law or agreed to in writing, software ~ distributed under the
License is distributed on an "AS IS" BASIS, ~ WITHOUT WARRANTIES OR CONDITIONS
OF ANY KIND, either express or implied. ~ See the License for the specific
language governing permissions and ~ limitations under the License. -->
<b:beans xmlns:b="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/security"
xsi:schemaLocation="
http://www.springframework.org/schema/security
https://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<http auto-config="true">
<session-management
session-authentication-error-url="/max-exceeded">
<concurrency-control
max-sessions="${sessionManagement.maxSessions}"
error-if-maximum-exceeded="true" />
</session-management>
</http>
<b:bean name="basicController"
class="org.springframework.security.config.http.SessionManagementConfigTests.BasicController"/>
<b:import resource="userservice.xml"/>
</b:beans>