WebSessionSecurityContextRepository custom session attribute name
Fixes: gh-4843
This commit is contained in:
parent
b7529be3d0
commit
8d30d6110b
|
@ -16,26 +16,45 @@
|
|||
package org.springframework.security.web.server.context;
|
||||
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
*
|
||||
* Stores the {@link SecurityContext} in the
|
||||
* {@link org.springframework.web.server.WebSession}. When a {@link SecurityContext} is
|
||||
* saved, the session id is changed to prevent session fixation attacks.
|
||||
* @author Rob Winch
|
||||
* @since 5.0
|
||||
*/
|
||||
public class WebSessionServerSecurityContextRepository
|
||||
implements ServerSecurityContextRepository {
|
||||
final String SESSION_ATTR = "USER";
|
||||
|
||||
/**
|
||||
* The default session attribute name to save and load the {@link SecurityContext}
|
||||
*/
|
||||
public static final String DEFAULT_SPRING_SECURITY_CONTEXT_ATTR_NAME = "SPRING_SECURITY_CONTEXT";
|
||||
|
||||
private String springSecurityContextAttrName = DEFAULT_SPRING_SECURITY_CONTEXT_ATTR_NAME;
|
||||
|
||||
/**
|
||||
* Sets the session attribute name used to save and load the {@link SecurityContext}
|
||||
* @param springSecurityContextAttrName the session attribute name to use to save and
|
||||
* load the {@link SecurityContext}
|
||||
*/
|
||||
public void setSpringSecurityContextAttrName(String springSecurityContextAttrName) {
|
||||
Assert.hasText(springSecurityContextAttrName, "springSecurityContextAttrName cannot be null or empty");
|
||||
this.springSecurityContextAttrName = springSecurityContextAttrName;
|
||||
}
|
||||
|
||||
public Mono<Void> save(ServerWebExchange exchange, SecurityContext context) {
|
||||
return exchange.getSession()
|
||||
.doOnNext(session -> {
|
||||
if(context == null) {
|
||||
session.getAttributes().remove(SESSION_ATTR);
|
||||
session.getAttributes().remove(this.springSecurityContextAttrName);
|
||||
} else {
|
||||
session.getAttributes().put(SESSION_ATTR, context);
|
||||
session.getAttributes().put(this.springSecurityContextAttrName, context);
|
||||
}
|
||||
})
|
||||
.flatMap(session -> session.changeSessionId());
|
||||
|
@ -43,7 +62,7 @@ public class WebSessionServerSecurityContextRepository
|
|||
|
||||
public Mono<SecurityContext> load(ServerWebExchange exchange) {
|
||||
return exchange.getSession().flatMap( session -> {
|
||||
SecurityContext context = (SecurityContext) session.getAttributes().get(SESSION_ATTR);
|
||||
SecurityContext context = (SecurityContext) session.getAttributes().get(this.springSecurityContextAttrName);
|
||||
return context == null ? Mono.empty() : Mono.just(context);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -39,7 +39,23 @@ public class WebSessionServerSecurityContextRepositoryTests {
|
|||
@Test
|
||||
public void saveAndLoadWhenDefaultsThenFound() {
|
||||
SecurityContext expected = new SecurityContextImpl();
|
||||
this.repository.save(this.exchange, new SecurityContextImpl()).block();
|
||||
this.repository.save(this.exchange, expected).block();
|
||||
|
||||
SecurityContext actual = this.repository.load(this.exchange).block();
|
||||
|
||||
assertThat(actual).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveAndLoadWhenCustomAttributeThenFound() {
|
||||
String attrName = "attr";
|
||||
this.repository.setSpringSecurityContextAttrName(attrName);
|
||||
SecurityContext expected = new SecurityContextImpl();
|
||||
|
||||
this.repository.save(this.exchange, expected).block();
|
||||
|
||||
WebSession session = this.exchange.getSession().block();
|
||||
assertThat(session.<SecurityContext>getAttribute(attrName)).isEqualTo(expected);
|
||||
|
||||
SecurityContext actual = this.repository.load(this.exchange).block();
|
||||
|
||||
|
@ -49,7 +65,7 @@ public class WebSessionServerSecurityContextRepositoryTests {
|
|||
@Test
|
||||
public void saveAndLoadWhenNullThenDeletes() {
|
||||
SecurityContext context = new SecurityContextImpl();
|
||||
this.repository.save(this.exchange, new SecurityContextImpl()).block();
|
||||
this.repository.save(this.exchange, context).block();
|
||||
this.repository.save(this.exchange, null).block();
|
||||
|
||||
SecurityContext actual = this.repository.load(this.exchange).block();
|
||||
|
|
Loading…
Reference in New Issue