Bläddra i källkod

Use Jwt.Builder

Fixes gh-7443
Josh Cummings 6 år sedan
förälder
incheckning
05caf3d8fb
25 ändrade filer med 247 tillägg och 389 borttagningar
  1. 12 15
      config/src/test/java/org/springframework/security/config/annotation/rsocket/JwtITests.java
  2. 11 10
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2LoginConfigurerTests.java
  3. 3 4
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/OAuth2ResourceServerConfigurerTests.java
  4. 11 13
      config/src/test/java/org/springframework/security/config/web/server/OAuth2LoginTests.java
  5. 2 6
      config/src/test/java/org/springframework/security/config/web/server/OAuth2ResourceServerSpecTests.java
  6. 1 0
      oauth2/oauth2-client/spring-security-oauth2-client.gradle
  7. 15 20
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/authentication/OidcAuthorizationCodeAuthenticationProviderTests.java
  8. 16 20
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/authentication/OidcAuthorizationCodeReactiveAuthenticationManagerTests.java
  9. 15 9
      oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/authentication/OidcIdTokenValidatorTests.java
  10. 1 0
      oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/Jwt.java
  11. 4 8
      oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/NimbusJwtDecoder.java
  12. 4 4
      oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/NimbusReactiveJwtDecoder.java
  13. 5 35
      oauth2/oauth2-jose/src/test/java/org/springframework/security/oauth2/jwt/JwtIssuerValidatorTests.java
  14. 22 69
      oauth2/oauth2-jose/src/test/java/org/springframework/security/oauth2/jwt/JwtTimestampValidatorTests.java
  15. 40 0
      oauth2/oauth2-jose/src/test/java/org/springframework/security/oauth2/jwt/TestJwts.java
  16. 1 0
      oauth2/oauth2-resource-server/spring-security-oauth2-resource-server.gradle
  17. 6 17
      oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtAuthenticationConverterTests.java
  18. 4 17
      oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtAuthenticationProviderTests.java
  19. 32 49
      oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtGrantedAuthoritiesConverterTests.java
  20. 4 11
      oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtReactiveAuthenticationManagerTests.java
  21. 13 24
      oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/ReactiveJwtAuthenticationConverterAdapterTests.java
  22. 6 18
      oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/ReactiveJwtAuthenticationConverterTests.java
  23. 5 16
      oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/ReactiveJwtGrantedAuthoritiesConverterAdapterTests.java
  24. 7 11
      test/src/test/java/org/springframework/security/test/web/reactive/server/SecurityMockServerConfigurersJwtTests.java
  25. 7 13
      test/src/test/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessorsJwtTests.java

+ 12 - 15
config/src/test/java/org/springframework/security/config/annotation/rsocket/JwtITests.java

@@ -15,6 +15,10 @@
  */
 package org.springframework.security.config.annotation.rsocket;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
 import io.rsocket.RSocketFactory;
 import io.rsocket.frame.decoder.PayloadDecoder;
 import io.rsocket.transport.netty.server.CloseableChannel;
@@ -23,6 +27,8 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import reactor.core.publisher.Mono;
+
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -34,6 +40,7 @@ import org.springframework.security.config.Customizer;
 import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames;
 import org.springframework.security.oauth2.jwt.Jwt;
 import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
+import org.springframework.security.oauth2.jwt.TestJwts;
 import org.springframework.security.rsocket.core.PayloadSocketAcceptorInterceptor;
 import org.springframework.security.rsocket.core.SecuritySocketAcceptorInterceptor;
 import org.springframework.security.rsocket.metadata.BasicAuthenticationEncoder;
@@ -41,14 +48,6 @@ import org.springframework.security.rsocket.metadata.BearerTokenMetadata;
 import org.springframework.stereotype.Controller;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringRunner;
-import reactor.core.publisher.Mono;
-
-import java.time.Instant;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Matchers.any;
@@ -114,13 +113,11 @@ public class JwtITests {
 	}
 
 	private Jwt jwt() {
-		Map<String, Object> claims = new HashMap<>();
-		claims.put(IdTokenClaimNames.ISS, "https://issuer.example.com");
-		claims.put(IdTokenClaimNames.SUB, "rob");
-		claims.put(IdTokenClaimNames.AUD, Arrays.asList("client-id"));
-		Instant issuedAt = Instant.now();
-		Instant expiresAt = Instant.from(issuedAt).plusSeconds(3600);
-		return new Jwt("token", issuedAt, expiresAt, claims, claims);
+		return TestJwts.jwt()
+				.claim(IdTokenClaimNames.ISS, "https://issuer.example.com")
+				.claim(IdTokenClaimNames.SUB, "rob")
+				.claim(IdTokenClaimNames.AUD, Arrays.asList("client-id"))
+				.build();
 	}
 
 	private RSocketRequester.Builder requester() {

+ 11 - 10
config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2LoginConfigurerTests.java

@@ -15,11 +15,20 @@
  */
 package org.springframework.security.config.annotation.web.configurers.oauth2.client;
 
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 import org.apache.http.HttpHeaders;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
+
 import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationListener;
@@ -79,19 +88,12 @@ import org.springframework.security.web.context.SecurityContextRepository;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
 
-import java.time.Instant;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
+import static org.springframework.security.oauth2.jwt.TestJwts.jwt;
 import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.authentication;
 import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
@@ -937,8 +939,7 @@ public class OAuth2LoginConfigurerTests {
 			claims.put(IdTokenClaimNames.ISS, "http://localhost/iss");
 			claims.put(IdTokenClaimNames.AUD, Arrays.asList("clientId", "a", "u", "d"));
 			claims.put(IdTokenClaimNames.AZP, "clientId");
-			Jwt jwt = new Jwt("token123", Instant.now(), Instant.now().plusSeconds(3600),
-					Collections.singletonMap("header1", "value1"), claims);
+			Jwt jwt = jwt().claims(c -> c.putAll(claims)).build();
 			JwtDecoder jwtDecoder = mock(JwtDecoder.class);
 			when(jwtDecoder.decode(any())).thenReturn(jwt);
 			return jwtDecoder;

+ 3 - 4
config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/OAuth2ResourceServerConfigurerTests.java

@@ -83,16 +83,15 @@ import org.springframework.security.oauth2.core.DefaultOAuth2AuthenticatedPrinci
 import org.springframework.security.oauth2.core.OAuth2Error;
 import org.springframework.security.oauth2.core.OAuth2TokenValidator;
 import org.springframework.security.oauth2.core.OAuth2TokenValidatorResult;
-import org.springframework.security.oauth2.jose.jws.JwsAlgorithms;
 import org.springframework.security.oauth2.jwt.Jwt;
 import org.springframework.security.oauth2.jwt.JwtClaimNames;
 import org.springframework.security.oauth2.jwt.JwtDecoder;
 import org.springframework.security.oauth2.jwt.JwtException;
 import org.springframework.security.oauth2.jwt.JwtTimestampValidator;
 import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
+import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthentication;
 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.BearerTokenAuthentication;
 import org.springframework.security.oauth2.server.resource.introspection.NimbusOpaqueTokenIntrospector;
 import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector;
 import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationEntryPoint;
@@ -131,6 +130,7 @@ import static org.springframework.security.config.Customizer.withDefaults;
 import static org.springframework.security.oauth2.core.TestOAuth2AccessTokens.noScopes;
 import static org.springframework.security.oauth2.jwt.NimbusJwtDecoder.withJwkSetUri;
 import static org.springframework.security.oauth2.jwt.NimbusJwtDecoder.withPublicKey;
+import static org.springframework.security.oauth2.jwt.TestJwts.jwt;
 import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
 import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic;
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@@ -150,9 +150,8 @@ import static org.springframework.web.bind.annotation.RequestMethod.POST;
 public class OAuth2ResourceServerConfigurerTests {
 	private static final String JWT_TOKEN = "token";
 	private static final String JWT_SUBJECT = "mock-test-subject";
-	private static final Map<String, Object> JWT_HEADERS = Collections.singletonMap("alg", JwsAlgorithms.RS256);
 	private static final Map<String, Object> JWT_CLAIMS = Collections.singletonMap(JwtClaimNames.SUB, JWT_SUBJECT);
-	private static final Jwt JWT = new Jwt(JWT_TOKEN, Instant.MIN, Instant.MAX, JWT_HEADERS, JWT_CLAIMS);
+	private static final Jwt JWT = jwt().build();
 	private static final String JWK_SET_URI = "https://mock.org";
 	private static final JwtAuthenticationToken JWT_AUTHENTICATION_TOKEN =
 			new JwtAuthenticationToken(JWT, Collections.emptyList());

+ 11 - 13
config/src/test/java/org/springframework/security/config/web/server/OAuth2LoginTests.java

@@ -16,7 +16,6 @@
 
 package org.springframework.security.config.web.server;
 
-import java.time.Instant;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
@@ -25,15 +24,6 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.mockito.stubbing.Answer;
 import org.openqa.selenium.WebDriver;
-
-import org.springframework.security.core.AuthenticationException;
-import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
-import org.springframework.security.oauth2.core.OAuth2Error;
-import org.springframework.security.web.server.WebFilterExchange;
-import org.springframework.security.web.server.authentication.RedirectServerAuthenticationFailureHandler;
-import org.springframework.security.web.server.authentication.RedirectServerAuthenticationSuccessHandler;
-import org.springframework.security.web.server.authentication.ServerAuthenticationFailureHandler;
-import org.springframework.security.web.server.authentication.ServerAuthenticationSuccessHandler;
 import reactor.core.publisher.Mono;
 
 import org.springframework.beans.factory.annotation.Autowired;
@@ -46,6 +36,7 @@ import org.springframework.security.config.annotation.web.reactive.EnableWebFlux
 import org.springframework.security.config.oauth2.client.CommonOAuth2Provider;
 import org.springframework.security.config.test.SpringTestRule;
 import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
 import org.springframework.security.core.authority.AuthorityUtils;
 import org.springframework.security.core.context.SecurityContext;
 import org.springframework.security.core.context.SecurityContextImpl;
@@ -56,14 +47,16 @@ import org.springframework.security.oauth2.client.authentication.OAuth2LoginAuth
 import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest;
 import org.springframework.security.oauth2.client.endpoint.ReactiveOAuth2AccessTokenResponseClient;
 import org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeReactiveAuthenticationManager;
-import org.springframework.security.oauth2.client.oidc.web.server.logout.OidcClientInitiatedServerLogoutSuccessHandler;
 import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest;
+import org.springframework.security.oauth2.client.oidc.web.server.logout.OidcClientInitiatedServerLogoutSuccessHandler;
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
 import org.springframework.security.oauth2.client.registration.InMemoryReactiveClientRegistrationRepository;
 import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
 import org.springframework.security.oauth2.client.userinfo.ReactiveOAuth2UserService;
 import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizationRequestResolver;
 import org.springframework.security.oauth2.core.OAuth2AccessToken;
+import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
+import org.springframework.security.oauth2.core.OAuth2Error;
 import org.springframework.security.oauth2.core.TestOAuth2AccessTokens;
 import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
 import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationExchange;
@@ -84,7 +77,12 @@ import org.springframework.security.oauth2.jwt.ReactiveJwtDecoderFactory;
 import org.springframework.security.test.web.reactive.server.WebTestClientBuilder;
 import org.springframework.security.web.server.SecurityWebFilterChain;
 import org.springframework.security.web.server.WebFilterChainProxy;
+import org.springframework.security.web.server.WebFilterExchange;
+import org.springframework.security.web.server.authentication.RedirectServerAuthenticationFailureHandler;
+import org.springframework.security.web.server.authentication.RedirectServerAuthenticationSuccessHandler;
 import org.springframework.security.web.server.authentication.ServerAuthenticationConverter;
+import org.springframework.security.web.server.authentication.ServerAuthenticationFailureHandler;
+import org.springframework.security.web.server.authentication.ServerAuthenticationSuccessHandler;
 import org.springframework.security.web.server.context.ServerSecurityContextRepository;
 import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher;
 import org.springframework.test.web.reactive.server.WebTestClient;
@@ -100,6 +98,7 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
+import static org.springframework.security.oauth2.jwt.TestJwts.jwt;
 
 /**
  * @author Rob Winch
@@ -514,8 +513,7 @@ public class OAuth2LoginTests {
 					claims.put(IdTokenClaimNames.ISS, "http://localhost/issuer");
 					claims.put(IdTokenClaimNames.AUD, Collections.singletonList("client"));
 					claims.put(IdTokenClaimNames.AZP, "client");
-					Jwt jwt = new Jwt("id-token", Instant.now(), Instant.now().plusSeconds(3600),
-							Collections.singletonMap("header1", "value1"), claims);
+					Jwt jwt = jwt().claims(c -> c.putAll(claims)).build();
 					return Mono.just(jwt);
 				};
 			}

+ 2 - 6
config/src/test/java/org/springframework/security/config/web/server/OAuth2ResourceServerSpecTests.java

@@ -23,9 +23,7 @@ import java.security.NoSuchAlgorithmException;
 import java.security.interfaces.RSAPublicKey;
 import java.security.spec.InvalidKeySpecException;
 import java.security.spec.RSAPublicKeySpec;
-import java.time.Instant;
 import java.util.Base64;
-import java.util.Collections;
 import java.util.Optional;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
@@ -61,7 +59,6 @@ import org.springframework.security.core.Authentication;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
 import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
 import org.springframework.security.oauth2.core.OAuth2Error;
-import org.springframework.security.oauth2.jose.jws.JwsAlgorithms;
 import org.springframework.security.oauth2.jwt.Jwt;
 import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
 import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
@@ -88,6 +85,7 @@ import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
+import static org.springframework.security.oauth2.jwt.TestJwts.jwt;
 
 /**
  * Tests for {@link org.springframework.security.config.web.server.ServerHttpSecurity.OAuth2ResourceServerSpec}
@@ -114,9 +112,7 @@ public class OAuth2ResourceServerSpecTests {
 			"  ]\n" +
 			"}\n";
 
-	private Jwt jwt = new Jwt("token", Instant.MIN, Instant.MAX,
-			Collections.singletonMap("alg", JwsAlgorithms.RS256),
-			Collections.singletonMap("sub", "user"));
+	private Jwt jwt = jwt().build();
 
 	private String clientId = "client";
 	private String clientSecret = "secret";

+ 1 - 0
oauth2/oauth2-client/spring-security-oauth2-client.gradle

@@ -12,6 +12,7 @@ dependencies {
 	optional 'org.springframework:spring-webflux'
 
 	testCompile project(path: ':spring-security-oauth2-core', configuration: 'tests')
+	testCompile project(path: ':spring-security-oauth2-jose', configuration: 'tests')
 	testCompile powerMock2Dependencies
 	testCompile 'com.squareup.okhttp3:mockwebserver'
 	testCompile 'com.fasterxml.jackson.core:jackson-databind'

+ 15 - 20
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/authentication/OidcAuthorizationCodeAuthenticationProviderTests.java

@@ -15,12 +15,22 @@
  */
 package org.springframework.security.oauth2.client.oidc.authentication;
 
+import java.time.Instant;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.mockito.ArgumentCaptor;
 import org.mockito.stubbing.Answer;
+
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.authority.AuthorityUtils;
 import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
@@ -44,24 +54,18 @@ import org.springframework.security.oauth2.jwt.Jwt;
 import org.springframework.security.oauth2.jwt.JwtDecoder;
 import org.springframework.security.oauth2.jwt.JwtException;
 
-import java.time.Instant;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.hamcrest.CoreMatchers.containsString;
-import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyCollection;
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 import static org.springframework.security.oauth2.client.registration.TestClientRegistrations.clientRegistration;
 import static org.springframework.security.oauth2.core.endpoint.TestOAuth2AuthorizationRequests.request;
 import static org.springframework.security.oauth2.core.endpoint.TestOAuth2AuthorizationResponses.error;
 import static org.springframework.security.oauth2.core.endpoint.TestOAuth2AuthorizationResponses.success;
+import static org.springframework.security.oauth2.jwt.TestJwts.jwt;
 
 /**
  * Tests for {@link OidcAuthorizationCodeAuthenticationProvider}.
@@ -299,16 +303,7 @@ public class OidcAuthorizationCodeAuthenticationProviderTests {
 	}
 
 	private void setUpIdToken(Map<String, Object> claims) {
-		Instant issuedAt = Instant.now();
-		Instant expiresAt = Instant.from(issuedAt).plusSeconds(3600);
-		this.setUpIdToken(claims, issuedAt, expiresAt);
-	}
-
-	private void setUpIdToken(Map<String, Object> claims, Instant issuedAt, Instant expiresAt) {
-		Map<String, Object> headers = new HashMap<>();
-		headers.put("alg", "RS256");
-
-		Jwt idToken = new Jwt("id-token", issuedAt, expiresAt, headers, claims);
+		Jwt idToken = jwt().claims(c -> c.putAll(claims)).build();
 
 		JwtDecoder jwtDecoder = mock(JwtDecoder.class);
 		when(jwtDecoder.decode(anyString())).thenReturn(idToken);

+ 16 - 20
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/authentication/OidcAuthorizationCodeReactiveAuthenticationManagerTests.java

@@ -16,12 +16,20 @@
 
 package org.springframework.security.oauth2.client.oidc.authentication;
 
+import java.time.Instant;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnitRunner;
+import reactor.core.publisher.Mono;
+
 import org.springframework.security.authentication.TestingAuthenticationToken;
 import org.springframework.security.core.authority.AuthorityUtils;
 import org.springframework.security.oauth2.client.authentication.OAuth2AuthorizationCodeAuthenticationToken;
@@ -46,17 +54,13 @@ import org.springframework.security.oauth2.core.oidc.user.OidcUser;
 import org.springframework.security.oauth2.jwt.Jwt;
 import org.springframework.security.oauth2.jwt.JwtException;
 import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
-import reactor.core.publisher.Mono;
-
-import java.time.Instant;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
 
-import static org.assertj.core.api.Assertions.*;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.when;
+import static org.springframework.security.oauth2.jwt.TestJwts.jwt;
 
 /**
  * @author Rob Winch
@@ -171,9 +175,7 @@ public class OidcAuthorizationCodeReactiveAuthenticationManagerTests {
 		claims.put(IdTokenClaimNames.ISS, "https://issuer.example.com");
 		claims.put(IdTokenClaimNames.SUB, "rob");
 		claims.put(IdTokenClaimNames.AUD, Arrays.asList("client-id"));
-		Instant issuedAt = Instant.now();
-		Instant expiresAt = Instant.from(issuedAt).plusSeconds(3600);
-		Jwt idToken = new Jwt("id-token", issuedAt, expiresAt, claims, claims);
+		Jwt idToken = jwt().claims(c -> c.putAll(claims)).build();
 
 		when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(Mono.just(accessTokenResponse));
 		when(this.userService.loadUser(any())).thenReturn(Mono.empty());
@@ -193,9 +195,7 @@ public class OidcAuthorizationCodeReactiveAuthenticationManagerTests {
 		claims.put(IdTokenClaimNames.ISS, "https://issuer.example.com");
 		claims.put(IdTokenClaimNames.SUB, "rob");
 		claims.put(IdTokenClaimNames.AUD, Arrays.asList("client-id"));
-		Instant issuedAt = Instant.now();
-		Instant expiresAt = Instant.from(issuedAt).plusSeconds(3600);
-		Jwt idToken = new Jwt("id-token", issuedAt, expiresAt, claims, claims);
+		Jwt idToken = jwt().claims(c -> c.putAll(claims)).build();
 
 		when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(Mono.just(accessTokenResponse));
 		DefaultOidcUser user = new DefaultOidcUser(AuthorityUtils.createAuthorityList("ROLE_USER"), this.idToken);
@@ -222,9 +222,7 @@ public class OidcAuthorizationCodeReactiveAuthenticationManagerTests {
 		claims.put(IdTokenClaimNames.ISS, "https://issuer.example.com");
 		claims.put(IdTokenClaimNames.SUB, "rob");
 		claims.put(IdTokenClaimNames.AUD, Arrays.asList("client-id"));
-		Instant issuedAt = Instant.now();
-		Instant expiresAt = Instant.from(issuedAt).plusSeconds(3600);
-		Jwt idToken = new Jwt("id-token", issuedAt, expiresAt, claims, claims);
+		Jwt idToken = jwt().claims(c -> c.putAll(claims)).build();
 
 		when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(Mono.just(accessTokenResponse));
 		DefaultOidcUser user = new DefaultOidcUser(AuthorityUtils.createAuthorityList("ROLE_USER"), this.idToken);
@@ -257,9 +255,7 @@ public class OidcAuthorizationCodeReactiveAuthenticationManagerTests {
 		claims.put(IdTokenClaimNames.ISS, "https://issuer.example.com");
 		claims.put(IdTokenClaimNames.SUB, "rob");
 		claims.put(IdTokenClaimNames.AUD, Arrays.asList(clientRegistration.getClientId()));
-		Instant issuedAt = Instant.now();
-		Instant expiresAt = Instant.from(issuedAt).plusSeconds(3600);
-		Jwt idToken = new Jwt("id-token", issuedAt, expiresAt, claims, claims);
+		Jwt idToken = jwt().claims(c -> c.putAll(claims)).build();
 
 		when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(Mono.just(accessTokenResponse));
 		DefaultOidcUser user = new DefaultOidcUser(AuthorityUtils.createAuthorityList("ROLE_USER"), this.idToken);

+ 15 - 9
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/authentication/OidcIdTokenValidatorTests.java

@@ -15,8 +15,17 @@
  */
 package org.springframework.security.oauth2.client.oidc.authentication;
 
+import java.time.Duration;
+import java.time.Instant;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
 import org.junit.Before;
 import org.junit.Test;
+
 import org.springframework.security.oauth2.client.registration.ClientRegistration;
 import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
 import org.springframework.security.oauth2.core.OAuth2Error;
@@ -24,14 +33,6 @@ import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames;
 import org.springframework.security.oauth2.jose.jws.JwsAlgorithms;
 import org.springframework.security.oauth2.jwt.Jwt;
 
-import java.time.Duration;
-import java.time.Instant;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
@@ -240,7 +241,12 @@ public class OidcIdTokenValidatorTests {
 	}
 
 	private Collection<OAuth2Error> validateIdToken() {
-		Jwt idToken = new Jwt("token123", this.issuedAt, this.expiresAt, this.headers, this.claims);
+		Jwt idToken = Jwt.withTokenValue("token")
+			.issuedAt(this.issuedAt)
+			.expiresAt(this.expiresAt)
+			.headers(h -> h.putAll(this.headers))
+			.claims(c -> c.putAll(this.claims))
+			.build();
 		OidcIdTokenValidator validator = new OidcIdTokenValidator(this.registration.build());
 		validator.setClockSkew(this.clockSkew);
 		return validator.validate(idToken).getErrors();

+ 1 - 0
oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/Jwt.java

@@ -62,6 +62,7 @@ public class Jwt extends AbstractOAuth2Token implements JwtClaimAccessor {
 	 * @param expiresAt the expiration time on or after which the JWT MUST NOT be accepted
 	 * @param headers the JOSE header(s)
 	 * @param claims the JWT Claims Set
+	 *
 	 */
 	public Jwt(String tokenValue, Instant issuedAt, Instant expiresAt,
 				Map<String, Object> headers, Map<String, Object> claims) {

+ 4 - 8
oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/NimbusJwtDecoder.java

@@ -21,7 +21,6 @@ import java.net.MalformedURLException;
 import java.net.URL;
 import java.security.interfaces.RSAPublicKey;
 import java.text.ParseException;
-import java.time.Instant;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
@@ -136,8 +135,6 @@ public final class NimbusJwtDecoder implements JwtDecoder {
 	}
 
 	private Jwt createJwt(String token, JWT parsedJwt) {
-		Jwt jwt;
-
 		try {
 			// Verify the signature
 			JWTClaimsSet jwtClaimsSet = this.jwtProcessor.process(parsedJwt, null);
@@ -145,9 +142,10 @@ public final class NimbusJwtDecoder implements JwtDecoder {
 			Map<String, Object> headers = new LinkedHashMap<>(parsedJwt.getHeader().toJSONObject());
 			Map<String, Object> claims = this.claimSetConverter.convert(jwtClaimsSet.getClaims());
 
-			Instant expiresAt = (Instant) claims.get(JwtClaimNames.EXP);
-			Instant issuedAt = (Instant) claims.get(JwtClaimNames.IAT);
-			jwt = new Jwt(token, issuedAt, expiresAt, headers, claims);
+			return Jwt.withTokenValue(token)
+					.headers(h -> h.putAll(headers))
+					.claims(c -> c.putAll(claims))
+					.build();
 		} catch (RemoteKeySourceException ex) {
 			if (ex.getCause() instanceof ParseException) {
 				throw new JwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, "Malformed Jwk set"));
@@ -161,8 +159,6 @@ public final class NimbusJwtDecoder implements JwtDecoder {
 				throw new JwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, ex.getMessage()), ex);
 			}
 		}
-
-		return jwt;
 	}
 
 	private Jwt validateJwt(Jwt jwt){

+ 4 - 4
oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/NimbusReactiveJwtDecoder.java

@@ -16,7 +16,6 @@
 package org.springframework.security.oauth2.jwt;
 
 import java.security.interfaces.RSAPublicKey;
-import java.time.Instant;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -165,9 +164,10 @@ public final class NimbusReactiveJwtDecoder implements ReactiveJwtDecoder {
 		Map<String, Object> headers = new LinkedHashMap<>(parsedJwt.getHeader().toJSONObject());
 		Map<String, Object> claims = this.claimSetConverter.convert(jwtClaimsSet.getClaims());
 
-		Instant expiresAt = (Instant) claims.get(JwtClaimNames.EXP);
-		Instant issuedAt = (Instant) claims.get(JwtClaimNames.IAT);
-		return new Jwt(parsedJwt.getParsedString(), issuedAt, expiresAt, headers, claims);
+		return Jwt.withTokenValue(parsedJwt.getParsedString())
+				.headers(h -> h.putAll(headers))
+				.claims(c -> c.putAll(claims))
+				.build();
 	}
 
 	private Jwt validateJwt(Jwt jwt) {

+ 5 - 35
oauth2/oauth2-jose/src/test/java/org/springframework/security/oauth2/jwt/JwtIssuerValidatorTests.java

@@ -15,41 +15,26 @@
  */
 package org.springframework.security.oauth2.jwt;
 
-import java.time.Instant;
-import java.util.Collections;
-import java.util.Map;
-
 import org.junit.Test;
 
 import org.springframework.security.oauth2.core.OAuth2TokenValidatorResult;
-import org.springframework.security.oauth2.jose.jws.JwsAlgorithms;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.springframework.security.oauth2.jwt.TestJwts.jwt;
 
 /**
  * @author Josh Cummings
  * @since 5.1
  */
 public class JwtIssuerValidatorTests {
-	private static final String MOCK_TOKEN = "token";
-	private static final Instant MOCK_ISSUED_AT = Instant.MIN;
-	private static final Instant MOCK_EXPIRES_AT = Instant.MAX;
-	private static final Map<String, Object> MOCK_HEADERS =
-			Collections.singletonMap("alg", JwsAlgorithms.RS256);
-
 	private static final String ISSUER = "https://issuer";
 
 	private final JwtIssuerValidator validator = new JwtIssuerValidator(ISSUER);
 
 	@Test
 	public void validateWhenIssuerMatchesThenReturnsSuccess() {
-		Jwt jwt = new Jwt(
-				MOCK_TOKEN,
-				MOCK_ISSUED_AT,
-				MOCK_EXPIRES_AT,
-				MOCK_HEADERS,
-				Collections.singletonMap("iss", ISSUER));
+		Jwt jwt = jwt().claim("iss", ISSUER).build();
 
 		assertThat(this.validator.validate(jwt))
 				.isEqualTo(OAuth2TokenValidatorResult.success());
@@ -57,12 +42,7 @@ public class JwtIssuerValidatorTests {
 
 	@Test
 	public void validateWhenIssuerMismatchesThenReturnsError() {
-		Jwt jwt = new Jwt(
-				MOCK_TOKEN,
-				MOCK_ISSUED_AT,
-				MOCK_EXPIRES_AT,
-				MOCK_HEADERS,
-				Collections.singletonMap(JwtClaimNames.ISS, "https://other"));
+		Jwt jwt = jwt().claim(JwtClaimNames.ISS, "https://other").build();
 
 		OAuth2TokenValidatorResult result = this.validator.validate(jwt);
 
@@ -71,12 +51,7 @@ public class JwtIssuerValidatorTests {
 
 	@Test
 	public void validateWhenJwtHasNoIssuerThenReturnsError() {
-		Jwt jwt = new Jwt(
-				MOCK_TOKEN,
-				MOCK_ISSUED_AT,
-				MOCK_EXPIRES_AT,
-				MOCK_HEADERS,
-				Collections.singletonMap(JwtClaimNames.AUD, "https://aud"));
+		Jwt jwt = jwt().claim(JwtClaimNames.AUD, "https://aud").build();
 
 		OAuth2TokenValidatorResult result = this.validator.validate(jwt);
 		assertThat(result.getErrors()).isNotEmpty();
@@ -85,12 +60,7 @@ public class JwtIssuerValidatorTests {
 	// gh-6073
 	@Test
 	public void validateWhenIssuerMatchesAndIsNotAUriThenReturnsSuccess() {
-		Jwt jwt = new Jwt(
-				MOCK_TOKEN,
-				MOCK_ISSUED_AT,
-				MOCK_EXPIRES_AT,
-				MOCK_HEADERS,
-				Collections.singletonMap(JwtClaimNames.ISS, "issuer"));
+		Jwt jwt = jwt().claim(JwtClaimNames.ISS, "issuer").build();
 		JwtIssuerValidator validator = new JwtIssuerValidator("issuer");
 
 		assertThat(validator.validate(jwt))

+ 22 - 69
oauth2/oauth2-jose/src/test/java/org/springframework/security/oauth2/jwt/JwtTimestampValidatorTests.java

@@ -29,12 +29,11 @@ import org.junit.Test;
 import org.springframework.security.oauth2.core.OAuth2Error;
 import org.springframework.security.oauth2.core.OAuth2TokenValidatorResult;
 import org.springframework.security.oauth2.jose.jws.JwsAlgorithms;
-import org.springframework.security.oauth2.jwt.Jwt;
-import org.springframework.security.oauth2.jwt.JwtClaimNames;
-import org.springframework.security.oauth2.jwt.JwtTimestampValidator;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.springframework.security.oauth2.jwt.JwtClaimNames.EXP;
+import static org.springframework.security.oauth2.jwt.TestJwts.jwt;
 
 /**
  * Tests verifying {@link JwtTimestampValidator}
@@ -52,12 +51,7 @@ public class JwtTimestampValidatorTests {
 	public void validateWhenJwtIsExpiredThenErrorMessageIndicatesExpirationTime() {
 		Instant oneHourAgo = Instant.now().minusSeconds(3600);
 
-		Jwt jwt = new Jwt(
-				MOCK_TOKEN_VALUE,
-				MOCK_ISSUED_AT,
-				oneHourAgo,
-				MOCK_HEADER,
-				MOCK_CLAIM_SET);
+		Jwt jwt = jwt().expiresAt(oneHourAgo).build();
 
 		JwtTimestampValidator jwtValidator = new JwtTimestampValidator();
 
@@ -71,12 +65,7 @@ public class JwtTimestampValidatorTests {
 	public void validateWhenJwtIsTooEarlyThenErrorMessageIndicatesNotBeforeTime() {
 		Instant oneHourFromNow = Instant.now().plusSeconds(3600);
 
-		Jwt jwt = new Jwt(
-				MOCK_TOKEN_VALUE,
-				MOCK_ISSUED_AT,
-				null,
-				MOCK_HEADER,
-				Collections.singletonMap(JwtClaimNames.NBF, oneHourFromNow));
+		Jwt jwt = jwt().notBefore(oneHourFromNow).build();
 
 		JwtTimestampValidator jwtValidator = new JwtTimestampValidator();
 
@@ -97,21 +86,14 @@ public class JwtTimestampValidatorTests {
 		Instant justOverOneDayAgo = now.minus(oneDayOff).minusSeconds(10);
 		Instant justOverOneDayFromNow = now.plus(oneDayOff).plusSeconds(10);
 
-		Jwt jwt = new Jwt(
-				MOCK_TOKEN_VALUE,
-				MOCK_ISSUED_AT,
-				almostOneDayAgo,
-				MOCK_HEADER,
-				Collections.singletonMap(JwtClaimNames.NBF, almostOneDayFromNow));
+		Jwt jwt = jwt()
+				.expiresAt(almostOneDayAgo)
+				.notBefore(almostOneDayFromNow)
+				.build();
 
 		assertThat(jwtValidator.validate(jwt).hasErrors()).isFalse();
 
-		jwt = new Jwt(
-				MOCK_TOKEN_VALUE,
-				MOCK_ISSUED_AT,
-				justOverOneDayAgo,
-				MOCK_HEADER,
-				MOCK_CLAIM_SET);
+		jwt = jwt().expiresAt(justOverOneDayAgo).build();
 
 		OAuth2TokenValidatorResult result = jwtValidator.validate(jwt);
 		Collection<String> messages =
@@ -120,12 +102,7 @@ public class JwtTimestampValidatorTests {
 		assertThat(result.hasErrors()).isTrue();
 		assertThat(messages).contains("Jwt expired at " + justOverOneDayAgo);
 
-		jwt = new Jwt(
-				MOCK_TOKEN_VALUE,
-				MOCK_ISSUED_AT,
-				null,
-				MOCK_HEADER,
-				Collections.singletonMap(JwtClaimNames.NBF, justOverOneDayFromNow));
+		jwt = jwt().notBefore(justOverOneDayFromNow).build();
 
 		result = jwtValidator.validate(jwt);
 		messages =
@@ -138,36 +115,21 @@ public class JwtTimestampValidatorTests {
 
 	@Test
 	public void validateWhenConfiguredWithFixedClockThenValidatesUsingFixedTime() {
-		Jwt jwt = new Jwt(
-				MOCK_TOKEN_VALUE,
-				MOCK_ISSUED_AT,
-				Instant.now(MOCK_NOW),
-				MOCK_HEADER,
-				Collections.singletonMap("some", "claim"));
+		Jwt jwt = jwt().expiresAt(Instant.now(MOCK_NOW)).build();
 
 		JwtTimestampValidator jwtValidator = new JwtTimestampValidator(Duration.ofNanos(0));
 		jwtValidator.setClock(MOCK_NOW);
 
 		assertThat(jwtValidator.validate(jwt).hasErrors()).isFalse();
 
-		jwt = new Jwt(
-				MOCK_TOKEN_VALUE,
-				MOCK_ISSUED_AT,
-				null,
-				MOCK_HEADER,
-				Collections.singletonMap(JwtClaimNames.NBF, Instant.now(MOCK_NOW)));
+		jwt = jwt().notBefore(Instant.now(MOCK_NOW)).build();
 
 		assertThat(jwtValidator.validate(jwt).hasErrors()).isFalse();
 	}
 
 	@Test
 	public void validateWhenNeitherExpiryNorNotBeforeIsSpecifiedThenReturnsSuccessfulResult() {
-		Jwt jwt = new Jwt(
-				MOCK_TOKEN_VALUE,
-				MOCK_ISSUED_AT,
-				null,
-				MOCK_HEADER,
-				MOCK_CLAIM_SET);
+		Jwt jwt = jwt().claims(c -> c.remove(EXP)).build();
 
 		JwtTimestampValidator jwtValidator = new JwtTimestampValidator();
 		assertThat(jwtValidator.validate(jwt).hasErrors()).isFalse();
@@ -175,12 +137,10 @@ public class JwtTimestampValidatorTests {
 
 	@Test
 	public void validateWhenNotBeforeIsValidAndExpiryIsNotSpecifiedThenReturnsSuccessfulResult() {
-		Jwt jwt = new Jwt(
-				MOCK_TOKEN_VALUE,
-				MOCK_ISSUED_AT,
-				null,
-				MOCK_HEADER,
-				Collections.singletonMap(JwtClaimNames.NBF, Instant.MIN));
+		Jwt jwt = jwt()
+				.claims(c -> c.remove(EXP))
+				.notBefore(Instant.MIN)
+				.build();
 
 		JwtTimestampValidator jwtValidator = new JwtTimestampValidator();
 		assertThat(jwtValidator.validate(jwt).hasErrors()).isFalse();
@@ -188,12 +148,7 @@ public class JwtTimestampValidatorTests {
 
 	@Test
 	public void validateWhenExpiryIsValidAndNotBeforeIsNotSpecifiedThenReturnsSuccessfulResult() {
-		Jwt jwt = new Jwt(
-				MOCK_TOKEN_VALUE,
-				MOCK_ISSUED_AT,
-				Instant.MAX,
-				MOCK_HEADER,
-				MOCK_CLAIM_SET);
+		Jwt jwt = jwt().build();
 
 		JwtTimestampValidator jwtValidator = new JwtTimestampValidator();
 		assertThat(jwtValidator.validate(jwt).hasErrors()).isFalse();
@@ -201,12 +156,10 @@ public class JwtTimestampValidatorTests {
 
 	@Test
 	public void validateWhenBothExpiryAndNotBeforeAreValidThenReturnsSuccessfulResult() {
-		Jwt jwt = new Jwt(
-				MOCK_TOKEN_VALUE,
-				MOCK_ISSUED_AT,
-				Instant.now(MOCK_NOW),
-				MOCK_HEADER,
-				Collections.singletonMap(JwtClaimNames.NBF, Instant.now(MOCK_NOW)));
+		Jwt jwt = jwt()
+				.expiresAt(Instant.now(MOCK_NOW))
+				.notBefore(Instant.now(MOCK_NOW))
+				.build();
 
 		JwtTimestampValidator jwtValidator = new JwtTimestampValidator(Duration.ofNanos(0));
 		jwtValidator.setClock(MOCK_NOW);

+ 40 - 0
oauth2/oauth2-jose/src/test/java/org/springframework/security/oauth2/jwt/TestJwts.java

@@ -0,0 +1,40 @@
+/*
+ * Copyright 2002-2019 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.security.oauth2.jwt;
+
+import java.time.Instant;
+import java.util.Arrays;
+
+public class TestJwts {
+	public static Jwt.Builder jwt() {
+		return Jwt.withTokenValue("token")
+				.header("alg", "none")
+				.audience(Arrays.asList("https://audience.example.org"))
+				.expiresAt(Instant.MAX)
+				.issuedAt(Instant.MIN)
+				.issuer("https://issuer.example.org")
+				.jti("jti")
+				.notBefore(Instant.MIN)
+				.subject("mock-test-subject");
+	}
+
+	public static Jwt user() {
+		return jwt()
+				.claim("sub", "mock-test-subject")
+				.build();
+	}
+}

+ 1 - 0
oauth2/oauth2-resource-server/spring-security-oauth2-resource-server.gradle

@@ -13,6 +13,7 @@ dependencies {
 
 	provided 'javax.servlet:javax.servlet-api'
 
+	testCompile project(path: ':spring-security-oauth2-jose', configuration: 'tests')
 	testCompile 'com.squareup.okhttp3:mockwebserver'
 	testCompile 'com.fasterxml.jackson.core:jackson-databind'
 	testCompile 'io.projectreactor.netty:reactor-netty'

+ 6 - 17
oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtAuthenticationConverterTests.java

@@ -16,15 +16,8 @@
 
 package org.springframework.security.oauth2.server.resource.authentication;
 
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
-
-import java.time.Instant;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
 
 import org.junit.Test;
 
@@ -32,9 +25,12 @@ import org.springframework.core.convert.converter.Converter;
 import org.springframework.security.authentication.AbstractAuthenticationToken;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
-import org.springframework.security.oauth2.jose.jws.JwsAlgorithms;
 import org.springframework.security.oauth2.jwt.Jwt;
 
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
+import static org.springframework.security.oauth2.jwt.TestJwts.jwt;
+
 /**
  * Tests for {@link JwtAuthenticationConverter}
  *
@@ -45,7 +41,7 @@ public class JwtAuthenticationConverterTests {
 
 	@Test
 	public void convertWhenDefaultGrantedAuthoritiesConverterSet() {
-		Jwt jwt = this.jwt(Collections.singletonMap("scope", "message:read message:write"));
+		Jwt jwt = jwt().claim("scope", "message:read message:write").build();
 
 		AbstractAuthenticationToken authentication = this.jwtAuthenticationConverter.convert(jwt);
 		Collection<GrantedAuthority> authorities = authentication.getAuthorities();
@@ -64,7 +60,7 @@ public class JwtAuthenticationConverterTests {
 
 	@Test
 	public void convertWithOverriddenGrantedAuthoritiesConverter() {
-		Jwt jwt = this.jwt(Collections.singletonMap("scope", "message:read message:write"));
+		Jwt jwt = jwt().claim("scope", "message:read message:write").build();
 
 		Converter<Jwt, Collection<GrantedAuthority>> grantedAuthoritiesConverter =
 				token -> Arrays.asList(new SimpleGrantedAuthority("blah"));
@@ -77,11 +73,4 @@ public class JwtAuthenticationConverterTests {
 		assertThat(authorities).containsExactly(
 				new SimpleGrantedAuthority("blah"));
 	}
-
-	private Jwt jwt(Map<String, Object> claims) {
-		Map<String, Object> headers = new HashMap<>();
-		headers.put("alg", JwsAlgorithms.RS256);
-
-		return new Jwt("token", Instant.now(), Instant.now().plusSeconds(3600), headers, claims);
-	}
 }

+ 4 - 17
oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtAuthenticationProviderTests.java

@@ -15,10 +15,6 @@
  */
 package org.springframework.security.oauth2.server.resource.authentication;
 
-import java.time.Instant;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
 import java.util.function.Predicate;
 
 import org.junit.Before;
@@ -29,7 +25,6 @@ import org.mockito.junit.MockitoJUnitRunner;
 
 import org.springframework.core.convert.converter.Converter;
 import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
-import org.springframework.security.oauth2.jose.jws.JwsAlgorithms;
 import org.springframework.security.oauth2.jwt.Jwt;
 import org.springframework.security.oauth2.jwt.JwtDecoder;
 import org.springframework.security.oauth2.jwt.JwtException;
@@ -40,6 +35,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatCode;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
+import static org.springframework.security.oauth2.jwt.TestJwts.jwt;
 
 /**
  * Tests for {@link JwtAuthenticationProvider}
@@ -67,9 +63,7 @@ public class JwtAuthenticationProviderTests {
 	public void authenticateWhenJwtDecodesThenAuthenticationHasAttributesContainedInJwt() {
 		BearerTokenAuthenticationToken token = this.authentication();
 
-		Map<String, Object> claims = new HashMap<>();
-		claims.put("name", "value");
-		Jwt jwt = this.jwt(claims);
+		Jwt jwt = jwt().claim("name", "value").build();
 
 		when(this.jwtDecoder.decode("token")).thenReturn(jwt);
 		when(this.jwtAuthenticationConverter.convert(jwt)).thenReturn(new JwtAuthenticationToken(jwt));
@@ -77,7 +71,7 @@ public class JwtAuthenticationProviderTests {
 		JwtAuthenticationToken authentication =
 				(JwtAuthenticationToken) this.provider.authenticate(token);
 
-		assertThat(authentication.getTokenAttributes()).isEqualTo(claims);
+		assertThat(authentication.getTokenAttributes()).containsEntry("name", "value");
 	}
 
 	@Test
@@ -110,7 +104,7 @@ public class JwtAuthenticationProviderTests {
 		Object details = mock(Object.class);
 		token.setDetails(details);
 
-		Jwt jwt = this.jwt(Collections.singletonMap("some", "value"));
+		Jwt jwt = jwt().build();
 		JwtAuthenticationToken authentication = new JwtAuthenticationToken(jwt);
 
 		when(this.jwtDecoder.decode(token.getToken())).thenReturn(jwt);
@@ -130,13 +124,6 @@ public class JwtAuthenticationProviderTests {
 		return new BearerTokenAuthenticationToken("token");
 	}
 
-	private Jwt jwt(Map<String, Object> claims) {
-		Map<String, Object> headers = new HashMap<>();
-		headers.put("alg", JwsAlgorithms.RS256);
-
-		return new Jwt("token", Instant.now(), Instant.now().plusSeconds(3600), headers, claims);
-	}
-
 	private Predicate<? super Throwable> errorCode(String errorCode) {
 		return failed ->
 				((OAuth2AuthenticationException) failed).getError().getErrorCode() == errorCode;

+ 32 - 49
oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtGrantedAuthoritiesConverterTests.java

@@ -16,23 +16,19 @@
 
 package org.springframework.security.oauth2.server.resource.authentication;
 
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.time.Instant;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
 
-import org.assertj.core.util.Maps;
 import org.junit.Test;
 
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
-import org.springframework.security.oauth2.jose.jws.JwsAlgorithms;
 import org.springframework.security.oauth2.jwt.Jwt;
 
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.security.oauth2.jwt.TestJwts.jwt;
+
 /**
  * Tests for {@link JwtGrantedAuthoritiesConverter}
  *
@@ -43,7 +39,7 @@ public class JwtGrantedAuthoritiesConverterTests {
 
 	@Test
 	public void convertWhenTokenHasScopeAttributeThenTranslatedToAuthorities() {
-		Jwt jwt = this.jwt(Collections.singletonMap("scope", "message:read message:write"));
+		Jwt jwt = jwt().claim("scope", "message:read message:write").build();
 
 		JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
 		Collection<GrantedAuthority> authorities = jwtGrantedAuthoritiesConverter.convert(jwt);
@@ -55,7 +51,7 @@ public class JwtGrantedAuthoritiesConverterTests {
 
 	@Test
 	public void convertWithCustomAuthorityPrefixWhenTokenHasScopeAttributeThenTranslatedToAuthorities() {
-		Jwt jwt = this.jwt(Collections.singletonMap("scope", "message:read message:write"));
+		Jwt jwt = jwt().claim("scope", "message:read message:write").build();
 
 		JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
 		jwtGrantedAuthoritiesConverter.setAuthorityPrefix("ROLE_");
@@ -68,7 +64,7 @@ public class JwtGrantedAuthoritiesConverterTests {
 
 	@Test
 	public void convertWhenTokenHasEmptyScopeAttributeThenTranslatedToNoAuthorities() {
-		Jwt jwt = this.jwt(Collections.singletonMap("scope", ""));
+		Jwt jwt = jwt().claim("scope", "").build();
 
 		JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
 		Collection<GrantedAuthority> authorities = jwtGrantedAuthoritiesConverter.convert(jwt);
@@ -78,7 +74,7 @@ public class JwtGrantedAuthoritiesConverterTests {
 
 	@Test
 	public void convertWhenTokenHasScpAttributeThenTranslatedToAuthorities() {
-		Jwt jwt = this.jwt(Collections.singletonMap("scp", Arrays.asList("message:read", "message:write")));
+		Jwt jwt = jwt().claim("scp", Arrays.asList("message:read", "message:write")).build();
 
 		JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
 		Collection<GrantedAuthority> authorities = jwtGrantedAuthoritiesConverter.convert(jwt);
@@ -90,7 +86,7 @@ public class JwtGrantedAuthoritiesConverterTests {
 
 	@Test
 	public void convertWithCustomAuthorityPrefixWhenTokenHasScpAttributeThenTranslatedToAuthorities() {
-		Jwt jwt = this.jwt(Collections.singletonMap("scp", Arrays.asList("message:read", "message:write")));
+		Jwt jwt = jwt().claim("scp", Arrays.asList("message:read", "message:write")).build();
 
 		JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
 		jwtGrantedAuthoritiesConverter.setAuthorityPrefix("ROLE_");
@@ -103,7 +99,7 @@ public class JwtGrantedAuthoritiesConverterTests {
 
 	@Test
 	public void convertWhenTokenHasEmptyScpAttributeThenTranslatedToNoAuthorities() {
-		Jwt jwt = this.jwt(Maps.newHashMap("scp", Collections.emptyList()));
+		Jwt jwt = jwt().claim("scp", Collections.emptyList()).build();
 
 		JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
 		Collection<GrantedAuthority> authorities = jwtGrantedAuthoritiesConverter.convert(jwt);
@@ -113,10 +109,10 @@ public class JwtGrantedAuthoritiesConverterTests {
 
 	@Test
 	public void convertWhenTokenHasBothScopeAndScpThenScopeAttributeIsTranslatedToAuthorities() {
-		Map<String, Object> claims = new HashMap<>();
-		claims.put("scp", Arrays.asList("message:read", "message:write"));
-		claims.put("scope", "missive:read missive:write");
-		Jwt jwt = this.jwt(claims);
+		Jwt jwt = jwt()
+			.claim("scp", Arrays.asList("message:read", "message:write"))
+			.claim("scope", "missive:read missive:write")
+			.build();
 
 		JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
 		Collection<GrantedAuthority> authorities = jwtGrantedAuthoritiesConverter.convert(jwt);
@@ -128,10 +124,10 @@ public class JwtGrantedAuthoritiesConverterTests {
 
 	@Test
 	public void convertWhenTokenHasEmptyScopeAndNonEmptyScpThenScopeAttributeIsTranslatedToNoAuthorities() {
-		Map<String, Object> claims = new HashMap<>();
-		claims.put("scp", Arrays.asList("message:read", "message:write"));
-		claims.put("scope", "");
-		Jwt jwt = this.jwt(claims);
+		Jwt jwt = jwt()
+			.claim("scp", Arrays.asList("message:read", "message:write"))
+			.claim("scope", "")
+			.build();
 
 		JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
 		Collection<GrantedAuthority> authorities = jwtGrantedAuthoritiesConverter.convert(jwt);
@@ -141,10 +137,10 @@ public class JwtGrantedAuthoritiesConverterTests {
 
 	@Test
 	public void convertWhenTokenHasEmptyScopeAndEmptyScpAttributeThenTranslatesToNoAuthorities() {
-		Map<String, Object> claims = new HashMap<>();
-		claims.put("scp", Collections.emptyList());
-		claims.put("scope", Collections.emptyList());
-		Jwt jwt = this.jwt(claims);
+		Jwt jwt = jwt()
+			.claim("scp", Collections.emptyList())
+			.claim("scope", Collections.emptyList())
+			.build();
 
 		JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
 		Collection<GrantedAuthority> authorities = jwtGrantedAuthoritiesConverter.convert(jwt);
@@ -154,9 +150,7 @@ public class JwtGrantedAuthoritiesConverterTests {
 
 	@Test
 	public void convertWhenTokenHasNoScopeAndNoScpAttributeThenTranslatesToNoAuthorities() {
-		Map<String, Object> claims = new HashMap<>();
-		claims.put("roles", Arrays.asList("message:read", "message:write"));
-		Jwt jwt = this.jwt(claims);
+		Jwt jwt = jwt().claim("roles", Arrays.asList("message:read", "message:write")).build();
 
 		JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
 		Collection<GrantedAuthority> authorities = jwtGrantedAuthoritiesConverter.convert(jwt);
@@ -166,9 +160,7 @@ public class JwtGrantedAuthoritiesConverterTests {
 
 	@Test
 	public void convertWhenTokenHasUnsupportedTypeForScopeThenTranslatesToNoAuthorities() {
-		Map<String, Object> claims = new HashMap<>();
-		claims.put("scope", new String[] {"message:read", "message:write"});
-		Jwt jwt = this.jwt(claims);
+		Jwt jwt = jwt().claim("scope", new String[] {"message:read", "message:write"}).build();
 
 		JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
 		Collection<GrantedAuthority> authorities = jwtGrantedAuthoritiesConverter.convert(jwt);
@@ -178,10 +170,10 @@ public class JwtGrantedAuthoritiesConverterTests {
 
 	@Test
 	public void convertWhenTokenHasCustomClaimNameThenCustomClaimNameAttributeIsTranslatedToAuthorities() {
-		Map<String, Object> claims = new HashMap<>();
-		claims.put("roles", Arrays.asList("message:read", "message:write"));
-		claims.put("scope", "missive:read missive:write");
-		Jwt jwt = this.jwt(claims);
+		Jwt jwt = jwt()
+				.claim("roles", Arrays.asList("message:read", "message:write"))
+				.claim("scope", "missive:read missive:write")
+				.build();
 
 		JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
 		jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName("roles");
@@ -194,10 +186,10 @@ public class JwtGrantedAuthoritiesConverterTests {
 
 	@Test
 	public void convertWhenTokenHasEmptyCustomClaimNameThenCustomClaimNameAttributeIsTranslatedToNoAuthorities() {
-		Map<String, Object> claims = new HashMap<>();
-		claims.put("roles", Collections.emptyList());
-		claims.put("scope", "missive:read missive:write");
-		Jwt jwt = this.jwt(claims);
+		Jwt jwt = jwt()
+				.claim("roles", Collections.emptyList())
+				.claim("scope", "missive:read missive:write")
+				.build();
 
 		JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
 		jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName("roles");
@@ -208,9 +200,7 @@ public class JwtGrantedAuthoritiesConverterTests {
 
 	@Test
 	public void convertWhenTokenHasNoCustomClaimNameThenCustomClaimNameAttributeIsTranslatedToNoAuthorities() {
-		Map<String, Object> claims = new HashMap<>();
-		claims.put("scope", "missive:read missive:write");
-		Jwt jwt = this.jwt(claims);
+		Jwt jwt = jwt().claim("scope", "missive:read missive:write").build();
 
 		JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
 		jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName("roles");
@@ -218,11 +208,4 @@ public class JwtGrantedAuthoritiesConverterTests {
 
 		assertThat(authorities).isEmpty();
 	}
-
-	private Jwt jwt(Map<String, Object> claims) {
-		Map<String, Object> headers = new HashMap<>();
-		headers.put("alg", JwsAlgorithms.RS256);
-
-		return new Jwt("token", Instant.now(), Instant.now().plusSeconds(3600), headers, claims);
-	}
 }

+ 4 - 11
oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtReactiveAuthenticationManagerTests.java

@@ -21,6 +21,8 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnitRunner;
+import reactor.core.publisher.Mono;
+
 import org.springframework.security.authentication.TestingAuthenticationToken;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.GrantedAuthority;
@@ -29,16 +31,12 @@ import org.springframework.security.oauth2.jwt.Jwt;
 import org.springframework.security.oauth2.jwt.JwtException;
 import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
 import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
-import reactor.core.publisher.Mono;
-
-import java.time.Instant;
-import java.util.HashMap;
-import java.util.Map;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatCode;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.when;
+import static org.springframework.security.oauth2.jwt.TestJwts.jwt;
 
 /**
  * @author Rob Winch
@@ -56,12 +54,7 @@ public class JwtReactiveAuthenticationManagerTests {
 	@Before
 	public void setup() {
 		this.manager = new JwtReactiveAuthenticationManager(this.jwtDecoder);
-
-		Map<String, Object> claims = new HashMap<>();
-		claims.put("scope", "message:read message:write");
-		Instant issuedAt = Instant.now();
-		Instant expiresAt = Instant.from(issuedAt).plusSeconds(3600);
-		this.jwt = new Jwt("jwt", issuedAt, expiresAt, claims, claims);
+		this.jwt = jwt().claim("scope", "message:read message:write").build();
 	}
 
 	@Test

+ 13 - 24
oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/ReactiveJwtAuthenticationConverterAdapterTests.java

@@ -16,12 +16,8 @@
 
 package org.springframework.security.oauth2.server.resource.authentication;
 
-import java.time.Instant;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
 
 import org.junit.Test;
 
@@ -29,10 +25,10 @@ import org.springframework.core.convert.converter.Converter;
 import org.springframework.security.authentication.AbstractAuthenticationToken;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
-import org.springframework.security.oauth2.jose.jws.JwsAlgorithms;
 import org.springframework.security.oauth2.jwt.Jwt;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.security.oauth2.jwt.TestJwts.jwt;
 
 /**
  * Tests for {@link ReactiveJwtAuthenticationConverterAdapter}
@@ -46,7 +42,7 @@ public class ReactiveJwtAuthenticationConverterAdapterTests {
 
 	@Test
 	public void convertWhenTokenHasScopeAttributeThenTranslatedToAuthorities() {
-		Jwt jwt = this.jwt(Collections.singletonMap("scope", "message:read message:write"));
+		Jwt jwt = jwt().claim("scope", "message:read message:write").build();
 
 		AbstractAuthenticationToken authentication = this.jwtAuthenticationConverter.convert(jwt).block();
 		Collection<GrantedAuthority> authorities = authentication.getAuthorities();
@@ -58,7 +54,7 @@ public class ReactiveJwtAuthenticationConverterAdapterTests {
 
 	@Test
 	public void convertWhenTokenHasEmptyScopeAttributeThenTranslatedToNoAuthorities() {
-		Jwt jwt = this.jwt(Collections.singletonMap("scope", ""));
+		Jwt jwt = jwt().claim("scope", "").build();
 
 		AbstractAuthenticationToken authentication = this.jwtAuthenticationConverter.convert(jwt).block();
 
@@ -69,7 +65,7 @@ public class ReactiveJwtAuthenticationConverterAdapterTests {
 
 	@Test
 	public void convertWhenTokenHasScpAttributeThenTranslatedToAuthorities() {
-		Jwt jwt = this.jwt(Collections.singletonMap("scp", Arrays.asList("message:read", "message:write")));
+		Jwt jwt = jwt().claim("scp", Arrays.asList("message:read", "message:write")).build();
 
 		AbstractAuthenticationToken authentication = this.jwtAuthenticationConverter.convert(jwt).block();
 
@@ -82,7 +78,7 @@ public class ReactiveJwtAuthenticationConverterAdapterTests {
 
 	@Test
 	public void convertWhenTokenHasEmptyScpAttributeThenTranslatedToNoAuthorities() {
-		Jwt jwt = this.jwt(Collections.singletonMap("scp", Arrays.asList()));
+		Jwt jwt = jwt().claim("scp", Arrays.asList()).build();
 
 		AbstractAuthenticationToken authentication = this.jwtAuthenticationConverter.convert(jwt).block();
 
@@ -93,10 +89,10 @@ public class ReactiveJwtAuthenticationConverterAdapterTests {
 
 	@Test
 	public void convertWhenTokenHasBothScopeAndScpThenScopeAttributeIsTranslatedToAuthorities() {
-		Map<String, Object> claims = new HashMap<>();
-		claims.put("scp", Arrays.asList("message:read", "message:write"));
-		claims.put("scope", "missive:read missive:write");
-		Jwt jwt = this.jwt(claims);
+		Jwt jwt = jwt()
+				.claim("scp", Arrays.asList("message:read", "message:write"))
+				.claim("scope", "missive:read missive:write")
+				.build();
 
 		AbstractAuthenticationToken authentication = this.jwtAuthenticationConverter.convert(jwt).block();
 
@@ -109,10 +105,10 @@ public class ReactiveJwtAuthenticationConverterAdapterTests {
 
 	@Test
 	public void convertWhenTokenHasEmptyScopeAndNonEmptyScpThenScopeAttributeIsTranslatedToNoAuthorities() {
-		Map<String, Object> claims = new HashMap<>();
-		claims.put("scp", Arrays.asList("message:read", "message:write"));
-		claims.put("scope", "");
-		Jwt jwt = this.jwt(claims);
+		Jwt jwt = jwt()
+				.claim("scp", Arrays.asList("message:read", "message:write"))
+				.claim("scope", "")
+				.build();
 
 		AbstractAuthenticationToken authentication = this.jwtAuthenticationConverter.convert(jwt).block();
 
@@ -120,11 +116,4 @@ public class ReactiveJwtAuthenticationConverterAdapterTests {
 
 		assertThat(authorities).containsExactly();
 	}
-
-	private Jwt jwt(Map<String, Object> claims) {
-		Map<String, Object> headers = new HashMap<>();
-		headers.put("alg", JwsAlgorithms.RS256);
-
-		return new Jwt("token", Instant.now(), Instant.now().plusSeconds(3600), headers, claims);
-	}
 }

+ 6 - 18
oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/ReactiveJwtAuthenticationConverterTests.java

@@ -16,26 +16,21 @@
 
 package org.springframework.security.oauth2.server.resource.authentication;
 
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
-
-import java.time.Instant;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
 
 import org.junit.Test;
-
 import reactor.core.publisher.Flux;
 
 import org.springframework.core.convert.converter.Converter;
 import org.springframework.security.authentication.AbstractAuthenticationToken;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
-import org.springframework.security.oauth2.jose.jws.JwsAlgorithms;
 import org.springframework.security.oauth2.jwt.Jwt;
 
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
+import static org.springframework.security.oauth2.jwt.TestJwts.jwt;
+
 /**
  * Tests for {@link ReactiveJwtAuthenticationConverter}
  *
@@ -47,7 +42,7 @@ public class ReactiveJwtAuthenticationConverterTests {
 
 	@Test
 	public void convertWhenDefaultGrantedAuthoritiesConverterSet() {
-		Jwt jwt = this.jwt(Collections.singletonMap("scope", "message:read message:write"));
+		Jwt jwt = jwt().claim("scope", "message:read message:write").build();
 
 		AbstractAuthenticationToken authentication = this.jwtAuthenticationConverter.convert(jwt).block();
 		Collection<GrantedAuthority> authorities = authentication.getAuthorities();
@@ -66,7 +61,7 @@ public class ReactiveJwtAuthenticationConverterTests {
 
 	@Test
 	public void convertWithOverriddenGrantedAuthoritiesConverter() {
-		Jwt jwt = this.jwt(Collections.singletonMap("scope", "message:read message:write"));
+		Jwt jwt = jwt().claim("scope", "message:read message:write").build();
 
 		Converter<Jwt, Flux<GrantedAuthority>> grantedAuthoritiesConverter =
 				token -> Flux.just(new SimpleGrantedAuthority("blah"));
@@ -79,11 +74,4 @@ public class ReactiveJwtAuthenticationConverterTests {
 		assertThat(authorities).containsExactly(
 				new SimpleGrantedAuthority("blah"));
 	}
-
-	private Jwt jwt(Map<String, Object> claims) {
-		Map<String, Object> headers = new HashMap<>();
-		headers.put("alg", JwsAlgorithms.RS256);
-
-		return new Jwt("token", Instant.now(), Instant.now().plusSeconds(3600), headers, claims);
-	}
 }

+ 5 - 16
oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/ReactiveJwtGrantedAuthoritiesConverterAdapterTests.java

@@ -16,15 +16,8 @@
 
 package org.springframework.security.oauth2.server.resource.authentication;
 
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
-
-import java.time.Instant;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
 import java.util.stream.Collectors;
 
 import org.junit.Test;
@@ -32,9 +25,12 @@ import org.junit.Test;
 import org.springframework.core.convert.converter.Converter;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
-import org.springframework.security.oauth2.jose.jws.JwsAlgorithms;
 import org.springframework.security.oauth2.jwt.Jwt;
 
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
+import static org.springframework.security.oauth2.jwt.TestJwts.jwt;
+
 /**
  * Tests for {@link ReactiveJwtGrantedAuthoritiesConverterAdapter}
  *
@@ -44,7 +40,7 @@ import org.springframework.security.oauth2.jwt.Jwt;
 public class ReactiveJwtGrantedAuthoritiesConverterAdapterTests {
 	@Test
 	public void convertWithGrantedAuthoritiesConverter() {
-		Jwt jwt = this.jwt(Collections.singletonMap("scope", "message:read message:write"));
+		Jwt jwt = jwt().claim("scope", "message:read message:write").build();
 
 		Converter<Jwt, Collection<GrantedAuthority>> grantedAuthoritiesConverter =
 				token -> Arrays.asList(new SimpleGrantedAuthority("blah"));
@@ -65,11 +61,4 @@ public class ReactiveJwtGrantedAuthoritiesConverterAdapterTests {
 				.isThrownBy(() -> new ReactiveJwtGrantedAuthoritiesConverterAdapter(null))
 				.withMessage("grantedAuthoritiesConverter cannot be null");
 	}
-
-	private Jwt jwt(Map<String, Object> claims) {
-		Map<String, Object> headers = new HashMap<>();
-		headers.put("alg", JwsAlgorithms.RS256);
-
-		return new Jwt("token", Instant.now(), Instant.now().plusSeconds(3600), headers, claims);
-	}
 }

+ 7 - 11
test/src/test/java/org/springframework/security/test/web/reactive/server/SecurityMockServerConfigurersJwtTests.java

@@ -15,12 +15,8 @@
  */
 package org.springframework.security.test.web.reactive.server;
 
-import java.time.Instant;
 import java.util.Arrays;
 import java.util.List;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Collections;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -33,8 +29,8 @@ import org.springframework.http.MediaType;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
 import org.springframework.security.core.context.SecurityContext;
-import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames;
 import org.springframework.security.oauth2.jwt.Jwt;
+import org.springframework.security.oauth2.jwt.TestJwts;
 import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
 import org.springframework.security.web.reactive.result.method.annotation.CurrentSecurityContextArgumentResolver;
 import org.springframework.security.web.server.context.SecurityContextServerWebExchangeWebFilter;
@@ -145,11 +141,11 @@ public class SecurityMockServerConfigurersJwtTests extends AbstractMockServerCon
 
 	@Test
 	public void mockJwtWhenProvidingPreparedJwtThenProducesJwtAuthentication() {
-		Map<String, Object> claims = new HashMap<>();
-		claims.put(IdTokenClaimNames.SUB, "some_user");
-		Jwt originalToken = new Jwt("token123", Instant.now(), Instant.now().plusSeconds(3600),
-				Collections.singletonMap("header1", "value1"), claims);
-		client
+		Jwt originalToken = TestJwts.jwt()
+				.header("header1", "value1")
+				.subject("some_user")
+				.build();
+		this.client
 				.mutateWith(mockJwt(originalToken))
 				.get()
 				.exchange()
@@ -160,7 +156,7 @@ public class SecurityMockServerConfigurersJwtTests extends AbstractMockServerCon
 				JwtAuthenticationToken.class);
 		JwtAuthenticationToken retrievedToken = (JwtAuthenticationToken) context.getAuthentication();
 		assertThat(retrievedToken.getToken().getSubject()).isEqualTo("some_user");
-		assertThat(retrievedToken.getToken().getTokenValue()).isEqualTo("token123");
+		assertThat(retrievedToken.getToken().getTokenValue()).isEqualTo("token");
 		assertThat(retrievedToken.getToken().getHeaders().get("header1")).isEqualTo("value1");
 	}
 }

+ 7 - 13
test/src/test/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessorsJwtTests.java

@@ -15,13 +15,8 @@
  */
 package org.springframework.security.test.web.servlet.request;
 
-import java.time.Instant;
-import java.util.List;
-import java.util.Map;
-import java.util.HashMap;
 import java.util.Arrays;
-import java.util.Collections;
-
+import java.util.List;
 import javax.servlet.http.HttpServletResponse;
 
 import org.junit.After;
@@ -39,8 +34,8 @@ import org.springframework.security.config.BeanIds;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
 import org.springframework.security.core.context.SecurityContext;
-import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames;
 import org.springframework.security.oauth2.jwt.Jwt;
+import org.springframework.security.oauth2.jwt.TestJwts;
 import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
 import org.springframework.security.test.context.TestSecurityContextHolder;
 import org.springframework.security.test.web.support.WebTestUtils;
@@ -164,19 +159,18 @@ public class SecurityMockMvcRequestPostProcessorsJwtTests {
 
 	@Test
 	public void jwtWhenProvidingPreparedJwtThenUsesItForAuthentication() {
-		Map<String, Object> claims = new HashMap<>();
-		claims.put(IdTokenClaimNames.SUB, "some_user");
-		Jwt originalToken = new Jwt("token123", Instant.now(), Instant.now().plusSeconds(3600),
-				Collections.singletonMap("header1", "value1"), claims);
+		Jwt originalToken = TestJwts.jwt()
+				.header("header1", "value1")
+				.subject("some_user")
+				.build();
 		jwt(originalToken).postProcessRequest(this.request);
 
-
 		verify(this.repository).saveContext(this.contextCaptor.capture(), eq(this.request),
 				any(HttpServletResponse.class));
 		SecurityContext context = this.contextCaptor.getValue();
 		JwtAuthenticationToken retrievedToken = (JwtAuthenticationToken) context.getAuthentication();
 		assertThat(retrievedToken.getToken().getSubject()).isEqualTo("some_user");
-		assertThat(retrievedToken.getToken().getTokenValue()).isEqualTo("token123");
+		assertThat(retrievedToken.getToken().getTokenValue()).isEqualTo("token");
 		assertThat(retrievedToken.getToken().getHeaders().get("header1")).isEqualTo("value1");
 	}
 }