Skip to content

Commit d0d655e

Browse files
arvidOttjzheaux
authored andcommitted
Allow Customization of Bearer Token Resolution
Closes gh-8535
1 parent 9d1637d commit d0d655e

File tree

4 files changed

+91
-4
lines changed

4 files changed

+91
-4
lines changed

oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/JwtIssuerAuthenticationManagerResolver.java

+21-2
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public final class JwtIssuerAuthenticationManagerResolver implements Authenticat
6565

6666
private final AuthenticationManagerResolver<String> issuerAuthenticationManagerResolver;
6767

68-
private final Converter<HttpServletRequest, String> issuerConverter = new JwtClaimIssuerConverter();
68+
private Converter<HttpServletRequest, String> issuerConverter = new JwtClaimIssuerConverter();
6969

7070
/**
7171
* Construct a {@link JwtIssuerAuthenticationManagerResolver} using the provided
@@ -130,9 +130,28 @@ public AuthenticationManager resolve(HttpServletRequest request) {
130130
return authenticationManager;
131131
}
132132

133+
/**
134+
* Set a custom bearer token resolver
135+
*
136+
* @since 5.5
137+
*/
138+
public void setBearerTokenResolver(BearerTokenResolver bearerTokenResolver) {
139+
Assert.notNull(bearerTokenResolver, "bearerTokenResolver cannot be null");
140+
this.issuerConverter = new JwtClaimIssuerConverter(bearerTokenResolver);
141+
}
142+
133143
private static class JwtClaimIssuerConverter implements Converter<HttpServletRequest, String> {
134144

135-
private final BearerTokenResolver resolver = new DefaultBearerTokenResolver();
145+
private final BearerTokenResolver resolver;
146+
147+
JwtClaimIssuerConverter() {
148+
this(new DefaultBearerTokenResolver());
149+
}
150+
151+
JwtClaimIssuerConverter(BearerTokenResolver bearerTokenResolver) {
152+
Assert.notNull(bearerTokenResolver, "bearerTokenResolver cannot be null");
153+
this.resolver = bearerTokenResolver;
154+
}
136155

137156
@Override
138157
public String convert(@NonNull HttpServletRequest request) {

oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/JwtIssuerReactiveAuthenticationManagerResolver.java

+24-2
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public final class JwtIssuerReactiveAuthenticationManagerResolver
6565

6666
private final ReactiveAuthenticationManagerResolver<String> issuerAuthenticationManagerResolver;
6767

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

7070
/**
7171
* Construct a {@link JwtIssuerReactiveAuthenticationManagerResolver} using the
@@ -131,9 +131,31 @@ public Mono<ReactiveAuthenticationManager> resolve(ServerWebExchange exchange) {
131131
// @formatter:on
132132
}
133133

134+
/**
135+
* Set a custom server bearer token authentication converter
136+
*
137+
* @since 5.5
138+
*/
139+
public void setServerBearerTokenAuthenticationConverter(
140+
ServerBearerTokenAuthenticationConverter serverBearerTokenAuthenticationConverter) {
141+
Assert.notNull(serverBearerTokenAuthenticationConverter,
142+
"serverBearerTokenAuthenticationConverter cannot be null");
143+
this.issuerConverter = new JwtClaimIssuerConverter(serverBearerTokenAuthenticationConverter);
144+
}
145+
134146
private static class JwtClaimIssuerConverter implements Converter<ServerWebExchange, Mono<String>> {
135147

136-
private final ServerBearerTokenAuthenticationConverter converter = new ServerBearerTokenAuthenticationConverter();
148+
private final ServerBearerTokenAuthenticationConverter converter;
149+
150+
JwtClaimIssuerConverter() {
151+
this(new ServerBearerTokenAuthenticationConverter());
152+
}
153+
154+
JwtClaimIssuerConverter(ServerBearerTokenAuthenticationConverter serverBearerTokenAuthenticationConverter) {
155+
Assert.notNull(serverBearerTokenAuthenticationConverter,
156+
"serverBearerTokenAuthenticationConverter cannot be null");
157+
this.converter = serverBearerTokenAuthenticationConverter;
158+
}
137159

138160
@Override
139161
public Mono<String> convert(@NonNull ServerWebExchange exchange) {

oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtIssuerAuthenticationManagerResolverTests.java

+28
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import java.util.HashMap;
2222
import java.util.Map;
2323

24+
import javax.servlet.http.HttpServletRequest;
25+
2426
import com.nimbusds.jose.JWSAlgorithm;
2527
import com.nimbusds.jose.JWSHeader;
2628
import com.nimbusds.jose.JWSObject;
@@ -39,11 +41,15 @@
3941
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
4042
import org.springframework.security.oauth2.jose.TestKeys;
4143
import org.springframework.security.oauth2.jwt.JwtClaimNames;
44+
import org.springframework.security.oauth2.server.resource.web.BearerTokenResolver;
4245

4346
import static org.assertj.core.api.Assertions.assertThat;
4447
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
4548
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
49+
import static org.mockito.Mockito.any;
4650
import static org.mockito.Mockito.mock;
51+
import static org.mockito.Mockito.spy;
52+
import static org.mockito.Mockito.verify;
4753

4854
/**
4955
* Tests for {@link JwtIssuerAuthenticationManagerResolver}
@@ -113,6 +119,19 @@ public void resolveWhenUsingCustomIssuerAuthenticationManagerResolverThenUses()
113119
assertThat(authenticationManagerResolver.resolve(request)).isSameAs(authenticationManager);
114120
}
115121

122+
@Test
123+
public void resolveWhenUsingCustomIssuerAuthenticationManagerResolverAndCustomBearerTokenResolverThenUses() {
124+
AuthenticationManager authenticationManager = mock(AuthenticationManager.class);
125+
JwtIssuerAuthenticationManagerResolver authenticationManagerResolver = new JwtIssuerAuthenticationManagerResolver(
126+
(issuer) -> authenticationManager);
127+
BearerTokenResolver bearerTokenResolverSpy = spy(new TestBearerTokenResolver());
128+
authenticationManagerResolver.setBearerTokenResolver(bearerTokenResolverSpy);
129+
MockHttpServletRequest request = new MockHttpServletRequest();
130+
request.addHeader("Authorization", "Bearer " + this.jwt);
131+
assertThat(authenticationManagerResolver.resolve(request)).isSameAs(authenticationManager);
132+
verify(bearerTokenResolverSpy).resolve(any());
133+
}
134+
116135
@Test
117136
public void resolveWhenUsingExternalSourceThenRespondsToChanges() {
118137
MockHttpServletRequest request = new MockHttpServletRequest();
@@ -196,4 +215,13 @@ private String jwt(String claim, String value) {
196215
return jwt.serialize();
197216
}
198217

218+
static class TestBearerTokenResolver implements BearerTokenResolver {
219+
220+
@Override
221+
public String resolve(HttpServletRequest request) {
222+
return "eyJhbGciOiJub25lIn0.eyJpc3MiOiJ0cnVzdGVkIn0.";
223+
}
224+
225+
}
226+
199227
}

oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtIssuerReactiveAuthenticationManagerResolverTests.java

+18
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,15 @@
4141
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
4242
import org.springframework.security.oauth2.jose.TestKeys;
4343
import org.springframework.security.oauth2.jwt.JwtClaimNames;
44+
import org.springframework.security.oauth2.server.resource.web.server.ServerBearerTokenAuthenticationConverter;
4445

4546
import static org.assertj.core.api.Assertions.assertThat;
4647
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
4748
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
49+
import static org.mockito.Mockito.any;
4850
import static org.mockito.Mockito.mock;
51+
import static org.mockito.Mockito.spy;
52+
import static org.mockito.Mockito.verify;
4953

5054
/**
5155
* Tests for {@link JwtIssuerReactiveAuthenticationManagerResolver}
@@ -111,6 +115,20 @@ public void resolveWhenUsingCustomIssuerAuthenticationManagerResolverThenUses()
111115
assertThat(authenticationManagerResolver.resolve(exchange).block()).isSameAs(authenticationManager);
112116
}
113117

118+
@Test
119+
public void resolveWhenUsingCustomIssuerAuthenticationManagerResolverAndCustomServerBearerTokenAuthenticationConverterThenUses() {
120+
ReactiveAuthenticationManager authenticationManager = mock(ReactiveAuthenticationManager.class);
121+
JwtIssuerReactiveAuthenticationManagerResolver authenticationManagerResolver = new JwtIssuerReactiveAuthenticationManagerResolver(
122+
(issuer) -> Mono.just(authenticationManager));
123+
ServerBearerTokenAuthenticationConverter serverBearerTokenAuthenticationConverterSpy = spy(
124+
new ServerBearerTokenAuthenticationConverter());
125+
authenticationManagerResolver
126+
.setServerBearerTokenAuthenticationConverter(serverBearerTokenAuthenticationConverterSpy);
127+
MockServerWebExchange exchange = withBearerToken(this.jwt);
128+
assertThat(authenticationManagerResolver.resolve(exchange).block()).isSameAs(authenticationManager);
129+
verify(serverBearerTokenAuthenticationConverterSpy).convert(any());
130+
}
131+
114132
@Test
115133
public void resolveWhenUsingExternalSourceThenRespondsToChanges() {
116134
MockServerWebExchange exchange = withBearerToken(this.jwt);

0 commit comments

Comments
 (0)