mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-05-30 00:32:14 +00:00
Use Jwt.Builder
Fixes gh-7443
This commit is contained in:
parent
40901fe072
commit
05caf3d8fb
@ -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() {
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
@ -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";
|
||||
|
@ -12,6 +12,7 @@ dependencies {
|
||||
optional 'org.springframework:spring-webflux'
|
||||
|
||||
testCompile project(path: ':spring-security-oauth2-core', configuration: 'tests')
|
||||
testCompile project(path: ':spring-security-oauth2-jose', configuration: 'tests')
|
||||
testCompile powerMock2Dependencies
|
||||
testCompile 'com.squareup.okhttp3:mockwebserver'
|
||||
testCompile 'com.fasterxml.jackson.core:jackson-databind'
|
||||
|
@ -15,12 +15,22 @@
|
||||
*/
|
||||
package org.springframework.security.oauth2.client.oidc.authentication;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
|
||||
@ -44,24 +54,18 @@ import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
||||
import org.springframework.security.oauth2.jwt.JwtException;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyCollection;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.security.oauth2.client.registration.TestClientRegistrations.clientRegistration;
|
||||
import static org.springframework.security.oauth2.core.endpoint.TestOAuth2AuthorizationRequests.request;
|
||||
import static org.springframework.security.oauth2.core.endpoint.TestOAuth2AuthorizationResponses.error;
|
||||
import static org.springframework.security.oauth2.core.endpoint.TestOAuth2AuthorizationResponses.success;
|
||||
import static org.springframework.security.oauth2.jwt.TestJwts.jwt;
|
||||
|
||||
/**
|
||||
* Tests for {@link OidcAuthorizationCodeAuthenticationProvider}.
|
||||
@ -299,16 +303,7 @@ public class OidcAuthorizationCodeAuthenticationProviderTests {
|
||||
}
|
||||
|
||||
private void setUpIdToken(Map<String, Object> claims) {
|
||||
Instant issuedAt = Instant.now();
|
||||
Instant expiresAt = Instant.from(issuedAt).plusSeconds(3600);
|
||||
this.setUpIdToken(claims, issuedAt, expiresAt);
|
||||
}
|
||||
|
||||
private void setUpIdToken(Map<String, Object> claims, Instant issuedAt, Instant expiresAt) {
|
||||
Map<String, Object> headers = new HashMap<>();
|
||||
headers.put("alg", "RS256");
|
||||
|
||||
Jwt idToken = new Jwt("id-token", issuedAt, expiresAt, headers, claims);
|
||||
Jwt idToken = jwt().claims(c -> c.putAll(claims)).build();
|
||||
|
||||
JwtDecoder jwtDecoder = mock(JwtDecoder.class);
|
||||
when(jwtDecoder.decode(anyString())).thenReturn(idToken);
|
||||
|
@ -16,12 +16,20 @@
|
||||
|
||||
package org.springframework.security.oauth2.client.oidc.authentication;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.security.oauth2.client.authentication.OAuth2AuthorizationCodeAuthenticationToken;
|
||||
@ -46,17 +54,13 @@ import org.springframework.security.oauth2.core.oidc.user.OidcUser;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.security.oauth2.jwt.JwtException;
|
||||
import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatCode;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.security.oauth2.jwt.TestJwts.jwt;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
@ -171,9 +175,7 @@ public class OidcAuthorizationCodeReactiveAuthenticationManagerTests {
|
||||
claims.put(IdTokenClaimNames.ISS, "https://issuer.example.com");
|
||||
claims.put(IdTokenClaimNames.SUB, "rob");
|
||||
claims.put(IdTokenClaimNames.AUD, Arrays.asList("client-id"));
|
||||
Instant issuedAt = Instant.now();
|
||||
Instant expiresAt = Instant.from(issuedAt).plusSeconds(3600);
|
||||
Jwt idToken = new Jwt("id-token", issuedAt, expiresAt, claims, claims);
|
||||
Jwt idToken = jwt().claims(c -> c.putAll(claims)).build();
|
||||
|
||||
when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(Mono.just(accessTokenResponse));
|
||||
when(this.userService.loadUser(any())).thenReturn(Mono.empty());
|
||||
@ -193,9 +195,7 @@ public class OidcAuthorizationCodeReactiveAuthenticationManagerTests {
|
||||
claims.put(IdTokenClaimNames.ISS, "https://issuer.example.com");
|
||||
claims.put(IdTokenClaimNames.SUB, "rob");
|
||||
claims.put(IdTokenClaimNames.AUD, Arrays.asList("client-id"));
|
||||
Instant issuedAt = Instant.now();
|
||||
Instant expiresAt = Instant.from(issuedAt).plusSeconds(3600);
|
||||
Jwt idToken = new Jwt("id-token", issuedAt, expiresAt, claims, claims);
|
||||
Jwt idToken = jwt().claims(c -> c.putAll(claims)).build();
|
||||
|
||||
when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(Mono.just(accessTokenResponse));
|
||||
DefaultOidcUser user = new DefaultOidcUser(AuthorityUtils.createAuthorityList("ROLE_USER"), this.idToken);
|
||||
@ -222,9 +222,7 @@ public class OidcAuthorizationCodeReactiveAuthenticationManagerTests {
|
||||
claims.put(IdTokenClaimNames.ISS, "https://issuer.example.com");
|
||||
claims.put(IdTokenClaimNames.SUB, "rob");
|
||||
claims.put(IdTokenClaimNames.AUD, Arrays.asList("client-id"));
|
||||
Instant issuedAt = Instant.now();
|
||||
Instant expiresAt = Instant.from(issuedAt).plusSeconds(3600);
|
||||
Jwt idToken = new Jwt("id-token", issuedAt, expiresAt, claims, claims);
|
||||
Jwt idToken = jwt().claims(c -> c.putAll(claims)).build();
|
||||
|
||||
when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(Mono.just(accessTokenResponse));
|
||||
DefaultOidcUser user = new DefaultOidcUser(AuthorityUtils.createAuthorityList("ROLE_USER"), this.idToken);
|
||||
@ -257,9 +255,7 @@ public class OidcAuthorizationCodeReactiveAuthenticationManagerTests {
|
||||
claims.put(IdTokenClaimNames.ISS, "https://issuer.example.com");
|
||||
claims.put(IdTokenClaimNames.SUB, "rob");
|
||||
claims.put(IdTokenClaimNames.AUD, Arrays.asList(clientRegistration.getClientId()));
|
||||
Instant issuedAt = Instant.now();
|
||||
Instant expiresAt = Instant.from(issuedAt).plusSeconds(3600);
|
||||
Jwt idToken = new Jwt("id-token", issuedAt, expiresAt, claims, claims);
|
||||
Jwt idToken = jwt().claims(c -> c.putAll(claims)).build();
|
||||
|
||||
when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(Mono.just(accessTokenResponse));
|
||||
DefaultOidcUser user = new DefaultOidcUser(AuthorityUtils.createAuthorityList("ROLE_USER"), this.idToken);
|
||||
|
@ -15,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();
|
||||
|
@ -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) {
|
||||
|
@ -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){
|
||||
|
@ -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) {
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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'
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user