1
0
mirror of synced 2026-08-06 02:08:01 +00:00

Resource Server w/ SecurityReactorContextSubscriber

Fixes gh-7423
This commit is contained in:
Josh Cummings
2019-09-27 10:47:27 -06:00
parent e6d40e8280
commit 33ba292fed
5 changed files with 39 additions and 161 deletions
@@ -16,6 +16,8 @@
package org.springframework.security.oauth2.server.resource.web.reactive.function.client;
import java.util.Map;
import reactor.core.publisher.Mono;
import reactor.util.context.Context;
@@ -56,6 +58,9 @@ import org.springframework.web.reactive.function.client.ExchangeFunction;
public final class ServletBearerExchangeFilterFunction
implements ExchangeFilterFunction {
static final String SECURITY_REACTOR_CONTEXT_ATTRIBUTES_KEY =
"org.springframework.security.SECURITY_CONTEXT_ATTRIBUTES";
/**
* {@inheritDoc}
*/
@@ -76,8 +81,16 @@ public final class ServletBearerExchangeFilterFunction
}
private Mono<Authentication> currentAuthentication(Context ctx) {
Authentication authentication = ctx.getOrDefault(Authentication.class, null);
return Mono.justOrEmpty(authentication);
return Mono.justOrEmpty(getAttribute(ctx, Authentication.class));
}
private <T> T getAttribute(Context ctx, Class<T> clazz) {
// NOTE: SecurityReactorContextConfiguration.SecurityReactorContextSubscriber adds this key
if (!ctx.hasKey(SECURITY_REACTOR_CONTEXT_ATTRIBUTES_KEY)) {
return null;
}
Map<Class<T>, T> attributes = ctx.get(SECURITY_REACTOR_CONTEXT_ATTRIBUTES_KEY);
return attributes.get(clazz);
}
private ClientRequest bearer(ClientRequest request, AbstractOAuth2Token token) {
@@ -20,6 +20,7 @@ import java.net.URI;
import java.time.Duration;
import java.time.Instant;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
@@ -37,6 +38,7 @@ import org.springframework.web.reactive.function.client.ClientRequest;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.http.HttpMethod.GET;
import static org.springframework.security.oauth2.server.resource.web.reactive.function.client.ServletBearerExchangeFilterFunction.SECURITY_REACTOR_CONTEXT_ATTRIBUTES_KEY;
/**
* Tests for {@link ServletBearerExchangeFilterFunction}
@@ -80,7 +82,7 @@ public class ServletBearerExchangeFilterFunctionTests {
.build();
this.function.filter(request, this.exchange)
.subscriberContext(Context.of(Authentication.class, token))
.subscriberContext(context(token))
.block();
assertThat(this.exchange.getRequest().headers().getFirst(HttpHeaders.AUTHORIZATION))
@@ -93,7 +95,7 @@ public class ServletBearerExchangeFilterFunctionTests {
.build();
this.function.filter(request, this.exchange)
.subscriberContext(Context.of(Authentication.class, this.authentication))
.subscriberContext(context(this.authentication))
.block();
assertThat(this.exchange.getRequest().headers().getFirst(HttpHeaders.AUTHORIZATION))
@@ -107,10 +109,16 @@ public class ServletBearerExchangeFilterFunctionTests {
.build();
this.function.filter(request, this.exchange)
.subscriberContext(Context.of(Authentication.class, this.authentication))
.subscriberContext(context(this.authentication))
.block();
HttpHeaders headers = this.exchange.getRequest().headers();
assertThat(headers.get(HttpHeaders.AUTHORIZATION)).containsOnly("Bearer " + this.accessToken.getTokenValue());
}
private Context context(Authentication authentication) {
Map<Class<?>, Object> contextAttributes = new HashMap<>();
contextAttributes.put(Authentication.class, authentication);
return Context.of(SECURITY_REACTOR_CONTEXT_ATTRIBUTES_KEY, contextAttributes);
}
}