Rename OAuth2TokenIntrospectionClient

Renamed to OpaqueTokenIntrospector

Fixes gh-7245
This commit is contained in:
Josh Cummings 2019-08-09 17:47:31 -06:00
parent cfef52f50c
commit 4ed197e515
14 changed files with 147 additions and 146 deletions

View File

@ -38,8 +38,8 @@ import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationProvider; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationProvider;
import org.springframework.security.oauth2.server.resource.authentication.OAuth2IntrospectionAuthenticationProvider; import org.springframework.security.oauth2.server.resource.authentication.OAuth2IntrospectionAuthenticationProvider;
import org.springframework.security.oauth2.server.resource.introspection.NimbusOAuth2TokenIntrospectionClient; import org.springframework.security.oauth2.server.resource.introspection.NimbusOpaqueTokenIntrospector;
import org.springframework.security.oauth2.server.resource.introspection.OAuth2TokenIntrospectionClient; import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector;
import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationEntryPoint; import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationEntryPoint;
import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationFilter; import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationFilter;
import org.springframework.security.oauth2.server.resource.web.BearerTokenResolver; import org.springframework.security.oauth2.server.resource.web.BearerTokenResolver;
@ -339,7 +339,7 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
private String introspectionUri; private String introspectionUri;
private String clientId; private String clientId;
private String clientSecret; private String clientSecret;
private Supplier<OAuth2TokenIntrospectionClient> introspectionClient; private Supplier<OpaqueTokenIntrospector> introspector;
OpaqueTokenConfigurer(ApplicationContext context) { OpaqueTokenConfigurer(ApplicationContext context) {
this.context = context; this.context = context;
@ -354,8 +354,8 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
public OpaqueTokenConfigurer introspectionUri(String introspectionUri) { public OpaqueTokenConfigurer introspectionUri(String introspectionUri) {
Assert.notNull(introspectionUri, "introspectionUri cannot be null"); Assert.notNull(introspectionUri, "introspectionUri cannot be null");
this.introspectionUri = introspectionUri; this.introspectionUri = introspectionUri;
this.introspectionClient = () -> this.introspector = () ->
new NimbusOAuth2TokenIntrospectionClient(this.introspectionUri, this.clientId, this.clientSecret); new NimbusOpaqueTokenIntrospector(this.introspectionUri, this.clientId, this.clientSecret);
return this; return this;
} }
@ -364,22 +364,22 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
Assert.notNull(clientSecret, "clientSecret cannot be null"); Assert.notNull(clientSecret, "clientSecret cannot be null");
this.clientId = clientId; this.clientId = clientId;
this.clientSecret = clientSecret; this.clientSecret = clientSecret;
this.introspectionClient = () -> this.introspector = () ->
new NimbusOAuth2TokenIntrospectionClient(this.introspectionUri, this.clientId, this.clientSecret); new NimbusOpaqueTokenIntrospector(this.introspectionUri, this.clientId, this.clientSecret);
return this; return this;
} }
public OpaqueTokenConfigurer introspectionClient(OAuth2TokenIntrospectionClient introspectionClient) { public OpaqueTokenConfigurer introspector(OpaqueTokenIntrospector introspector) {
Assert.notNull(introspectionClient, "introspectionClient cannot be null"); Assert.notNull(introspector, "introspector cannot be null");
this.introspectionClient = () -> introspectionClient; this.introspector = () -> introspector;
return this; return this;
} }
OAuth2TokenIntrospectionClient getIntrospectionClient() { OpaqueTokenIntrospector getIntrospector() {
if (this.introspectionClient != null) { if (this.introspector != null) {
return this.introspectionClient.get(); return this.introspector.get();
} }
return this.context.getBean(OAuth2TokenIntrospectionClient.class); return this.context.getBean(OpaqueTokenIntrospector.class);
} }
AuthenticationManager getAuthenticationManager(H http) { AuthenticationManager getAuthenticationManager(H http) {
@ -387,9 +387,9 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
return this.authenticationManager; return this.authenticationManager;
} }
OAuth2TokenIntrospectionClient introspectionClient = getIntrospectionClient(); OpaqueTokenIntrospector introspector = getIntrospector();
OAuth2IntrospectionAuthenticationProvider provider = OAuth2IntrospectionAuthenticationProvider provider =
new OAuth2IntrospectionAuthenticationProvider(introspectionClient); new OAuth2IntrospectionAuthenticationProvider(introspector);
http.authenticationProvider(provider); http.authenticationProvider(provider);
return http.getSharedObject(AuthenticationManager.class); return http.getSharedObject(AuthenticationManager.class);

View File

@ -32,7 +32,6 @@ import java.util.UUID;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.springframework.security.config.Customizer;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import reactor.util.context.Context; import reactor.util.context.Context;
@ -53,6 +52,7 @@ import org.springframework.security.authorization.AuthenticatedReactiveAuthoriza
import org.springframework.security.authorization.AuthorityReactiveAuthorizationManager; import org.springframework.security.authorization.AuthorityReactiveAuthorizationManager;
import org.springframework.security.authorization.AuthorizationDecision; import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.ReactiveAuthorizationManager; import org.springframework.security.authorization.ReactiveAuthorizationManager;
import org.springframework.security.config.Customizer;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.authority.AuthorityUtils;
@ -90,8 +90,8 @@ import org.springframework.security.oauth2.server.resource.authentication.JwtAut
import org.springframework.security.oauth2.server.resource.authentication.JwtReactiveAuthenticationManager; import org.springframework.security.oauth2.server.resource.authentication.JwtReactiveAuthenticationManager;
import org.springframework.security.oauth2.server.resource.authentication.OAuth2IntrospectionReactiveAuthenticationManager; import org.springframework.security.oauth2.server.resource.authentication.OAuth2IntrospectionReactiveAuthenticationManager;
import org.springframework.security.oauth2.server.resource.authentication.ReactiveJwtAuthenticationConverterAdapter; import org.springframework.security.oauth2.server.resource.authentication.ReactiveJwtAuthenticationConverterAdapter;
import org.springframework.security.oauth2.server.resource.introspection.NimbusReactiveOAuth2TokenIntrospectionClient; import org.springframework.security.oauth2.server.resource.introspection.NimbusReactiveOpaqueTokenIntrospector;
import org.springframework.security.oauth2.server.resource.introspection.ReactiveOAuth2TokenIntrospectionClient; import org.springframework.security.oauth2.server.resource.introspection.ReactiveOpaqueTokenIntrospector;
import org.springframework.security.oauth2.server.resource.web.access.server.BearerTokenServerAccessDeniedHandler; import org.springframework.security.oauth2.server.resource.web.access.server.BearerTokenServerAccessDeniedHandler;
import org.springframework.security.oauth2.server.resource.web.server.BearerTokenServerAuthenticationEntryPoint; import org.springframework.security.oauth2.server.resource.web.server.BearerTokenServerAuthenticationEntryPoint;
import org.springframework.security.oauth2.server.resource.web.server.ServerBearerTokenAuthenticationConverter; import org.springframework.security.oauth2.server.resource.web.server.ServerBearerTokenAuthenticationConverter;
@ -1820,7 +1820,7 @@ public class ServerHttpSecurity {
private String introspectionUri; private String introspectionUri;
private String clientId; private String clientId;
private String clientSecret; private String clientSecret;
private Supplier<ReactiveOAuth2TokenIntrospectionClient> introspectionClient; private Supplier<ReactiveOpaqueTokenIntrospector> introspector;
/** /**
* Configures the URI of the Introspection endpoint * Configures the URI of the Introspection endpoint
@ -1830,8 +1830,8 @@ public class ServerHttpSecurity {
public OpaqueTokenSpec introspectionUri(String introspectionUri) { public OpaqueTokenSpec introspectionUri(String introspectionUri) {
Assert.hasText(introspectionUri, "introspectionUri cannot be empty"); Assert.hasText(introspectionUri, "introspectionUri cannot be empty");
this.introspectionUri = introspectionUri; this.introspectionUri = introspectionUri;
this.introspectionClient = () -> this.introspector = () ->
new NimbusReactiveOAuth2TokenIntrospectionClient( new NimbusReactiveOpaqueTokenIntrospector(
this.introspectionUri, this.clientId, this.clientSecret); this.introspectionUri, this.clientId, this.clientSecret);
return this; return this;
} }
@ -1847,15 +1847,15 @@ public class ServerHttpSecurity {
Assert.notNull(clientSecret, "clientSecret cannot be null"); Assert.notNull(clientSecret, "clientSecret cannot be null");
this.clientId = clientId; this.clientId = clientId;
this.clientSecret = clientSecret; this.clientSecret = clientSecret;
this.introspectionClient = () -> this.introspector = () ->
new NimbusReactiveOAuth2TokenIntrospectionClient( new NimbusReactiveOpaqueTokenIntrospector(
this.introspectionUri, this.clientId, this.clientSecret); this.introspectionUri, this.clientId, this.clientSecret);
return this; return this;
} }
public OpaqueTokenSpec introspectionClient(ReactiveOAuth2TokenIntrospectionClient introspectionClient) { public OpaqueTokenSpec introspector(ReactiveOpaqueTokenIntrospector introspector) {
Assert.notNull(introspectionClient, "introspectionClient cannot be null"); Assert.notNull(introspector, "introspector cannot be null");
this.introspectionClient = () -> introspectionClient; this.introspector = () -> introspector;
return this; return this;
} }
@ -1868,14 +1868,14 @@ public class ServerHttpSecurity {
} }
protected ReactiveAuthenticationManager getAuthenticationManager() { protected ReactiveAuthenticationManager getAuthenticationManager() {
return new OAuth2IntrospectionReactiveAuthenticationManager(getIntrospectionClient()); return new OAuth2IntrospectionReactiveAuthenticationManager(getIntrospector());
} }
protected ReactiveOAuth2TokenIntrospectionClient getIntrospectionClient() { protected ReactiveOpaqueTokenIntrospector getIntrospector() {
if (this.introspectionClient != null) { if (this.introspector != null) {
return this.introspectionClient.get(); return this.introspector.get();
} }
return getBean(ReactiveOAuth2TokenIntrospectionClient.class); return getBean(ReactiveOpaqueTokenIntrospector.class);
} }
protected void configure(ServerHttpSecurity http) { protected void configure(ServerHttpSecurity http) {

View File

@ -92,8 +92,8 @@ import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.security.oauth2.server.resource.authentication.OAuth2IntrospectionAuthenticationToken; import org.springframework.security.oauth2.server.resource.authentication.OAuth2IntrospectionAuthenticationToken;
import org.springframework.security.oauth2.server.resource.introspection.NimbusOAuth2TokenIntrospectionClient; import org.springframework.security.oauth2.server.resource.introspection.NimbusOpaqueTokenIntrospector;
import org.springframework.security.oauth2.server.resource.introspection.OAuth2TokenIntrospectionClient; import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector;
import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationEntryPoint; import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationEntryPoint;
import org.springframework.security.oauth2.server.resource.web.BearerTokenResolver; import org.springframework.security.oauth2.server.resource.web.BearerTokenResolver;
import org.springframework.security.oauth2.server.resource.web.DefaultBearerTokenResolver; import org.springframework.security.oauth2.server.resource.web.DefaultBearerTokenResolver;
@ -1182,38 +1182,38 @@ public class OAuth2ResourceServerConfigurerTests {
OAuth2ResourceServerConfigurer.OpaqueTokenConfigurer opaqueTokenConfigurer = OAuth2ResourceServerConfigurer.OpaqueTokenConfigurer opaqueTokenConfigurer =
new OAuth2ResourceServerConfigurer(context).opaqueToken(); new OAuth2ResourceServerConfigurer(context).opaqueToken();
OAuth2TokenIntrospectionClient client = mock(OAuth2TokenIntrospectionClient.class); OpaqueTokenIntrospector client = mock(OpaqueTokenIntrospector.class);
opaqueTokenConfigurer.introspectionUri(INTROSPECTION_URI); opaqueTokenConfigurer.introspectionUri(INTROSPECTION_URI);
opaqueTokenConfigurer.introspectionClientCredentials(CLIENT_ID, CLIENT_SECRET); opaqueTokenConfigurer.introspectionClientCredentials(CLIENT_ID, CLIENT_SECRET);
opaqueTokenConfigurer.introspectionClient(client); opaqueTokenConfigurer.introspector(client);
assertThat(opaqueTokenConfigurer.getIntrospectionClient()).isEqualTo(client); assertThat(opaqueTokenConfigurer.getIntrospector()).isEqualTo(client);
opaqueTokenConfigurer = opaqueTokenConfigurer =
new OAuth2ResourceServerConfigurer(context).opaqueToken(); new OAuth2ResourceServerConfigurer(context).opaqueToken();
opaqueTokenConfigurer.introspectionClient(client); opaqueTokenConfigurer.introspector(client);
opaqueTokenConfigurer.introspectionUri(INTROSPECTION_URI); opaqueTokenConfigurer.introspectionUri(INTROSPECTION_URI);
opaqueTokenConfigurer.introspectionClientCredentials(CLIENT_ID, CLIENT_SECRET); opaqueTokenConfigurer.introspectionClientCredentials(CLIENT_ID, CLIENT_SECRET);
assertThat(opaqueTokenConfigurer.getIntrospectionClient()) assertThat(opaqueTokenConfigurer.getIntrospector())
.isInstanceOf(NimbusOAuth2TokenIntrospectionClient.class); .isInstanceOf(NimbusOpaqueTokenIntrospector.class);
} }
@Test @Test
public void getIntrospectionClientWhenDslAndBeanWiredThenDslTakesPrecedence() { public void getIntrospectionClientWhenDslAndBeanWiredThenDslTakesPrecedence() {
GenericApplicationContext context = new GenericApplicationContext(); GenericApplicationContext context = new GenericApplicationContext();
registerMockBean(context, "introspectionClientOne", OAuth2TokenIntrospectionClient.class); registerMockBean(context, "introspectionClientOne", OpaqueTokenIntrospector.class);
registerMockBean(context, "introspectionClientTwo", OAuth2TokenIntrospectionClient.class); registerMockBean(context, "introspectionClientTwo", OpaqueTokenIntrospector.class);
OAuth2ResourceServerConfigurer.OpaqueTokenConfigurer opaqueToken = OAuth2ResourceServerConfigurer.OpaqueTokenConfigurer opaqueToken =
new OAuth2ResourceServerConfigurer(context).opaqueToken(); new OAuth2ResourceServerConfigurer(context).opaqueToken();
opaqueToken.introspectionUri(INTROSPECTION_URI); opaqueToken.introspectionUri(INTROSPECTION_URI);
opaqueToken.introspectionClientCredentials(CLIENT_ID, CLIENT_SECRET); opaqueToken.introspectionClientCredentials(CLIENT_ID, CLIENT_SECRET);
assertThat(opaqueToken.getIntrospectionClient()).isNotNull(); assertThat(opaqueToken.getIntrospector()).isNotNull();
} }
// -- In combination with other authentication providers // -- In combination with other authentication providers
@ -1327,7 +1327,7 @@ public class OAuth2ResourceServerConfigurerTests {
oauth2ResourceServer oauth2ResourceServer
.opaqueToken() .opaqueToken()
.authenticationManager(authenticationManager) .authenticationManager(authenticationManager)
.introspectionClient(mock(OAuth2TokenIntrospectionClient.class)); .introspector(mock(OpaqueTokenIntrospector.class));
assertThat(oauth2ResourceServer.getAuthenticationManager(http)).isSameAs(authenticationManager); assertThat(oauth2ResourceServer.getAuthenticationManager(http)).isSameAs(authenticationManager);
verify(http, never()).authenticationProvider(any(AuthenticationProvider.class)); verify(http, never()).authenticationProvider(any(AuthenticationProvider.class));
} }
@ -2164,8 +2164,8 @@ public class OAuth2ResourceServerConfigurerTests {
} }
@Bean @Bean
NimbusOAuth2TokenIntrospectionClient tokenIntrospectionClient() { NimbusOpaqueTokenIntrospector tokenIntrospectionClient() {
return new NimbusOAuth2TokenIntrospectionClient("https://example.org/introspect", this.rest); return new NimbusOpaqueTokenIntrospector("https://example.org/introspect", this.rest);
} }
} }

View File

@ -34,7 +34,7 @@ import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.OAuth2Error; import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.core.OAuth2TokenAttributes; import org.springframework.security.oauth2.core.OAuth2TokenAttributes;
import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionException; import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionException;
import org.springframework.security.oauth2.server.resource.introspection.OAuth2TokenIntrospectionClient; import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector;
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken; import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
import org.springframework.security.oauth2.server.resource.BearerTokenError; import org.springframework.security.oauth2.server.resource.BearerTokenError;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -69,14 +69,14 @@ public final class OAuth2IntrospectionAuthenticationProvider implements Authenti
private static final BearerTokenError DEFAULT_INVALID_TOKEN = private static final BearerTokenError DEFAULT_INVALID_TOKEN =
invalidToken("An error occurred while attempting to introspect the token: Invalid token"); invalidToken("An error occurred while attempting to introspect the token: Invalid token");
private OAuth2TokenIntrospectionClient introspectionClient; private OpaqueTokenIntrospector introspectionClient;
/** /**
* Creates a {@code OAuth2IntrospectionAuthenticationProvider} with the provided parameters * Creates a {@code OAuth2IntrospectionAuthenticationProvider} with the provided parameters
* *
* @param introspectionClient The {@link OAuth2TokenIntrospectionClient} to use * @param introspectionClient The {@link OpaqueTokenIntrospector} to use
*/ */
public OAuth2IntrospectionAuthenticationProvider(OAuth2TokenIntrospectionClient introspectionClient) { public OAuth2IntrospectionAuthenticationProvider(OpaqueTokenIntrospector introspectionClient) {
Assert.notNull(introspectionClient, "introspectionClient cannot be null"); Assert.notNull(introspectionClient, "introspectionClient cannot be null");
this.introspectionClient = introspectionClient; this.introspectionClient = introspectionClient;
} }

View File

@ -35,7 +35,7 @@ import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.OAuth2Error; import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionException; import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionException;
import org.springframework.security.oauth2.server.resource.introspection.ReactiveOAuth2TokenIntrospectionClient; import org.springframework.security.oauth2.server.resource.introspection.ReactiveOpaqueTokenIntrospector;
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken; import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
import org.springframework.security.oauth2.server.resource.BearerTokenError; import org.springframework.security.oauth2.server.resource.BearerTokenError;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -70,14 +70,14 @@ public class OAuth2IntrospectionReactiveAuthenticationManager implements Reactiv
private static final BearerTokenError DEFAULT_INVALID_TOKEN = private static final BearerTokenError DEFAULT_INVALID_TOKEN =
invalidToken("An error occurred while attempting to introspect the token: Invalid token"); invalidToken("An error occurred while attempting to introspect the token: Invalid token");
private ReactiveOAuth2TokenIntrospectionClient introspectionClient; private ReactiveOpaqueTokenIntrospector introspectionClient;
/** /**
* Creates a {@code OAuth2IntrospectionReactiveAuthenticationManager} with the provided parameters * Creates a {@code OAuth2IntrospectionReactiveAuthenticationManager} with the provided parameters
* *
* @param introspectionClient The {@link ReactiveOAuth2TokenIntrospectionClient} to use * @param introspectionClient The {@link ReactiveOpaqueTokenIntrospector} to use
*/ */
public OAuth2IntrospectionReactiveAuthenticationManager(ReactiveOAuth2TokenIntrospectionClient introspectionClient) { public OAuth2IntrospectionReactiveAuthenticationManager(ReactiveOpaqueTokenIntrospector introspectionClient) {
Assert.notNull(introspectionClient, "introspectionClient cannot be null"); Assert.notNull(introspectionClient, "introspectionClient cannot be null");
this.introspectionClient = introspectionClient; this.introspectionClient = introspectionClient;
} }

View File

@ -52,13 +52,15 @@ import static org.springframework.security.oauth2.server.resource.introspection.
import static org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames.SCOPE; import static org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames.SCOPE;
/** /**
* A Nimbus implementation of {@link OAuth2TokenIntrospectionClient}. * A Nimbus implementation of {@link OpaqueTokenIntrospector} that verifies and introspects
* a token using the configured
* <a href="https://tools.ietf.org/html/rfc7662" target="_blank">OAuth 2.0 Introspection Endpoint</a>.
* *
* @author Josh Cummings * @author Josh Cummings
* @author MD Sayem Ahmed * @author MD Sayem Ahmed
* @since 5.2 * @since 5.2
*/ */
public class NimbusOAuth2TokenIntrospectionClient implements OAuth2TokenIntrospectionClient { public class NimbusOpaqueTokenIntrospector implements OpaqueTokenIntrospector {
private Converter<String, RequestEntity<?>> requestEntityConverter; private Converter<String, RequestEntity<?>> requestEntityConverter;
private RestOperations restOperations; private RestOperations restOperations;
@ -69,7 +71,7 @@ public class NimbusOAuth2TokenIntrospectionClient implements OAuth2TokenIntrospe
* @param clientId The client id authorized to introspect * @param clientId The client id authorized to introspect
* @param clientSecret The client's secret * @param clientSecret The client's secret
*/ */
public NimbusOAuth2TokenIntrospectionClient(String introspectionUri, String clientId, String clientSecret) { public NimbusOpaqueTokenIntrospector(String introspectionUri, String clientId, String clientSecret) {
Assert.notNull(introspectionUri, "introspectionUri cannot be null"); Assert.notNull(introspectionUri, "introspectionUri cannot be null");
Assert.notNull(clientId, "clientId cannot be null"); Assert.notNull(clientId, "clientId cannot be null");
Assert.notNull(clientSecret, "clientSecret cannot be null"); Assert.notNull(clientSecret, "clientSecret cannot be null");
@ -89,7 +91,7 @@ public class NimbusOAuth2TokenIntrospectionClient implements OAuth2TokenIntrospe
* @param introspectionUri The introspection endpoint uri * @param introspectionUri The introspection endpoint uri
* @param restOperations The client for performing the introspection request * @param restOperations The client for performing the introspection request
*/ */
public NimbusOAuth2TokenIntrospectionClient(String introspectionUri, RestOperations restOperations) { public NimbusOpaqueTokenIntrospector(String introspectionUri, RestOperations restOperations) {
Assert.notNull(introspectionUri, "introspectionUri cannot be null"); Assert.notNull(introspectionUri, "introspectionUri cannot be null");
Assert.notNull(restOperations, "restOperations cannot be null"); Assert.notNull(restOperations, "restOperations cannot be null");

View File

@ -46,12 +46,14 @@ import static org.springframework.security.oauth2.server.resource.introspection.
import static org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames.SCOPE; import static org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames.SCOPE;
/** /**
* A Nimbus implementation of {@link ReactiveOAuth2TokenIntrospectionClient} * A Nimbus implementation of {@link ReactiveOpaqueTokenIntrospector} that verifies and introspects
* a token using the configured
* <a href="https://tools.ietf.org/html/rfc7662" target="_blank">OAuth 2.0 Introspection Endpoint</a>.
* *
* @author Josh Cummings * @author Josh Cummings
* @since 5.2 * @since 5.2
*/ */
public class NimbusReactiveOAuth2TokenIntrospectionClient implements ReactiveOAuth2TokenIntrospectionClient { public class NimbusReactiveOpaqueTokenIntrospector implements ReactiveOpaqueTokenIntrospector {
private URI introspectionUri; private URI introspectionUri;
private WebClient webClient; private WebClient webClient;
@ -62,7 +64,7 @@ public class NimbusReactiveOAuth2TokenIntrospectionClient implements ReactiveOAu
* @param clientId The client id authorized to introspect * @param clientId The client id authorized to introspect
* @param clientSecret The client secret for the authorized client * @param clientSecret The client secret for the authorized client
*/ */
public NimbusReactiveOAuth2TokenIntrospectionClient(String introspectionUri, String clientId, String clientSecret) { public NimbusReactiveOpaqueTokenIntrospector(String introspectionUri, String clientId, String clientSecret) {
Assert.hasText(introspectionUri, "introspectionUri cannot be empty"); Assert.hasText(introspectionUri, "introspectionUri cannot be empty");
Assert.hasText(clientId, "clientId cannot be empty"); Assert.hasText(clientId, "clientId cannot be empty");
Assert.notNull(clientSecret, "clientSecret cannot be null"); Assert.notNull(clientSecret, "clientSecret cannot be null");
@ -79,7 +81,7 @@ public class NimbusReactiveOAuth2TokenIntrospectionClient implements ReactiveOAu
* @param introspectionUri The introspection endpoint uri * @param introspectionUri The introspection endpoint uri
* @param webClient The client for performing the introspection request * @param webClient The client for performing the introspection request
*/ */
public NimbusReactiveOAuth2TokenIntrospectionClient(String introspectionUri, WebClient webClient) { public NimbusReactiveOpaqueTokenIntrospector(String introspectionUri, WebClient webClient) {
Assert.hasText(introspectionUri, "introspectionUri cannot be null"); Assert.hasText(introspectionUri, "introspectionUri cannot be null");
Assert.notNull(webClient, "webClient cannot be null"); Assert.notNull(webClient, "webClient cannot be null");

View File

@ -19,25 +19,27 @@ package org.springframework.security.oauth2.server.resource.introspection;
import java.util.Map; import java.util.Map;
/** /**
* A client to an * A contract for introspecting and verifying an OAuth 2.0 token.
* <a href="https://tools.ietf.org/html/rfc7662" target="_blank">OAuth 2.0 Introspection Endpoint</a>.
* *
* Basically, this client is handy when a resource server authenticates opaque OAuth 2.0 tokens. * A typical implementation of this interface will make a request to an
* It's also nice when a resource server simply can't decode tokens - whether the tokens are opaque or not - * <a href="https://tools.ietf.org/html/rfc7662" target="_blank">OAuth 2.0 Introspection Endpoint</a>
* and would prefer to delegate that task to an authorization server. * to verify the token and return its attributes, indicating a successful verification.
*
* Another sensible implementation of this interface would be to query a backing store
* of tokens, for example a distributed cache.
* *
* @author Josh Cummings * @author Josh Cummings
* @since 5.2 * @since 5.2
*/ */
public interface OAuth2TokenIntrospectionClient { public interface OpaqueTokenIntrospector {
/** /**
* Request that the configured * Introspect and verify the given token, returning its attributes.
* <a href="https://tools.ietf.org/html/rfc7662" target="_blank">OAuth 2.0 Introspection Endpoint</a> *
* introspect the given token and return its associated attributes. * Returning a {@link Map} is indicative that the token is valid.
* *
* @param token the token to introspect * @param token the token to introspect
* @return the token's attributes, including whether or not the token is active * @return the token's attributes
*/ */
Map<String, Object> introspect(String token); Map<String, Object> introspect(String token);
} }

View File

@ -21,25 +21,27 @@ import java.util.Map;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
/** /**
* A reactive client to an * A contract for introspecting and verifying an OAuth 2.0 token.
* <a href="https://tools.ietf.org/html/rfc7662" target="_blank">OAuth 2.0 Introspection Endpoint</a>.
* *
* Basically, this client is handy when a resource server authenticates opaque OAuth 2.0 tokens. * A typical implementation of this interface will make a request to an
* It's also nice when a resource server simply can't decode tokens - whether the tokens are opaque or not - * <a href="https://tools.ietf.org/html/rfc7662" target="_blank">OAuth 2.0 Introspection Endpoint</a>
* and would prefer to delegate that task to an authorization server. * to verify the token and return its attributes, indicating a successful verification.
*
* Another sensible implementation of this interface would be to query a backing store
* of tokens, for example a distributed cache.
* *
* @author Josh Cummings * @author Josh Cummings
* @since 5.2 * @since 5.2
*/ */
public interface ReactiveOAuth2TokenIntrospectionClient { public interface ReactiveOpaqueTokenIntrospector {
/** /**
* Request that the configured * Introspect and verify the given token, returning its attributes.
* <a href="https://tools.ietf.org/html/rfc7662" target="_blank">OAuth 2.0 Introspection Endpoint</a> *
* introspect the given token and return its associated attributes. * Returning a {@link Map} is indicative that the token is valid.
* *
* @param token the token to introspect * @param token the token to introspect
* @return the token's attributes, including whether or not the token is active * @return the token's attributes
*/ */
Mono<Map<String, Object>> introspect(String token); Mono<Map<String, Object>> introspect(String token);
} }

View File

@ -27,7 +27,7 @@ import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.OAuth2TokenAttributes; import org.springframework.security.oauth2.core.OAuth2TokenAttributes;
import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames; import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames;
import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionException; import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionException;
import org.springframework.security.oauth2.server.resource.introspection.OAuth2TokenIntrospectionClient; import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector;
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken; import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -56,7 +56,7 @@ public class OAuth2IntrospectionAuthenticationProviderTests {
public void authenticateWhenActiveTokenThenOk() throws Exception { public void authenticateWhenActiveTokenThenOk() throws Exception {
Map<String, Object> claims = active(); Map<String, Object> claims = active();
claims.put("extension_field", "twenty-seven"); claims.put("extension_field", "twenty-seven");
OAuth2TokenIntrospectionClient introspectionClient = mock(OAuth2TokenIntrospectionClient.class); OpaqueTokenIntrospector introspectionClient = mock(OpaqueTokenIntrospector.class);
when(introspectionClient.introspect(any())).thenReturn(claims); when(introspectionClient.introspect(any())).thenReturn(claims);
OAuth2IntrospectionAuthenticationProvider provider = OAuth2IntrospectionAuthenticationProvider provider =
new OAuth2IntrospectionAuthenticationProvider(introspectionClient); new OAuth2IntrospectionAuthenticationProvider(introspectionClient);
@ -88,7 +88,7 @@ public class OAuth2IntrospectionAuthenticationProviderTests {
public void authenticateWhenMissingScopeAttributeThenNoAuthorities() { public void authenticateWhenMissingScopeAttributeThenNoAuthorities() {
Map<String, Object> claims = active(); Map<String, Object> claims = active();
claims.remove(SCOPE); claims.remove(SCOPE);
OAuth2TokenIntrospectionClient introspectionClient = mock(OAuth2TokenIntrospectionClient.class); OpaqueTokenIntrospector introspectionClient = mock(OpaqueTokenIntrospector.class);
when(introspectionClient.introspect(any())).thenReturn(claims); when(introspectionClient.introspect(any())).thenReturn(claims);
OAuth2IntrospectionAuthenticationProvider provider = OAuth2IntrospectionAuthenticationProvider provider =
new OAuth2IntrospectionAuthenticationProvider(introspectionClient); new OAuth2IntrospectionAuthenticationProvider(introspectionClient);
@ -107,7 +107,7 @@ public class OAuth2IntrospectionAuthenticationProviderTests {
@Test @Test
public void authenticateWhenIntrospectionEndpointThrowsExceptionThenInvalidToken() { public void authenticateWhenIntrospectionEndpointThrowsExceptionThenInvalidToken() {
OAuth2TokenIntrospectionClient introspectionClient = mock(OAuth2TokenIntrospectionClient.class); OpaqueTokenIntrospector introspectionClient = mock(OpaqueTokenIntrospector.class);
when(introspectionClient.introspect(any())).thenThrow(new OAuth2IntrospectionException("with \"invalid\" chars")); when(introspectionClient.introspect(any())).thenThrow(new OAuth2IntrospectionException("with \"invalid\" chars"));
OAuth2IntrospectionAuthenticationProvider provider = OAuth2IntrospectionAuthenticationProvider provider =
new OAuth2IntrospectionAuthenticationProvider(introspectionClient); new OAuth2IntrospectionAuthenticationProvider(introspectionClient);

View File

@ -29,7 +29,7 @@ import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames; import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames;
import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionException; import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionException;
import org.springframework.security.oauth2.server.resource.introspection.ReactiveOAuth2TokenIntrospectionClient; import org.springframework.security.oauth2.server.resource.introspection.ReactiveOpaqueTokenIntrospector;
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken; import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -55,7 +55,7 @@ public class OAuth2IntrospectionReactiveAuthenticationManagerTests {
public void authenticateWhenActiveTokenThenOk() throws Exception { public void authenticateWhenActiveTokenThenOk() throws Exception {
Map<String, Object> claims = active(); Map<String, Object> claims = active();
claims.put("extension_field", "twenty-seven"); claims.put("extension_field", "twenty-seven");
ReactiveOAuth2TokenIntrospectionClient introspectionClient = mock(ReactiveOAuth2TokenIntrospectionClient.class); ReactiveOpaqueTokenIntrospector introspectionClient = mock(ReactiveOpaqueTokenIntrospector.class);
when(introspectionClient.introspect(any())).thenReturn(Mono.just(claims)); when(introspectionClient.introspect(any())).thenReturn(Mono.just(claims));
OAuth2IntrospectionReactiveAuthenticationManager provider = OAuth2IntrospectionReactiveAuthenticationManager provider =
new OAuth2IntrospectionReactiveAuthenticationManager(introspectionClient); new OAuth2IntrospectionReactiveAuthenticationManager(introspectionClient);
@ -87,7 +87,7 @@ public class OAuth2IntrospectionReactiveAuthenticationManagerTests {
public void authenticateWhenMissingScopeAttributeThenNoAuthorities() { public void authenticateWhenMissingScopeAttributeThenNoAuthorities() {
Map<String, Object> claims = active(); Map<String, Object> claims = active();
claims.remove(SCOPE); claims.remove(SCOPE);
ReactiveOAuth2TokenIntrospectionClient introspectionClient = mock(ReactiveOAuth2TokenIntrospectionClient.class); ReactiveOpaqueTokenIntrospector introspectionClient = mock(ReactiveOpaqueTokenIntrospector.class);
when(introspectionClient.introspect(any())).thenReturn(Mono.just(claims)); when(introspectionClient.introspect(any())).thenReturn(Mono.just(claims));
OAuth2IntrospectionReactiveAuthenticationManager provider = OAuth2IntrospectionReactiveAuthenticationManager provider =
new OAuth2IntrospectionReactiveAuthenticationManager(introspectionClient); new OAuth2IntrospectionReactiveAuthenticationManager(introspectionClient);
@ -106,7 +106,7 @@ public class OAuth2IntrospectionReactiveAuthenticationManagerTests {
@Test @Test
public void authenticateWhenIntrospectionEndpointThrowsExceptionThenInvalidToken() { public void authenticateWhenIntrospectionEndpointThrowsExceptionThenInvalidToken() {
ReactiveOAuth2TokenIntrospectionClient introspectionClient = mock(ReactiveOAuth2TokenIntrospectionClient.class); ReactiveOpaqueTokenIntrospector introspectionClient = mock(ReactiveOpaqueTokenIntrospector.class);
when(introspectionClient.introspect(any())) when(introspectionClient.introspect(any()))
.thenReturn(Mono.error(new OAuth2IntrospectionException("with \"invalid\" chars"))); .thenReturn(Mono.error(new OAuth2IntrospectionException("with \"invalid\" chars")));
OAuth2IntrospectionReactiveAuthenticationManager provider = OAuth2IntrospectionReactiveAuthenticationManager provider =

View File

@ -38,10 +38,6 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.RequestEntity; import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.server.resource.introspection.NimbusOAuth2TokenIntrospectionClient;
import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames;
import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionException;
import org.springframework.security.oauth2.server.resource.introspection.OAuth2TokenIntrospectionClient;
import org.springframework.web.client.RestOperations; import org.springframework.web.client.RestOperations;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -61,9 +57,9 @@ import static org.springframework.security.oauth2.server.resource.introspection.
import static org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames.USERNAME; import static org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames.USERNAME;
/** /**
* Tests for {@link NimbusOAuth2TokenIntrospectionClient} * Tests for {@link NimbusOpaqueTokenIntrospector}
*/ */
public class NimbusOAuth2TokenIntrospectionClientTests { public class NimbusOpaqueTokenIntrospectorTests {
private static final String INTROSPECTION_URL = "https://server.example.com"; private static final String INTROSPECTION_URL = "https://server.example.com";
private static final String CLIENT_ID = "client"; private static final String CLIENT_ID = "client";
@ -114,8 +110,8 @@ public class NimbusOAuth2TokenIntrospectionClientTests {
server.setDispatcher(requiresAuth(CLIENT_ID, CLIENT_SECRET, ACTIVE_RESPONSE)); server.setDispatcher(requiresAuth(CLIENT_ID, CLIENT_SECRET, ACTIVE_RESPONSE));
String introspectUri = server.url("/introspect").toString(); String introspectUri = server.url("/introspect").toString();
OAuth2TokenIntrospectionClient introspectionClient = OpaqueTokenIntrospector introspectionClient =
new NimbusOAuth2TokenIntrospectionClient(introspectUri, CLIENT_ID, CLIENT_SECRET); new NimbusOpaqueTokenIntrospector(introspectUri, CLIENT_ID, CLIENT_SECRET);
Map<String, Object> attributes = introspectionClient.introspect("token"); Map<String, Object> attributes = introspectionClient.introspect("token");
assertThat(attributes) assertThat(attributes)
@ -138,8 +134,8 @@ public class NimbusOAuth2TokenIntrospectionClientTests {
server.setDispatcher(requiresAuth(CLIENT_ID, CLIENT_SECRET, ACTIVE_RESPONSE)); server.setDispatcher(requiresAuth(CLIENT_ID, CLIENT_SECRET, ACTIVE_RESPONSE));
String introspectUri = server.url("/introspect").toString(); String introspectUri = server.url("/introspect").toString();
OAuth2TokenIntrospectionClient introspectionClient = OpaqueTokenIntrospector introspectionClient =
new NimbusOAuth2TokenIntrospectionClient(introspectUri, CLIENT_ID, "wrong"); new NimbusOpaqueTokenIntrospector(introspectUri, CLIENT_ID, "wrong");
assertThatCode(() -> introspectionClient.introspect("token")) assertThatCode(() -> introspectionClient.introspect("token"))
.isInstanceOf(OAuth2IntrospectionException.class); .isInstanceOf(OAuth2IntrospectionException.class);
@ -149,7 +145,7 @@ public class NimbusOAuth2TokenIntrospectionClientTests {
@Test @Test
public void introspectWhenInactiveTokenThenInvalidToken() { public void introspectWhenInactiveTokenThenInvalidToken() {
RestOperations restOperations = mock(RestOperations.class); RestOperations restOperations = mock(RestOperations.class);
OAuth2TokenIntrospectionClient introspectionClient = new NimbusOAuth2TokenIntrospectionClient(INTROSPECTION_URL, restOperations); OpaqueTokenIntrospector introspectionClient = new NimbusOpaqueTokenIntrospector(INTROSPECTION_URL, restOperations);
when(restOperations.exchange(any(RequestEntity.class), eq(String.class))) when(restOperations.exchange(any(RequestEntity.class), eq(String.class)))
.thenReturn(INACTIVE); .thenReturn(INACTIVE);
@ -167,8 +163,8 @@ public class NimbusOAuth2TokenIntrospectionClientTests {
introspectedValues.put(NOT_BEFORE, 29348723984L); introspectedValues.put(NOT_BEFORE, 29348723984L);
RestOperations restOperations = mock(RestOperations.class); RestOperations restOperations = mock(RestOperations.class);
OAuth2TokenIntrospectionClient introspectionClient = OpaqueTokenIntrospector introspectionClient =
new NimbusOAuth2TokenIntrospectionClient(INTROSPECTION_URL, restOperations); new NimbusOpaqueTokenIntrospector(INTROSPECTION_URL, restOperations);
when(restOperations.exchange(any(RequestEntity.class), eq(String.class))) when(restOperations.exchange(any(RequestEntity.class), eq(String.class)))
.thenReturn(response(new JSONObject(introspectedValues).toJSONString())); .thenReturn(response(new JSONObject(introspectedValues).toJSONString()));
@ -185,8 +181,8 @@ public class NimbusOAuth2TokenIntrospectionClientTests {
@Test @Test
public void introspectWhenIntrospectionEndpointThrowsExceptionThenInvalidToken() { public void introspectWhenIntrospectionEndpointThrowsExceptionThenInvalidToken() {
RestOperations restOperations = mock(RestOperations.class); RestOperations restOperations = mock(RestOperations.class);
OAuth2TokenIntrospectionClient introspectionClient = OpaqueTokenIntrospector introspectionClient =
new NimbusOAuth2TokenIntrospectionClient(INTROSPECTION_URL, restOperations); new NimbusOpaqueTokenIntrospector(INTROSPECTION_URL, restOperations);
when(restOperations.exchange(any(RequestEntity.class), eq(String.class))) when(restOperations.exchange(any(RequestEntity.class), eq(String.class)))
.thenThrow(new IllegalStateException("server was unresponsive")); .thenThrow(new IllegalStateException("server was unresponsive"));
@ -200,8 +196,8 @@ public class NimbusOAuth2TokenIntrospectionClientTests {
@Test @Test
public void introspectWhenIntrospectionEndpointReturnsMalformedResponseThenInvalidToken() { public void introspectWhenIntrospectionEndpointReturnsMalformedResponseThenInvalidToken() {
RestOperations restOperations = mock(RestOperations.class); RestOperations restOperations = mock(RestOperations.class);
OAuth2TokenIntrospectionClient introspectionClient = OpaqueTokenIntrospector introspectionClient =
new NimbusOAuth2TokenIntrospectionClient(INTROSPECTION_URL, restOperations); new NimbusOpaqueTokenIntrospector(INTROSPECTION_URL, restOperations);
when(restOperations.exchange(any(RequestEntity.class), eq(String.class))) when(restOperations.exchange(any(RequestEntity.class), eq(String.class)))
.thenReturn(response("malformed")); .thenReturn(response("malformed"));
@ -212,8 +208,8 @@ public class NimbusOAuth2TokenIntrospectionClientTests {
@Test @Test
public void introspectWhenIntrospectionTokenReturnsInvalidResponseThenInvalidToken() { public void introspectWhenIntrospectionTokenReturnsInvalidResponseThenInvalidToken() {
RestOperations restOperations = mock(RestOperations.class); RestOperations restOperations = mock(RestOperations.class);
OAuth2TokenIntrospectionClient introspectionClient = OpaqueTokenIntrospector introspectionClient =
new NimbusOAuth2TokenIntrospectionClient(INTROSPECTION_URL, restOperations); new NimbusOpaqueTokenIntrospector(INTROSPECTION_URL, restOperations);
when(restOperations.exchange(any(RequestEntity.class), eq(String.class))) when(restOperations.exchange(any(RequestEntity.class), eq(String.class)))
.thenReturn(INVALID); .thenReturn(INVALID);
@ -224,8 +220,8 @@ public class NimbusOAuth2TokenIntrospectionClientTests {
@Test @Test
public void introspectWhenIntrospectionTokenReturnsMalformedIssuerResponseThenInvalidToken() { public void introspectWhenIntrospectionTokenReturnsMalformedIssuerResponseThenInvalidToken() {
RestOperations restOperations = mock(RestOperations.class); RestOperations restOperations = mock(RestOperations.class);
OAuth2TokenIntrospectionClient introspectionClient = OpaqueTokenIntrospector introspectionClient =
new NimbusOAuth2TokenIntrospectionClient(INTROSPECTION_URL, restOperations); new NimbusOpaqueTokenIntrospector(INTROSPECTION_URL, restOperations);
when(restOperations.exchange(any(RequestEntity.class), eq(String.class))) when(restOperations.exchange(any(RequestEntity.class), eq(String.class)))
.thenReturn(MALFORMED_ISSUER); .thenReturn(MALFORMED_ISSUER);
@ -235,25 +231,25 @@ public class NimbusOAuth2TokenIntrospectionClientTests {
@Test @Test
public void constructorWhenIntrospectionUriIsNullThenIllegalArgumentException() { public void constructorWhenIntrospectionUriIsNullThenIllegalArgumentException() {
assertThatCode(() -> new NimbusOAuth2TokenIntrospectionClient(null, CLIENT_ID, CLIENT_SECRET)) assertThatCode(() -> new NimbusOpaqueTokenIntrospector(null, CLIENT_ID, CLIENT_SECRET))
.isInstanceOf(IllegalArgumentException.class); .isInstanceOf(IllegalArgumentException.class);
} }
@Test @Test
public void constructorWhenClientIdIsNullThenIllegalArgumentException() { public void constructorWhenClientIdIsNullThenIllegalArgumentException() {
assertThatCode(() -> new NimbusOAuth2TokenIntrospectionClient(INTROSPECTION_URL, null, CLIENT_SECRET)) assertThatCode(() -> new NimbusOpaqueTokenIntrospector(INTROSPECTION_URL, null, CLIENT_SECRET))
.isInstanceOf(IllegalArgumentException.class); .isInstanceOf(IllegalArgumentException.class);
} }
@Test @Test
public void constructorWhenClientSecretIsNullThenIllegalArgumentException() { public void constructorWhenClientSecretIsNullThenIllegalArgumentException() {
assertThatCode(() -> new NimbusOAuth2TokenIntrospectionClient(INTROSPECTION_URL, CLIENT_ID, null)) assertThatCode(() -> new NimbusOpaqueTokenIntrospector(INTROSPECTION_URL, CLIENT_ID, null))
.isInstanceOf(IllegalArgumentException.class); .isInstanceOf(IllegalArgumentException.class);
} }
@Test @Test
public void constructorWhenRestOperationsIsNullThenIllegalArgumentException() { public void constructorWhenRestOperationsIsNullThenIllegalArgumentException() {
assertThatCode(() -> new NimbusOAuth2TokenIntrospectionClient(INTROSPECTION_URL, null)) assertThatCode(() -> new NimbusOpaqueTokenIntrospector(INTROSPECTION_URL, null))
.isInstanceOf(IllegalArgumentException.class); .isInstanceOf(IllegalArgumentException.class);
} }
@ -261,7 +257,7 @@ public class NimbusOAuth2TokenIntrospectionClientTests {
public void setRequestEntityConverterWhenConverterIsNullThenExceptionIsThrown() { public void setRequestEntityConverterWhenConverterIsNullThenExceptionIsThrown() {
RestOperations restOperations = mock(RestOperations.class); RestOperations restOperations = mock(RestOperations.class);
NimbusOAuth2TokenIntrospectionClient introspectionClient = new NimbusOAuth2TokenIntrospectionClient( NimbusOpaqueTokenIntrospector introspectionClient = new NimbusOpaqueTokenIntrospector(
INTROSPECTION_URL, restOperations INTROSPECTION_URL, restOperations
); );
@ -278,7 +274,7 @@ public class NimbusOAuth2TokenIntrospectionClientTests {
String tokenToIntrospect = "some token"; String tokenToIntrospect = "some token";
when(requestEntityConverter.convert(tokenToIntrospect)).thenReturn(requestEntity); when(requestEntityConverter.convert(tokenToIntrospect)).thenReturn(requestEntity);
when(restOperations.exchange(requestEntity, String.class)).thenReturn(ACTIVE); when(restOperations.exchange(requestEntity, String.class)).thenReturn(ACTIVE);
NimbusOAuth2TokenIntrospectionClient introspectionClient = new NimbusOAuth2TokenIntrospectionClient( NimbusOpaqueTokenIntrospector introspectionClient = new NimbusOpaqueTokenIntrospector(
INTROSPECTION_URL, restOperations INTROSPECTION_URL, restOperations
); );
introspectionClient.setRequestEntityConverter(requestEntityConverter); introspectionClient.setRequestEntityConverter(requestEntityConverter);

View File

@ -36,9 +36,6 @@ import reactor.core.publisher.Mono;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.security.oauth2.server.resource.introspection.NimbusReactiveOAuth2TokenIntrospectionClient;
import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames;
import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionException;
import org.springframework.web.reactive.function.client.ClientResponse; import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.WebClient;
@ -56,9 +53,9 @@ import static org.springframework.security.oauth2.server.resource.introspection.
import static org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames.USERNAME; import static org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionClaimNames.USERNAME;
/** /**
* Tests for {@link NimbusReactiveOAuth2TokenIntrospectionClient} * Tests for {@link NimbusReactiveOpaqueTokenIntrospector}
*/ */
public class NimbusReactiveOAuth2TokenIntrospectionClientTests { public class NimbusReactiveOpaqueTokenIntrospectorTests {
private static final String INTROSPECTION_URL = "https://server.example.com"; private static final String INTROSPECTION_URL = "https://server.example.com";
private static final String CLIENT_ID = "client"; private static final String CLIENT_ID = "client";
private static final String CLIENT_SECRET = "secret"; private static final String CLIENT_SECRET = "secret";
@ -103,8 +100,8 @@ public class NimbusReactiveOAuth2TokenIntrospectionClientTests {
server.setDispatcher(requiresAuth(CLIENT_ID, CLIENT_SECRET, ACTIVE_RESPONSE)); server.setDispatcher(requiresAuth(CLIENT_ID, CLIENT_SECRET, ACTIVE_RESPONSE));
String introspectUri = server.url("/introspect").toString(); String introspectUri = server.url("/introspect").toString();
NimbusReactiveOAuth2TokenIntrospectionClient introspectionClient = NimbusReactiveOpaqueTokenIntrospector introspectionClient =
new NimbusReactiveOAuth2TokenIntrospectionClient(introspectUri, CLIENT_ID, CLIENT_SECRET); new NimbusReactiveOpaqueTokenIntrospector(introspectUri, CLIENT_ID, CLIENT_SECRET);
Map<String, Object> attributes = introspectionClient.introspect("token").block(); Map<String, Object> attributes = introspectionClient.introspect("token").block();
assertThat(attributes) assertThat(attributes)
@ -127,8 +124,8 @@ public class NimbusReactiveOAuth2TokenIntrospectionClientTests {
server.setDispatcher(requiresAuth(CLIENT_ID, CLIENT_SECRET, ACTIVE_RESPONSE)); server.setDispatcher(requiresAuth(CLIENT_ID, CLIENT_SECRET, ACTIVE_RESPONSE));
String introspectUri = server.url("/introspect").toString(); String introspectUri = server.url("/introspect").toString();
NimbusReactiveOAuth2TokenIntrospectionClient introspectionClient = NimbusReactiveOpaqueTokenIntrospector introspectionClient =
new NimbusReactiveOAuth2TokenIntrospectionClient(introspectUri, CLIENT_ID, "wrong"); new NimbusReactiveOpaqueTokenIntrospector(introspectUri, CLIENT_ID, "wrong");
assertThatCode(() -> introspectionClient.introspect("token").block()) assertThatCode(() -> introspectionClient.introspect("token").block())
.isInstanceOf(OAuth2IntrospectionException.class); .isInstanceOf(OAuth2IntrospectionException.class);
@ -138,8 +135,8 @@ public class NimbusReactiveOAuth2TokenIntrospectionClientTests {
@Test @Test
public void authenticateWhenInactiveTokenThenInvalidToken() { public void authenticateWhenInactiveTokenThenInvalidToken() {
WebClient webClient = mockResponse(INACTIVE_RESPONSE); WebClient webClient = mockResponse(INACTIVE_RESPONSE);
NimbusReactiveOAuth2TokenIntrospectionClient introspectionClient = NimbusReactiveOpaqueTokenIntrospector introspectionClient =
new NimbusReactiveOAuth2TokenIntrospectionClient(INTROSPECTION_URL, webClient); new NimbusReactiveOpaqueTokenIntrospector(INTROSPECTION_URL, webClient);
assertThatCode(() -> introspectionClient.introspect("token").block()) assertThatCode(() -> introspectionClient.introspect("token").block())
.isInstanceOf(OAuth2IntrospectionException.class) .isInstanceOf(OAuth2IntrospectionException.class)
@ -155,8 +152,8 @@ public class NimbusReactiveOAuth2TokenIntrospectionClientTests {
introspectedValues.put(NOT_BEFORE, 29348723984L); introspectedValues.put(NOT_BEFORE, 29348723984L);
WebClient webClient = mockResponse(new JSONObject(introspectedValues).toJSONString()); WebClient webClient = mockResponse(new JSONObject(introspectedValues).toJSONString());
NimbusReactiveOAuth2TokenIntrospectionClient introspectionClient = NimbusReactiveOpaqueTokenIntrospector introspectionClient =
new NimbusReactiveOAuth2TokenIntrospectionClient(INTROSPECTION_URL, webClient); new NimbusReactiveOpaqueTokenIntrospector(INTROSPECTION_URL, webClient);
Map<String, Object> attributes = introspectionClient.introspect("token").block(); Map<String, Object> attributes = introspectionClient.introspect("token").block();
assertThat(attributes) assertThat(attributes)
@ -171,8 +168,8 @@ public class NimbusReactiveOAuth2TokenIntrospectionClientTests {
@Test @Test
public void authenticateWhenIntrospectionEndpointThrowsExceptionThenInvalidToken() { public void authenticateWhenIntrospectionEndpointThrowsExceptionThenInvalidToken() {
WebClient webClient = mockResponse(new IllegalStateException("server was unresponsive")); WebClient webClient = mockResponse(new IllegalStateException("server was unresponsive"));
NimbusReactiveOAuth2TokenIntrospectionClient introspectionClient = NimbusReactiveOpaqueTokenIntrospector introspectionClient =
new NimbusReactiveOAuth2TokenIntrospectionClient(INTROSPECTION_URL, webClient); new NimbusReactiveOpaqueTokenIntrospector(INTROSPECTION_URL, webClient);
assertThatCode(() -> introspectionClient.introspect("token").block()) assertThatCode(() -> introspectionClient.introspect("token").block())
.isInstanceOf(OAuth2IntrospectionException.class) .isInstanceOf(OAuth2IntrospectionException.class)
@ -183,8 +180,8 @@ public class NimbusReactiveOAuth2TokenIntrospectionClientTests {
@Test @Test
public void authenticateWhenIntrospectionEndpointReturnsMalformedResponseThenInvalidToken() { public void authenticateWhenIntrospectionEndpointReturnsMalformedResponseThenInvalidToken() {
WebClient webClient = mockResponse("malformed"); WebClient webClient = mockResponse("malformed");
NimbusReactiveOAuth2TokenIntrospectionClient introspectionClient = NimbusReactiveOpaqueTokenIntrospector introspectionClient =
new NimbusReactiveOAuth2TokenIntrospectionClient(INTROSPECTION_URL, webClient); new NimbusReactiveOpaqueTokenIntrospector(INTROSPECTION_URL, webClient);
assertThatCode(() -> introspectionClient.introspect("token").block()) assertThatCode(() -> introspectionClient.introspect("token").block())
.isInstanceOf(OAuth2IntrospectionException.class); .isInstanceOf(OAuth2IntrospectionException.class);
@ -193,8 +190,8 @@ public class NimbusReactiveOAuth2TokenIntrospectionClientTests {
@Test @Test
public void authenticateWhenIntrospectionTokenReturnsInvalidResponseThenInvalidToken() { public void authenticateWhenIntrospectionTokenReturnsInvalidResponseThenInvalidToken() {
WebClient webClient = mockResponse(INVALID_RESPONSE); WebClient webClient = mockResponse(INVALID_RESPONSE);
NimbusReactiveOAuth2TokenIntrospectionClient introspectionClient = NimbusReactiveOpaqueTokenIntrospector introspectionClient =
new NimbusReactiveOAuth2TokenIntrospectionClient(INTROSPECTION_URL, webClient); new NimbusReactiveOpaqueTokenIntrospector(INTROSPECTION_URL, webClient);
assertThatCode(() -> introspectionClient.introspect("token").block()) assertThatCode(() -> introspectionClient.introspect("token").block())
.isInstanceOf(OAuth2IntrospectionException.class); .isInstanceOf(OAuth2IntrospectionException.class);
@ -203,8 +200,8 @@ public class NimbusReactiveOAuth2TokenIntrospectionClientTests {
@Test @Test
public void authenticateWhenIntrospectionTokenReturnsMalformedIssuerResponseThenInvalidToken() { public void authenticateWhenIntrospectionTokenReturnsMalformedIssuerResponseThenInvalidToken() {
WebClient webClient = mockResponse(MALFORMED_ISSUER_RESPONSE); WebClient webClient = mockResponse(MALFORMED_ISSUER_RESPONSE);
NimbusReactiveOAuth2TokenIntrospectionClient introspectionClient = NimbusReactiveOpaqueTokenIntrospector introspectionClient =
new NimbusReactiveOAuth2TokenIntrospectionClient(INTROSPECTION_URL, webClient); new NimbusReactiveOpaqueTokenIntrospector(INTROSPECTION_URL, webClient);
assertThatCode(() -> introspectionClient.introspect("token").block()) assertThatCode(() -> introspectionClient.introspect("token").block())
.isInstanceOf(OAuth2IntrospectionException.class); .isInstanceOf(OAuth2IntrospectionException.class);
@ -212,25 +209,25 @@ public class NimbusReactiveOAuth2TokenIntrospectionClientTests {
@Test @Test
public void constructorWhenIntrospectionUriIsEmptyThenIllegalArgumentException() { public void constructorWhenIntrospectionUriIsEmptyThenIllegalArgumentException() {
assertThatCode(() -> new NimbusReactiveOAuth2TokenIntrospectionClient("", CLIENT_ID, CLIENT_SECRET)) assertThatCode(() -> new NimbusReactiveOpaqueTokenIntrospector("", CLIENT_ID, CLIENT_SECRET))
.isInstanceOf(IllegalArgumentException.class); .isInstanceOf(IllegalArgumentException.class);
} }
@Test @Test
public void constructorWhenClientIdIsEmptyThenIllegalArgumentException() { public void constructorWhenClientIdIsEmptyThenIllegalArgumentException() {
assertThatCode(() -> new NimbusReactiveOAuth2TokenIntrospectionClient(INTROSPECTION_URL, "", CLIENT_SECRET)) assertThatCode(() -> new NimbusReactiveOpaqueTokenIntrospector(INTROSPECTION_URL, "", CLIENT_SECRET))
.isInstanceOf(IllegalArgumentException.class); .isInstanceOf(IllegalArgumentException.class);
} }
@Test @Test
public void constructorWhenClientSecretIsNullThenIllegalArgumentException() { public void constructorWhenClientSecretIsNullThenIllegalArgumentException() {
assertThatCode(() -> new NimbusReactiveOAuth2TokenIntrospectionClient(INTROSPECTION_URL, CLIENT_ID, null)) assertThatCode(() -> new NimbusReactiveOpaqueTokenIntrospector(INTROSPECTION_URL, CLIENT_ID, null))
.isInstanceOf(IllegalArgumentException.class); .isInstanceOf(IllegalArgumentException.class);
} }
@Test @Test
public void constructorWhenRestOperationsIsNullThenIllegalArgumentException() { public void constructorWhenRestOperationsIsNullThenIllegalArgumentException() {
assertThatCode(() -> new NimbusReactiveOAuth2TokenIntrospectionClient(INTROSPECTION_URL, null)) assertThatCode(() -> new NimbusReactiveOpaqueTokenIntrospector(INTROSPECTION_URL, null))
.isInstanceOf(IllegalArgumentException.class); .isInstanceOf(IllegalArgumentException.class);
} }

View File

@ -30,8 +30,8 @@ import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationProvider; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationProvider;
import org.springframework.security.oauth2.server.resource.authentication.OAuth2IntrospectionAuthenticationProvider; import org.springframework.security.oauth2.server.resource.authentication.OAuth2IntrospectionAuthenticationProvider;
import org.springframework.security.oauth2.server.resource.introspection.NimbusOAuth2TokenIntrospectionClient; import org.springframework.security.oauth2.server.resource.introspection.NimbusOpaqueTokenIntrospector;
import org.springframework.security.oauth2.server.resource.introspection.OAuth2TokenIntrospectionClient; import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector;
import static org.springframework.security.web.authentication.MultiTenantAuthenticationManagerResolver.resolveFromPath; import static org.springframework.security.web.authentication.MultiTenantAuthenticationManagerResolver.resolveFromPath;
@ -77,8 +77,8 @@ public class OAuth2ResourceServerSecurityConfiguration extends WebSecurityConfig
} }
AuthenticationManager opaque() { AuthenticationManager opaque() {
OAuth2TokenIntrospectionClient introspectionClient = OpaqueTokenIntrospector introspectionClient =
new NimbusOAuth2TokenIntrospectionClient(this.introspectionUri, "client", "secret"); new NimbusOpaqueTokenIntrospector(this.introspectionUri, "client", "secret");
return new OAuth2IntrospectionAuthenticationProvider(introspectionClient)::authenticate; return new OAuth2IntrospectionAuthenticationProvider(introspectionClient)::authenticate;
} }
} }