Use Jwt.Builder

Fixes gh-7443
This commit is contained in:
Josh Cummings 2019-09-16 09:00:04 -06:00
parent 40901fe072
commit 05caf3d8fb
No known key found for this signature in database
GPG Key ID: 49EF60DD7FF83443
25 changed files with 248 additions and 390 deletions

View File

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

View File

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

View File

@ -83,16 +83,15 @@ import org.springframework.security.oauth2.core.DefaultOAuth2AuthenticatedPrinci
import org.springframework.security.oauth2.core.OAuth2Error; import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.core.OAuth2TokenValidator; import org.springframework.security.oauth2.core.OAuth2TokenValidator;
import org.springframework.security.oauth2.core.OAuth2TokenValidatorResult; 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.Jwt;
import org.springframework.security.oauth2.jwt.JwtClaimNames; import org.springframework.security.oauth2.jwt.JwtClaimNames;
import org.springframework.security.oauth2.jwt.JwtDecoder; import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.JwtException; import org.springframework.security.oauth2.jwt.JwtException;
import org.springframework.security.oauth2.jwt.JwtTimestampValidator; import org.springframework.security.oauth2.jwt.JwtTimestampValidator;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; 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.JwtAuthenticationConverter;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthentication;
import org.springframework.security.oauth2.server.resource.introspection.NimbusOpaqueTokenIntrospector; 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.introspection.OpaqueTokenIntrospector;
import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationEntryPoint; 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.core.TestOAuth2AccessTokens.noScopes;
import static org.springframework.security.oauth2.jwt.NimbusJwtDecoder.withJwkSetUri; 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.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.csrf;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 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 { public class OAuth2ResourceServerConfigurerTests {
private static final String JWT_TOKEN = "token"; private static final String JWT_TOKEN = "token";
private static final String JWT_SUBJECT = "mock-test-subject"; 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 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 String JWK_SET_URI = "https://mock.org";
private static final JwtAuthenticationToken JWT_AUTHENTICATION_TOKEN = private static final JwtAuthenticationToken JWT_AUTHENTICATION_TOKEN =
new JwtAuthenticationToken(JWT, Collections.emptyList()); new JwtAuthenticationToken(JWT, Collections.emptyList());

View File

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

View File

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

View File

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

View File

@ -15,12 +15,22 @@
*/ */
package org.springframework.security.oauth2.client.oidc.authentication; 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.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.ExpectedException; import org.junit.rules.ExpectedException;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.stubbing.Answer; import org.mockito.stubbing.Answer;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; 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.JwtDecoder;
import org.springframework.security.oauth2.jwt.JwtException; 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.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.CoreMatchers.containsString; 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.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import static org.springframework.security.oauth2.client.registration.TestClientRegistrations.clientRegistration; 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.TestOAuth2AuthorizationRequests.request;
import static org.springframework.security.oauth2.core.endpoint.TestOAuth2AuthorizationResponses.error; 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.core.endpoint.TestOAuth2AuthorizationResponses.success;
import static org.springframework.security.oauth2.jwt.TestJwts.jwt;
/** /**
* Tests for {@link OidcAuthorizationCodeAuthenticationProvider}. * Tests for {@link OidcAuthorizationCodeAuthenticationProvider}.
@ -299,16 +303,7 @@ public class OidcAuthorizationCodeAuthenticationProviderTests {
} }
private void setUpIdToken(Map<String, Object> claims) { private void setUpIdToken(Map<String, Object> claims) {
Instant issuedAt = Instant.now(); Jwt idToken = jwt().claims(c -> c.putAll(claims)).build();
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);
JwtDecoder jwtDecoder = mock(JwtDecoder.class); JwtDecoder jwtDecoder = mock(JwtDecoder.class);
when(jwtDecoder.decode(anyString())).thenReturn(idToken); when(jwtDecoder.decode(anyString())).thenReturn(idToken);

View File

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

View File

@ -15,15 +15,6 @@
*/ */
package org.springframework.security.oauth2.client.oidc.authentication; package org.springframework.security.oauth2.client.oidc.authentication;
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;
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.Duration;
import java.time.Instant; import java.time.Instant;
import java.util.Arrays; import java.util.Arrays;
@ -32,6 +23,16 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; 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;
import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames;
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.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.assertThatThrownBy;
@ -240,7 +241,12 @@ public class OidcIdTokenValidatorTests {
} }
private Collection<OAuth2Error> validateIdToken() { 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()); OidcIdTokenValidator validator = new OidcIdTokenValidator(this.registration.build());
validator.setClockSkew(this.clockSkew); validator.setClockSkew(this.clockSkew);
return validator.validate(idToken).getErrors(); return validator.validate(idToken).getErrors();

View File

@ -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 expiresAt the expiration time on or after which the JWT MUST NOT be accepted
* @param headers the JOSE header(s) * @param headers the JOSE header(s)
* @param claims the JWT Claims Set * @param claims the JWT Claims Set
*
*/ */
public Jwt(String tokenValue, Instant issuedAt, Instant expiresAt, public Jwt(String tokenValue, Instant issuedAt, Instant expiresAt,
Map<String, Object> headers, Map<String, Object> claims) { Map<String, Object> headers, Map<String, Object> claims) {

View File

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

View File

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

View File

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

View File

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

View File

@ -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();
}
}

View File

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

View File

@ -16,15 +16,8 @@
package org.springframework.security.oauth2.server.resource.authentication; 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.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test; 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.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.jose.jws.JwsAlgorithms;
import org.springframework.security.oauth2.jwt.Jwt; 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} * Tests for {@link JwtAuthenticationConverter}
* *
@ -45,7 +41,7 @@ public class JwtAuthenticationConverterTests {
@Test @Test
public void convertWhenDefaultGrantedAuthoritiesConverterSet() { 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); AbstractAuthenticationToken authentication = this.jwtAuthenticationConverter.convert(jwt);
Collection<GrantedAuthority> authorities = authentication.getAuthorities(); Collection<GrantedAuthority> authorities = authentication.getAuthorities();
@ -64,7 +60,7 @@ public class JwtAuthenticationConverterTests {
@Test @Test
public void convertWithOverriddenGrantedAuthoritiesConverter() { 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 = Converter<Jwt, Collection<GrantedAuthority>> grantedAuthoritiesConverter =
token -> Arrays.asList(new SimpleGrantedAuthority("blah")); token -> Arrays.asList(new SimpleGrantedAuthority("blah"));
@ -77,11 +73,4 @@ public class JwtAuthenticationConverterTests {
assertThat(authorities).containsExactly( assertThat(authorities).containsExactly(
new SimpleGrantedAuthority("blah")); 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);
}
} }

View File

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

View File

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

View File

@ -21,6 +21,8 @@ import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner; import org.mockito.junit.MockitoJUnitRunner;
import reactor.core.publisher.Mono;
import org.springframework.security.authentication.TestingAuthenticationToken; import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority; 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.JwtException;
import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder; import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken; 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.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatCode;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import static org.springframework.security.oauth2.jwt.TestJwts.jwt;
/** /**
* @author Rob Winch * @author Rob Winch
@ -56,12 +54,7 @@ public class JwtReactiveAuthenticationManagerTests {
@Before @Before
public void setup() { public void setup() {
this.manager = new JwtReactiveAuthenticationManager(this.jwtDecoder); this.manager = new JwtReactiveAuthenticationManager(this.jwtDecoder);
this.jwt = jwt().claim("scope", "message:read message:write").build();
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);
} }
@Test @Test

View File

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

View File

@ -16,26 +16,21 @@
package org.springframework.security.oauth2.server.resource.authentication; 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.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test; import org.junit.Test;
import reactor.core.publisher.Flux; import reactor.core.publisher.Flux;
import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.Converter;
import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.jose.jws.JwsAlgorithms;
import org.springframework.security.oauth2.jwt.Jwt; 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} * Tests for {@link ReactiveJwtAuthenticationConverter}
* *
@ -47,7 +42,7 @@ public class ReactiveJwtAuthenticationConverterTests {
@Test @Test
public void convertWhenDefaultGrantedAuthoritiesConverterSet() { 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(); AbstractAuthenticationToken authentication = this.jwtAuthenticationConverter.convert(jwt).block();
Collection<GrantedAuthority> authorities = authentication.getAuthorities(); Collection<GrantedAuthority> authorities = authentication.getAuthorities();
@ -66,7 +61,7 @@ public class ReactiveJwtAuthenticationConverterTests {
@Test @Test
public void convertWithOverriddenGrantedAuthoritiesConverter() { 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 = Converter<Jwt, Flux<GrantedAuthority>> grantedAuthoritiesConverter =
token -> Flux.just(new SimpleGrantedAuthority("blah")); token -> Flux.just(new SimpleGrantedAuthority("blah"));
@ -79,11 +74,4 @@ public class ReactiveJwtAuthenticationConverterTests {
assertThat(authorities).containsExactly( assertThat(authorities).containsExactly(
new SimpleGrantedAuthority("blah")); 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);
}
} }

View File

@ -16,15 +16,8 @@
package org.springframework.security.oauth2.server.resource.authentication; 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.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.junit.Test; import org.junit.Test;
@ -32,9 +25,12 @@ import org.junit.Test;
import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.Converter;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.jose.jws.JwsAlgorithms;
import org.springframework.security.oauth2.jwt.Jwt; 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} * Tests for {@link ReactiveJwtGrantedAuthoritiesConverterAdapter}
* *
@ -44,7 +40,7 @@ import org.springframework.security.oauth2.jwt.Jwt;
public class ReactiveJwtGrantedAuthoritiesConverterAdapterTests { public class ReactiveJwtGrantedAuthoritiesConverterAdapterTests {
@Test @Test
public void convertWithGrantedAuthoritiesConverter() { 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 = Converter<Jwt, Collection<GrantedAuthority>> grantedAuthoritiesConverter =
token -> Arrays.asList(new SimpleGrantedAuthority("blah")); token -> Arrays.asList(new SimpleGrantedAuthority("blah"));
@ -65,11 +61,4 @@ public class ReactiveJwtGrantedAuthoritiesConverterAdapterTests {
.isThrownBy(() -> new ReactiveJwtGrantedAuthoritiesConverterAdapter(null)) .isThrownBy(() -> new ReactiveJwtGrantedAuthoritiesConverterAdapter(null))
.withMessage("grantedAuthoritiesConverter cannot be 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);
}
} }

View File

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

View File

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