Skip to content

Enable customization of BearerTokenResolver by adding a setter for JwtClaimIssuerConverter on JwtIssuerAuthenticationManagerResolver #9168

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public final class JwtIssuerAuthenticationManagerResolver implements Authenticat

private final AuthenticationManagerResolver<String> issuerAuthenticationManagerResolver;

private final Converter<HttpServletRequest, String> issuerConverter = new JwtClaimIssuerConverter();
private Converter<HttpServletRequest, String> issuerConverter = new JwtClaimIssuerConverter();

/**
* Construct a {@link JwtIssuerAuthenticationManagerResolver} using the provided
Expand Down Expand Up @@ -130,9 +130,28 @@ public AuthenticationManager resolve(HttpServletRequest request) {
return authenticationManager;
}

/**
* Set a custom bearer token resolver
*
* @since 5.5
*/
public void setBearerTokenResolver(BearerTokenResolver bearerTokenResolver) {
Assert.notNull(bearerTokenResolver, "bearerTokenResolver cannot be null");
this.issuerConverter = new JwtClaimIssuerConverter(bearerTokenResolver);
}

private static class JwtClaimIssuerConverter implements Converter<HttpServletRequest, String> {

private final BearerTokenResolver resolver = new DefaultBearerTokenResolver();
private final BearerTokenResolver resolver;

JwtClaimIssuerConverter() {
this(new DefaultBearerTokenResolver());
}

JwtClaimIssuerConverter(BearerTokenResolver bearerTokenResolver) {
Assert.notNull(bearerTokenResolver, "bearerTokenResolver cannot be null");
this.resolver = bearerTokenResolver;
}

@Override
public String convert(@NonNull HttpServletRequest request) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public final class JwtIssuerReactiveAuthenticationManagerResolver

private final ReactiveAuthenticationManagerResolver<String> issuerAuthenticationManagerResolver;

private final Converter<ServerWebExchange, Mono<String>> issuerConverter = new JwtClaimIssuerConverter();
private Converter<ServerWebExchange, Mono<String>> issuerConverter = new JwtClaimIssuerConverter();

/**
* Construct a {@link JwtIssuerReactiveAuthenticationManagerResolver} using the
Expand Down Expand Up @@ -131,9 +131,31 @@ public Mono<ReactiveAuthenticationManager> resolve(ServerWebExchange exchange) {
// @formatter:on
}

/**
* Set a custom server bearer token authentication converter
*
* @since 5.5
*/
public void setServerBearerTokenAuthenticationConverter(
ServerBearerTokenAuthenticationConverter serverBearerTokenAuthenticationConverter) {
Assert.notNull(serverBearerTokenAuthenticationConverter,
"serverBearerTokenAuthenticationConverter cannot be null");
this.issuerConverter = new JwtClaimIssuerConverter(serverBearerTokenAuthenticationConverter);
}

private static class JwtClaimIssuerConverter implements Converter<ServerWebExchange, Mono<String>> {

private final ServerBearerTokenAuthenticationConverter converter = new ServerBearerTokenAuthenticationConverter();
private final ServerBearerTokenAuthenticationConverter converter;

JwtClaimIssuerConverter() {
this(new ServerBearerTokenAuthenticationConverter());
}

JwtClaimIssuerConverter(ServerBearerTokenAuthenticationConverter serverBearerTokenAuthenticationConverter) {
Assert.notNull(serverBearerTokenAuthenticationConverter,
"serverBearerTokenAuthenticationConverter cannot be null");
this.converter = serverBearerTokenAuthenticationConverter;
}

@Override
public Mono<String> convert(@NonNull ServerWebExchange exchange) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.JWSObject;
Expand All @@ -39,11 +41,15 @@
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.jose.TestKeys;
import org.springframework.security.oauth2.jwt.JwtClaimNames;
import org.springframework.security.oauth2.server.resource.web.BearerTokenResolver;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;

/**
* Tests for {@link JwtIssuerAuthenticationManagerResolver}
Expand Down Expand Up @@ -113,6 +119,19 @@ public void resolveWhenUsingCustomIssuerAuthenticationManagerResolverThenUses()
assertThat(authenticationManagerResolver.resolve(request)).isSameAs(authenticationManager);
}

@Test
public void resolveWhenUsingCustomIssuerAuthenticationManagerResolverAndCustomBearerTokenResolverThenUses() {
AuthenticationManager authenticationManager = mock(AuthenticationManager.class);
JwtIssuerAuthenticationManagerResolver authenticationManagerResolver = new JwtIssuerAuthenticationManagerResolver(
(issuer) -> authenticationManager);
BearerTokenResolver bearerTokenResolverSpy = spy(new TestBearerTokenResolver());
authenticationManagerResolver.setBearerTokenResolver(bearerTokenResolverSpy);
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader("Authorization", "Bearer " + this.jwt);
assertThat(authenticationManagerResolver.resolve(request)).isSameAs(authenticationManager);
verify(bearerTokenResolverSpy).resolve(any());
}

@Test
public void resolveWhenUsingExternalSourceThenRespondsToChanges() {
MockHttpServletRequest request = new MockHttpServletRequest();
Expand Down Expand Up @@ -196,4 +215,13 @@ private String jwt(String claim, String value) {
return jwt.serialize();
}

static class TestBearerTokenResolver implements BearerTokenResolver {

@Override
public String resolve(HttpServletRequest request) {
return "eyJhbGciOiJub25lIn0.eyJpc3MiOiJ0cnVzdGVkIn0.";
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,15 @@
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.jose.TestKeys;
import org.springframework.security.oauth2.jwt.JwtClaimNames;
import org.springframework.security.oauth2.server.resource.web.server.ServerBearerTokenAuthenticationConverter;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;

/**
* Tests for {@link JwtIssuerReactiveAuthenticationManagerResolver}
Expand Down Expand Up @@ -111,6 +115,20 @@ public void resolveWhenUsingCustomIssuerAuthenticationManagerResolverThenUses()
assertThat(authenticationManagerResolver.resolve(exchange).block()).isSameAs(authenticationManager);
}

@Test
public void resolveWhenUsingCustomIssuerAuthenticationManagerResolverAndCustomServerBearerTokenAuthenticationConverterThenUses() {
ReactiveAuthenticationManager authenticationManager = mock(ReactiveAuthenticationManager.class);
JwtIssuerReactiveAuthenticationManagerResolver authenticationManagerResolver = new JwtIssuerReactiveAuthenticationManagerResolver(
(issuer) -> Mono.just(authenticationManager));
ServerBearerTokenAuthenticationConverter serverBearerTokenAuthenticationConverterSpy = spy(
new ServerBearerTokenAuthenticationConverter());
authenticationManagerResolver
.setServerBearerTokenAuthenticationConverter(serverBearerTokenAuthenticationConverterSpy);
MockServerWebExchange exchange = withBearerToken(this.jwt);
assertThat(authenticationManagerResolver.resolve(exchange).block()).isSameAs(authenticationManager);
verify(serverBearerTokenAuthenticationConverterSpy).convert(any());
}

@Test
public void resolveWhenUsingExternalSourceThenRespondsToChanges() {
MockServerWebExchange exchange = withBearerToken(this.jwt);
Expand Down