Fix mock for Spring(Reactive)OpaqueTokenIntrospector

Signed-off-by: Tran Ngoc Nhan <ngocnhan.tran1996@gmail.com>
This commit is contained in:
Tran Ngoc Nhan 2025-06-25 03:34:22 +07:00
parent 198b195427
commit 2d83821cc2
2 changed files with 100 additions and 58 deletions

View File

@ -39,6 +39,7 @@ import com.nimbusds.jose.Payload;
import com.nimbusds.jose.crypto.RSASSASigner;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.RSAKey;
import com.nimbusds.jose.util.JSONObjectUtils;
import jakarta.annotation.PreDestroy;
import jakarta.servlet.http.HttpServletRequest;
import net.minidev.json.JSONObject;
@ -62,6 +63,7 @@ import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
@ -217,7 +219,7 @@ public class OAuth2ResourceServerConfigurerTests {
@Test
public void getWhenUsingDefaultsWithValidBearerTokenThenAcceptsRequest() throws Exception {
this.spring.register(RestOperationsConfig.class, DefaultConfig.class, BasicController.class).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ValidNoScopes");
// @formatter:off
this.mvc.perform(get("/").with(bearerToken(token)))
@ -232,7 +234,7 @@ public class OAuth2ResourceServerConfigurerTests {
.register(RestOperationsConfig.class, DefaultConfig.class, BasicController.class,
SecurityContextChangedListenerConfig.class)
.autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ValidNoScopes");
// @formatter:off
this.mvc.perform(get("/").with(bearerToken(token)))
@ -248,7 +250,7 @@ public class OAuth2ResourceServerConfigurerTests {
.register(RestOperationsConfig.class, DefaultConfig.class, SecurityContextChangedListenerConfig.class,
BasicController.class)
.autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ValidNoScopes");
// @formatter:off
this.mvc.perform(get("/").with(bearerToken(token)))
@ -261,7 +263,7 @@ public class OAuth2ResourceServerConfigurerTests {
@Test
public void getWhenUsingDefaultsInLambdaWithValidBearerTokenThenAcceptsRequest() throws Exception {
this.spring.register(RestOperationsConfig.class, DefaultInLambdaConfig.class, BasicController.class).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ValidNoScopes");
// @formatter:off
this.mvc.perform(get("/").with(bearerToken(token)))
@ -297,7 +299,7 @@ public class OAuth2ResourceServerConfigurerTests {
@Test
public void getWhenUsingDefaultsWithExpiredBearerTokenThenInvalidToken() throws Exception {
this.spring.register(RestOperationsConfig.class, DefaultConfig.class, BasicController.class).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("Expired");
// @formatter:off
this.mvc.perform(get("/").with(bearerToken(token)))
@ -341,7 +343,7 @@ public class OAuth2ResourceServerConfigurerTests {
@Test
public void getWhenUsingDefaultsWithMalformedPayloadThenInvalidToken() throws Exception {
this.spring.register(RestOperationsConfig.class, DefaultConfig.class).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("MalformedPayload");
// @formatter:off
this.mvc.perform(get("/").with(bearerToken(token)))
@ -364,7 +366,7 @@ public class OAuth2ResourceServerConfigurerTests {
@Test
public void getWhenUsingDefaultsWithBearerTokenBeforeNotBeforeThenInvalidToken() throws Exception {
this.spring.register(RestOperationsConfig.class, DefaultConfig.class).autowire();
this.mockRestOperations(jwks("Default"));
this.mockJwksRestOperations(jwks("Default"));
String token = this.token("TooEarly");
// @formatter:off
this.mvc.perform(get("/").with(bearerToken(token)))
@ -421,7 +423,7 @@ public class OAuth2ResourceServerConfigurerTests {
@Test
public void getWhenAnonymousDisabledThenAllows() throws Exception {
this.spring.register(RestOperationsConfig.class, AnonymousDisabledConfig.class).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = token("ValidNoScopes");
// @formatter:off
this.mvc.perform(get("/authenticated").with(bearerToken(token)))
@ -442,7 +444,7 @@ public class OAuth2ResourceServerConfigurerTests {
@Test
public void getWhenUsingDefaultsWithSufficientlyScopedBearerTokenThenAcceptsRequest() throws Exception {
this.spring.register(RestOperationsConfig.class, DefaultConfig.class, BasicController.class).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ValidMessageReadScope");
// @formatter:off
this.mvc.perform(get("/requires-read-scope").with(bearerToken(token)))
@ -454,7 +456,7 @@ public class OAuth2ResourceServerConfigurerTests {
@Test
public void getWhenUsingDefaultsWithInsufficientScopeThenInsufficientScopeError() throws Exception {
this.spring.register(RestOperationsConfig.class, DefaultConfig.class, BasicController.class).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ValidNoScopes");
// @formatter:off
this.mvc.perform(get("/requires-read-scope").with(bearerToken(token)))
@ -466,7 +468,7 @@ public class OAuth2ResourceServerConfigurerTests {
@Test
public void getWhenUsingDefaultsWithInsufficientScpThenInsufficientScopeError() throws Exception {
this.spring.register(RestOperationsConfig.class, DefaultConfig.class, BasicController.class).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ValidMessageWriteScp");
// @formatter:off
this.mvc.perform(get("/requires-read-scope").with(bearerToken(token)))
@ -478,7 +480,7 @@ public class OAuth2ResourceServerConfigurerTests {
@Test
public void getWhenUsingDefaultsAndAuthorizationServerHasNoMatchingKeyThenInvalidToken() throws Exception {
this.spring.register(RestOperationsConfig.class, DefaultConfig.class).autowire();
mockRestOperations(jwks("Empty"));
mockJwksRestOperations(jwks("Empty"));
String token = this.token("ValidNoScopes");
// @formatter:off
this.mvc.perform(get("/").with(bearerToken(token)))
@ -490,7 +492,7 @@ public class OAuth2ResourceServerConfigurerTests {
@Test
public void getWhenUsingDefaultsAndAuthorizationServerHasMultipleMatchingKeysThenOk() throws Exception {
this.spring.register(RestOperationsConfig.class, DefaultConfig.class, BasicController.class).autowire();
mockRestOperations(jwks("TwoKeys"));
mockJwksRestOperations(jwks("TwoKeys"));
String token = this.token("ValidNoScopes");
// @formatter:off
this.mvc.perform(get("/authenticated").with(bearerToken(token)))
@ -502,7 +504,7 @@ public class OAuth2ResourceServerConfigurerTests {
@Test
public void getWhenUsingDefaultsAndKeyMatchesByKidThenOk() throws Exception {
this.spring.register(RestOperationsConfig.class, DefaultConfig.class, BasicController.class).autowire();
mockRestOperations(jwks("TwoKeys"));
mockJwksRestOperations(jwks("TwoKeys"));
String token = this.token("Kid");
// @formatter:off
this.mvc.perform(get("/authenticated").with(bearerToken(token)))
@ -514,7 +516,7 @@ public class OAuth2ResourceServerConfigurerTests {
@Test
public void getWhenUsingMethodSecurityWithValidBearerTokenThenAcceptsRequest() throws Exception {
this.spring.register(RestOperationsConfig.class, MethodSecurityConfig.class, BasicController.class).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ValidMessageReadScope");
// @formatter:off
this.mvc.perform(get("/ms-requires-read-scope").with(bearerToken(token)))
@ -526,7 +528,7 @@ public class OAuth2ResourceServerConfigurerTests {
@Test
public void getWhenUsingMethodSecurityWithValidBearerTokenHavingScpAttributeThenAcceptsRequest() throws Exception {
this.spring.register(RestOperationsConfig.class, MethodSecurityConfig.class, BasicController.class).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ValidMessageReadScp");
// @formatter:off
this.mvc.perform(get("/ms-requires-read-scope").with(bearerToken(token)))
@ -538,7 +540,7 @@ public class OAuth2ResourceServerConfigurerTests {
@Test
public void getWhenUsingMethodSecurityWithInsufficientScopeThenInsufficientScopeError() throws Exception {
this.spring.register(RestOperationsConfig.class, MethodSecurityConfig.class, BasicController.class).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ValidNoScopes");
// @formatter:off
this.mvc.perform(get("/ms-requires-read-scope").with(bearerToken(token)))
@ -550,7 +552,7 @@ public class OAuth2ResourceServerConfigurerTests {
@Test
public void getWhenUsingMethodSecurityWithInsufficientScpThenInsufficientScopeError() throws Exception {
this.spring.register(RestOperationsConfig.class, MethodSecurityConfig.class, BasicController.class).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ValidMessageWriteScp");
// @formatter:off
this.mvc.perform(get("/ms-requires-read-scope").with(bearerToken(token)))
@ -562,7 +564,7 @@ public class OAuth2ResourceServerConfigurerTests {
@Test
public void getWhenUsingMethodSecurityWithDenyAllThenInsufficientScopeError() throws Exception {
this.spring.register(RestOperationsConfig.class, MethodSecurityConfig.class, BasicController.class).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ValidMessageReadScope");
// @formatter:off
this.mvc.perform(get("/ms-deny").with(bearerToken(token)))
@ -574,7 +576,7 @@ public class OAuth2ResourceServerConfigurerTests {
@Test
public void postWhenUsingDefaultsWithValidBearerTokenAndNoCsrfTokenThenOk() throws Exception {
this.spring.register(RestOperationsConfig.class, DefaultConfig.class, BasicController.class).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ValidNoScopes");
// @formatter:off
this.mvc.perform(post("/authenticated").header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE).with(bearerToken(token)))
@ -596,7 +598,7 @@ public class OAuth2ResourceServerConfigurerTests {
@Test
public void postWhenUsingDefaultsWithExpiredBearerTokenAndNoCsrfThenInvalidToken() throws Exception {
this.spring.register(RestOperationsConfig.class, DefaultConfig.class).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("Expired");
// @formatter:off
this.mvc.perform(post("/authenticated").header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE).with(bearerToken(token)))
@ -608,7 +610,7 @@ public class OAuth2ResourceServerConfigurerTests {
@Test
public void requestWhenDefaultConfiguredThenSessionIsNotCreated() throws Exception {
this.spring.register(RestOperationsConfig.class, DefaultConfig.class, BasicController.class).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ValidNoScopes");
// @formatter:off
MvcResult result = this.mvc.perform(get("/").with(bearerToken(token)))
@ -621,7 +623,7 @@ public class OAuth2ResourceServerConfigurerTests {
@Test
public void requestWhenIntrospectionConfiguredThenSessionIsNotCreated() throws Exception {
this.spring.register(RestOperationsConfig.class, OpaqueTokenConfig.class, BasicController.class).autowire();
mockRestOperations(json("Active"));
mockJsonRestOperations(json("Active"));
// @formatter:off
MvcResult result = this.mvc.perform(get("/authenticated").with(bearerToken("token")))
.andExpect(status().isOk())
@ -646,7 +648,7 @@ public class OAuth2ResourceServerConfigurerTests {
public void requestWhenSessionManagementConfiguredThenUserConfigurationOverrides() throws Exception {
this.spring.register(RestOperationsConfig.class, AlwaysSessionCreationConfig.class, BasicController.class)
.autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ValidNoScopes");
// @formatter:off
MvcResult result = this.mvc.perform(get("/").with(bearerToken(token)))
@ -917,7 +919,7 @@ public class OAuth2ResourceServerConfigurerTests {
@Test
public void requestWhenCustomJwtValidatorFailsThenCorrespondingErrorMessage() throws Exception {
this.spring.register(RestOperationsConfig.class, CustomJwtValidatorConfig.class).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ValidNoScopes");
OAuth2TokenValidator<Jwt> jwtValidator = this.spring.getContext()
.getBean(CustomJwtValidatorConfig.class)
@ -935,7 +937,7 @@ public class OAuth2ResourceServerConfigurerTests {
public void requestWhenClockSkewSetThenTimestampWindowRelaxedAccordingly() throws Exception {
this.spring.register(RestOperationsConfig.class, UnexpiredJwtClockSkewConfig.class, BasicController.class)
.autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ExpiresAt4687177990");
// @formatter:off
this.mvc.perform(get("/").with(bearerToken(token)))
@ -947,7 +949,7 @@ public class OAuth2ResourceServerConfigurerTests {
public void requestWhenClockSkewSetButJwtStillTooLateThenReportsExpired() throws Exception {
this.spring.register(RestOperationsConfig.class, ExpiredJwtClockSkewConfig.class, BasicController.class)
.autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ExpiresAt4687177990");
// @formatter:off
this.mvc.perform(get("/").with(bearerToken(token)))
@ -1061,7 +1063,7 @@ public class OAuth2ResourceServerConfigurerTests {
@Test
public void getWhenIntrospectingThenOk() throws Exception {
this.spring.register(RestOperationsConfig.class, OpaqueTokenConfig.class, BasicController.class).autowire();
mockRestOperations(json("Active"));
mockJsonRestOperations(json("Active"));
// @formatter:off
this.mvc.perform(get("/authenticated").with(bearerToken("token")))
.andExpect(status().isOk())
@ -1073,7 +1075,7 @@ public class OAuth2ResourceServerConfigurerTests {
public void getWhenOpaqueTokenInLambdaAndIntrospectingThenOk() throws Exception {
this.spring.register(RestOperationsConfig.class, OpaqueTokenInLambdaConfig.class, BasicController.class)
.autowire();
mockRestOperations(json("Active"));
mockJsonRestOperations(json("Active"));
// @formatter:off
this.mvc.perform(get("/authenticated").with(bearerToken("token")))
.andExpect(status().isOk())
@ -1084,7 +1086,7 @@ public class OAuth2ResourceServerConfigurerTests {
@Test
public void getWhenIntrospectionFailsThenUnauthorized() throws Exception {
this.spring.register(RestOperationsConfig.class, OpaqueTokenConfig.class).autowire();
mockRestOperations(json("Inactive"));
mockJsonRestOperations(json("Inactive"));
// @formatter:off
this.mvc.perform(get("/").with(bearerToken("token")))
.andExpect(status().isUnauthorized())
@ -1095,7 +1097,7 @@ public class OAuth2ResourceServerConfigurerTests {
@Test
public void getWhenIntrospectionLacksScopeThenForbidden() throws Exception {
this.spring.register(RestOperationsConfig.class, OpaqueTokenConfig.class).autowire();
mockRestOperations(json("ActiveNoScopes"));
mockJsonRestOperations(json("ActiveNoScopes"));
// @formatter:off
this.mvc.perform(get("/requires-read-scope").with(bearerToken("token")))
.andExpect(status().isForbidden())
@ -1252,7 +1254,7 @@ public class OAuth2ResourceServerConfigurerTests {
public void getWhenAlsoUsingHttpBasicThenCorrectProviderEngages() throws Exception {
this.spring.register(RestOperationsConfig.class, BasicAndResourceServerConfig.class, BasicController.class)
.autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ValidNoScopes");
// @formatter:off
this.mvc.perform(get("/authenticated").with(bearerToken(token)))
@ -1408,7 +1410,7 @@ public class OAuth2ResourceServerConfigurerTests {
OpaqueTokenAuthenticationConverter authenticationConverter = bean(OpaqueTokenAuthenticationConverter.class);
given(authenticationConverter.convert(anyString(), any(OAuth2AuthenticatedPrincipal.class)))
.willReturn(new TestingAuthenticationToken("jdoe", null, Collections.emptyList()));
mockRestOperations(json("Active"));
mockJsonRestOperations(json("Active"));
// @formatter:off
this.mvc.perform(get("/authenticated").with(bearerToken("token")))
.andExpect(status().isOk())
@ -1515,6 +1517,29 @@ public class OAuth2ResourceServerConfigurerTests {
given(rest.exchange(any(RequestEntity.class), eq(String.class))).willReturn(entity);
}
private void mockJwksRestOperations(String response) {
RestOperations rest = this.spring.getContext().getBean(RestOperations.class);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
ResponseEntity<String> entity = new ResponseEntity<>(response, headers, HttpStatus.OK);
given(rest.exchange(any(RequestEntity.class), eq(String.class))).willReturn(entity);
}
private void mockJsonRestOperations(String response) {
try {
RestOperations rest = this.spring.getContext().getBean(RestOperations.class);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
ResponseEntity<Map<String, Object>> entity = new ResponseEntity<>(JSONObjectUtils.parse(response), headers,
HttpStatus.OK);
given(rest.exchange(any(RequestEntity.class), eq(new ParameterizedTypeReference<Map<String, Object>>() {
}))).willReturn(entity);
}
catch (Exception ex) {
throw new IllegalArgumentException(ex);
}
}
private <T> T bean(Class<T> beanClass) {
return this.spring.getContext().getBean(beanClass);
}

View File

@ -36,6 +36,7 @@ import com.nimbusds.jose.Payload;
import com.nimbusds.jose.crypto.RSASSASigner;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.RSAKey;
import com.nimbusds.jose.util.JSONObjectUtils;
import jakarta.servlet.http.HttpServletRequest;
import net.minidev.json.JSONObject;
import okhttp3.mockwebserver.MockResponse;
@ -57,6 +58,7 @@ import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.beans.factory.xml.XmlReaderContext;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpHeaders;
@ -139,7 +141,7 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
@Test
public void getWhenValidBearerTokenThenAcceptsRequest() throws Exception {
this.spring.configLocations(xml("JwtRestOperations"), xml("Jwt")).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ValidNoScopes");
// @formatter:off
this.mvc.perform(get("/").header("Authorization", "Bearer " + token))
@ -150,7 +152,7 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
@Test
public void getWhenCustomSecurityContextHolderStrategyThenUses() throws Exception {
this.spring.configLocations(xml("JwtRestOperations"), xml("JwtCustomSecurityContextHolderStrategy")).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ValidNoScopes");
// @formatter:off
this.mvc.perform(get("/").header("Authorization", "Bearer " + token))
@ -175,7 +177,7 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
@Test
public void getWhenExpiredBearerTokenThenInvalidToken() throws Exception {
this.spring.configLocations(xml("JwtRestOperations"), xml("Jwt")).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("Expired");
// @formatter:off
this.mvc.perform(get("/").header("Authorization", "Bearer " + token))
@ -187,7 +189,7 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
@Test
public void getWhenBadJwkEndpointThen500() throws Exception {
this.spring.configLocations(xml("JwtRestOperations"), xml("Jwt")).autowire();
mockRestOperations("malformed");
mockJwksRestOperations("malformed");
String token = this.token("ValidNoScopes");
// @formatter:off
assertThatExceptionOfType(AuthenticationServiceException.class)
@ -219,7 +221,7 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
@Test
public void getWhenMalformedPayloadThenInvalidToken() throws Exception {
this.spring.configLocations(xml("JwtRestOperations"), xml("Jwt")).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("MalformedPayload");
// @formatter:off
this.mvc.perform(get("/").header("Authorization", "Bearer " + token))
@ -242,7 +244,7 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
@Test
public void getWhenBearerTokenBeforeNotBeforeThenInvalidToken() throws Exception {
this.spring.configLocations(xml("JwtRestOperations"), xml("Jwt")).autowire();
this.mockRestOperations(jwks("Default"));
this.mockJwksRestOperations(jwks("Default"));
String token = this.token("TooEarly");
// @formatter:off
this.mvc.perform(get("/").header("Authorization", "Bearer " + token))
@ -299,7 +301,7 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
@Test
public void getWhenSufficientlyScopedBearerTokenThenAcceptsRequest() throws Exception {
this.spring.configLocations(xml("JwtRestOperations"), xml("Jwt")).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ValidMessageReadScope");
// @formatter:off
this.mvc.perform(get("/requires-read-scope").header("Authorization", "Bearer " + token))
@ -310,7 +312,7 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
@Test
public void getWhenInsufficientScopeThenInsufficientScopeError() throws Exception {
this.spring.configLocations(xml("JwtRestOperations"), xml("Jwt")).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ValidNoScopes");
// @formatter:off
this.mvc.perform(get("/requires-read-scope").header("Authorization", "Bearer " + token))
@ -322,7 +324,7 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
@Test
public void getWhenInsufficientScpThenInsufficientScopeError() throws Exception {
this.spring.configLocations(xml("JwtRestOperations"), xml("Jwt")).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ValidMessageWriteScp");
// @formatter:off
this.mvc.perform(get("/requires-read-scope").header("Authorization", "Bearer " + token))
@ -334,7 +336,7 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
@Test
public void getWhenAuthorizationServerHasNoMatchingKeyThenInvalidToken() throws Exception {
this.spring.configLocations(xml("JwtRestOperations"), xml("Jwt")).autowire();
mockRestOperations(jwks("Empty"));
mockJwksRestOperations(jwks("Empty"));
String token = this.token("ValidNoScopes");
// @formatter:off
this.mvc.perform(get("/").header("Authorization", "Bearer " + token))
@ -346,7 +348,7 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
@Test
public void getWhenAuthorizationServerHasMultipleMatchingKeysThenOk() throws Exception {
this.spring.configLocations(xml("JwtRestOperations"), xml("Jwt")).autowire();
mockRestOperations(jwks("TwoKeys"));
mockJwksRestOperations(jwks("TwoKeys"));
String token = this.token("ValidNoScopes");
// @formatter:off
this.mvc.perform(get("/authenticated").header("Authorization", "Bearer " + token))
@ -357,7 +359,7 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
@Test
public void getWhenKeyMatchesByKidThenOk() throws Exception {
this.spring.configLocations(xml("JwtRestOperations"), xml("Jwt")).autowire();
mockRestOperations(jwks("TwoKeys"));
mockJwksRestOperations(jwks("TwoKeys"));
String token = this.token("Kid");
// @formatter:off
this.mvc.perform(get("/authenticated").header("Authorization", "Bearer " + token))
@ -368,7 +370,7 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
@Test
public void postWhenValidBearerTokenAndNoCsrfTokenThenOk() throws Exception {
this.spring.configLocations(xml("JwtRestOperations"), xml("Jwt")).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ValidNoScopes");
// @formatter:off
this.mvc.perform(post("/authenticated").header("Authorization", "Bearer " + token))
@ -390,7 +392,7 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
@Test
public void postWhenExpiredBearerTokenAndNoCsrfThenInvalidToken() throws Exception {
this.spring.configLocations(xml("JwtRestOperations"), xml("Jwt")).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("Expired");
// @formatter:off
this.mvc.perform(post("/authenticated").header("Authorization", "Bearer " + token))
@ -402,7 +404,7 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
@Test
public void requestWhenJwtThenSessionIsNotCreated() throws Exception {
this.spring.configLocations(xml("JwtRestOperations"), xml("Jwt")).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ValidNoScopes");
// @formatter:off
MvcResult result = this.mvc.perform(get("/").header("Authorization", "Bearer " + token))
@ -438,7 +440,7 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
@Test
public void requestWhenSessionManagementConfiguredThenUses() throws Exception {
this.spring.configLocations(xml("JwtRestOperations"), xml("AlwaysSessionCreation")).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ValidNoScopes");
// @formatter:off
MvcResult result = this.mvc.perform(get("/").header("Authorization", "Bearer " + token))
@ -587,7 +589,7 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
@Test
public void requestWhenCustomJwtValidatorFailsThenCorrespondingErrorMessage() throws Exception {
this.spring.configLocations(xml("MockJwtValidator"), xml("Jwt")).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ValidNoScopes");
OAuth2TokenValidator<Jwt> jwtValidator = this.spring.getContext().getBean(OAuth2TokenValidator.class);
OAuth2Error error = new OAuth2Error("custom-error", "custom-description", "custom-uri");
@ -602,7 +604,7 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
@Test
public void requestWhenClockSkewSetThenTimestampWindowRelaxedAccordingly() throws Exception {
this.spring.configLocations(xml("UnexpiredJwtClockSkew"), xml("Jwt")).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ExpiresAt4687177990");
// @formatter:off
this.mvc.perform(get("/").header("Authorization", "Bearer " + token))
@ -613,7 +615,7 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
@Test
public void requestWhenClockSkewSetButJwtStillTooLateThenReportsExpired() throws Exception {
this.spring.configLocations(xml("ExpiredJwtClockSkew"), xml("Jwt")).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ExpiresAt4687177990");
// @formatter:off
this.mvc.perform(get("/").header("Authorization", "Bearer " + token))
@ -675,7 +677,7 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
@Test
public void getWhenIntrospectingThenOk() throws Exception {
this.spring.configLocations(xml("OpaqueTokenRestOperations"), xml("OpaqueToken")).autowire();
mockRestOperations(json("Active"));
mockJsonRestOperations(json("Active"));
// @formatter:off
this.mvc.perform(get("/authenticated").header("Authorization", "Bearer token"))
.andExpect(status().isNotFound());
@ -686,7 +688,7 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
public void configureWhenIntrospectingWithAuthenticationConverterThenUses() throws Exception {
this.spring.configLocations(xml("OpaqueTokenRestOperations"), xml("OpaqueTokenAndAuthenticationConverter"))
.autowire();
mockRestOperations(json("Active"));
mockJsonRestOperations(json("Active"));
OpaqueTokenAuthenticationConverter converter = bean(OpaqueTokenAuthenticationConverter.class);
given(converter.convert(any(), any())).willReturn(new TestingAuthenticationToken("user", "pass", "app"));
// @formatter:off
@ -699,7 +701,7 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
@Test
public void getWhenIntrospectionFailsThenUnauthorized() throws Exception {
this.spring.configLocations(xml("OpaqueTokenRestOperations"), xml("OpaqueToken")).autowire();
mockRestOperations(json("Inactive"));
mockJsonRestOperations(json("Inactive"));
// @formatter:off
MockHttpServletRequestBuilder request = get("/")
.header("Authorization", "Bearer token");
@ -712,7 +714,7 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
@Test
public void getWhenIntrospectionLacksScopeThenForbidden() throws Exception {
this.spring.configLocations(xml("OpaqueTokenRestOperations"), xml("OpaqueToken")).autowire();
mockRestOperations(json("ActiveNoScopes"));
mockJsonRestOperations(json("ActiveNoScopes"));
// @formatter:off
this.mvc.perform(get("/requires-read-scope").header("Authorization", "Bearer token"))
.andExpect(status().isForbidden())
@ -818,7 +820,7 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
@Test
public void getWhenAlsoUsingHttpBasicThenCorrectProviderEngages() throws Exception {
this.spring.configLocations(xml("JwtRestOperations"), xml("BasicAndResourceServer")).autowire();
mockRestOperations(jwks("Default"));
mockJwksRestOperations(jwks("Default"));
String token = this.token("ValidNoScopes");
// @formatter:off
this.mvc.perform(get("/authenticated").header("Authorization", "Bearer " + token))
@ -963,7 +965,7 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
.setBody(response));
}
private void mockRestOperations(String response) {
private void mockJwksRestOperations(String response) {
RestOperations rest = this.spring.getContext().getBean(RestOperations.class);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
@ -971,6 +973,21 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
given(rest.exchange(any(RequestEntity.class), eq(String.class))).willReturn(entity);
}
private void mockJsonRestOperations(String response) {
try {
RestOperations rest = this.spring.getContext().getBean(RestOperations.class);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
ResponseEntity<Map<String, Object>> entity = new ResponseEntity<>(JSONObjectUtils.parse(response), headers,
HttpStatus.OK);
given(rest.exchange(any(RequestEntity.class), eq(new ParameterizedTypeReference<Map<String, Object>>() {
}))).willReturn(entity);
}
catch (Exception ex) {
throw new IllegalArgumentException(ex);
}
}
private String json(String name) throws IOException {
return resource(name + ".json");
}