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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -15,15 +15,6 @@
*/
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.Instant;
import java.util.Arrays;
@ -32,6 +23,16 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
import org.springframework.security.oauth2.core.OAuth2Error;
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.assertThatThrownBy;
@ -240,7 +241,12 @@ public class OidcIdTokenValidatorTests {
}
private Collection<OAuth2Error> validateIdToken() {
Jwt idToken = new Jwt("token123", this.issuedAt, this.expiresAt, this.headers, this.claims);
Jwt idToken = Jwt.withTokenValue("token")
.issuedAt(this.issuedAt)
.expiresAt(this.expiresAt)
.headers(h -> h.putAll(this.headers))
.claims(c -> c.putAll(this.claims))
.build();
OidcIdTokenValidator validator = new OidcIdTokenValidator(this.registration.build());
validator.setClockSkew(this.clockSkew);
return validator.validate(idToken).getErrors();

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 headers the JOSE header(s)
* @param claims the JWT Claims Set
*
*/
public Jwt(String tokenValue, Instant issuedAt, Instant expiresAt,
Map<String, Object> headers, Map<String, Object> claims) {

View File

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

View File

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

View File

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

View File

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

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'
testCompile project(path: ':spring-security-oauth2-jose', configuration: 'tests')
testCompile 'com.squareup.okhttp3:mockwebserver'
testCompile 'com.fasterxml.jackson.core:jackson-databind'
testCompile 'io.projectreactor.netty:reactor-netty'

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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