Skip to content

AbstractOAuth2Token modifications: #6808

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -694,8 +694,9 @@ private static JwtDecoder getJwtDecoder() {
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);
claims.put(IdTokenClaimNames.IAT, Instant.now());
claims.put(IdTokenClaimNames.EXP, Instant.now().plusSeconds(3600));
Jwt jwt = new Jwt("token123", Collections.singletonMap("header1", "value1"), claims);
JwtDecoder jwtDecoder = mock(JwtDecoder.class);
when(jwtDecoder.decode(any())).thenReturn(jwt);
return jwtDecoder;
Expand Down Expand Up @@ -738,8 +739,11 @@ private static OAuth2UserService<OAuth2UserRequest, OAuth2User> createOauth2User
}

private static OAuth2UserService<OidcUserRequest, OidcUser> createOidcUserService() {
OidcIdToken idToken = new OidcIdToken("token123", Instant.now(),
Instant.now().plusSeconds(3600), Collections.singletonMap(IdTokenClaimNames.SUB, "sub123"));
final Map<String, Object> claims = new HashMap<>();
claims.put(IdTokenClaimNames.SUB, "sub123");
claims.put(IdTokenClaimNames.IAT, Instant.now());
claims.put(IdTokenClaimNames.EXP, Instant.now().plusSeconds(3600));
OidcIdToken idToken = new OidcIdToken("token123", claims);
return request -> new DefaultOidcUser(
Collections.singleton(new OidcUserAuthority(idToken)), idToken);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.util.Base64;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
import javax.annotation.PreDestroy;
Expand Down Expand Up @@ -141,8 +142,14 @@ 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 Map<String, Object> JWT_CLAIMS() {
final Map<String, Object> claims = new HashMap<>();
claims.put(JwtClaimNames.SUB, JWT_SUBJECT);
claims.put(JwtClaimNames.IAT, Instant.MIN);
claims.put(JwtClaimNames.EXP,Instant.MAX);
return claims;
}
private static final Jwt JWT = new Jwt(JWT_TOKEN, JWT_HEADERS, JWT_CLAIMS());
private static final String JWK_SET_URI = "https://mock.org";
private static final JwtAuthenticationToken JWT_AUTHENTICATION_TOKEN =
new JwtAuthenticationToken(JWT, Collections.emptyList());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -343,8 +343,9 @@ private ReactiveJwtDecoder getJwtDecoder() {
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);
claims.put(IdTokenClaimNames.IAT, Instant.now());
claims.put(IdTokenClaimNames.EXP, Instant.now().plusSeconds(3600));
Jwt jwt = new Jwt("id-token", Collections.singletonMap("header1", "value1"), claims);
return Mono.just(jwt);
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@

package org.springframework.security.config.web.server;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.hamcrest.core.StringStartsWith.startsWith;
import static org.mockito.ArgumentMatchers.any;
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 java.io.IOException;
import java.math.BigInteger;
import java.security.KeyFactory;
Expand All @@ -27,21 +36,18 @@
import java.util.Base64;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.annotation.PreDestroy;

import okhttp3.mockwebserver.Dispatcher;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
import org.apache.http.HttpHeaders;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import reactor.core.publisher.Mono;

import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -62,6 +68,7 @@
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.JwtClaimNames;
import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
Expand All @@ -79,14 +86,11 @@
import org.springframework.web.reactive.DispatcherHandler;
import org.springframework.web.reactive.config.EnableWebFlux;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.hamcrest.core.StringStartsWith.startsWith;
import static org.mockito.ArgumentMatchers.any;
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 okhttp3.mockwebserver.Dispatcher;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
import reactor.core.publisher.Mono;

/**
* Tests for {@link org.springframework.security.config.web.server.ServerHttpSecurity.OAuth2ResourceServerSpec}
Expand All @@ -112,10 +116,18 @@ public class OAuth2ResourceServerSpecTests {
" }\n" +
" ]\n" +
"}\n";

private Map<String, Object> claims() {
final Map<String, Object> claims = new HashMap<>();
claims.put("sub", "user");
claims.put(JwtClaimNames.IAT, Instant.MIN);
claims.put(JwtClaimNames.EXP, Instant.MAX);
return claims;
}

private Jwt jwt = new Jwt("token", Instant.MIN, Instant.MAX,
private Jwt jwt = new Jwt("token",
Collections.singletonMap("alg", JwsAlgorithms.RS256),
Collections.singletonMap("sub", "user"));
claims());

private String clientId = "client";
private String clientSecret = "secret";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ private OidcIdToken createOidcToken(ClientRegistration clientRegistration, OAuth
OAuth2Error invalidIdTokenError = new OAuth2Error(INVALID_ID_TOKEN_ERROR_CODE, ex.getMessage(), null);
throw new OAuth2AuthenticationException(invalidIdTokenError, invalidIdTokenError.toString(), ex);
}
OidcIdToken idToken = new OidcIdToken(jwt.getTokenValue(), jwt.getIssuedAt(), jwt.getExpiresAt(), jwt.getClaims());
OidcIdToken idToken = new OidcIdToken(jwt.getTokenValue(), jwt.getClaims());
return idToken;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,6 @@ private Mono<OidcIdToken> createOidcToken(ClientRegistration clientRegistration,
ReactiveJwtDecoder jwtDecoder = this.jwtDecoderFactory.createDecoder(clientRegistration);
String rawIdToken = (String) accessTokenResponse.getAdditionalParameters().get(OidcParameterNames.ID_TOKEN);
return jwtDecoder.decode(rawIdToken)
.map(jwt -> new OidcIdToken(jwt.getTokenValue(), jwt.getIssuedAt(), jwt.getExpiresAt(), jwt.getClaims()));
.map(jwt -> new OidcIdToken(jwt.getTokenValue(), jwt.getClaims()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,15 @@
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames;

import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;

import java.time.Duration;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;

import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.when;
Expand All @@ -54,10 +58,16 @@ public class InMemoryReactiveOAuth2AuthorizedClientServiceTests {

private Authentication principal = new TestingAuthenticationToken(this.principalName, "notused");

private Map<String, Object> attributes(final Instant iat, final Instant exp) {
final Map<String, Object> attributes = new HashMap<String, Object>();
if(iat != null) attributes.put(IdTokenClaimNames.IAT, iat);
if(exp != null) attributes.put(IdTokenClaimNames.EXP, exp);
return attributes;
}

OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER,
"token",
Instant.now(),
Instant.now().plus(Duration.ofDays(1)));
attributes(Instant.now(), Instant.now().plus(Duration.ofDays(1))));

private ClientRegistration clientRegistration = ClientRegistration.withRegistrationId(this.clientRegistrationId)
.redirectUriTemplate("{baseUrl}/{action}/oauth2/code/{registrationId}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,8 +307,12 @@ private void setUpIdToken(Map<String, Object> claims) {
private void setUpIdToken(Map<String, Object> claims, Instant issuedAt, Instant expiresAt) {
Map<String, Object> headers = new HashMap<>();
headers.put("alg", "RS256");

Map<String, Object> attributes = new HashMap<>(claims);
headers.put(IdTokenClaimNames.IAT, issuedAt);
headers.put(IdTokenClaimNames.EXP, expiresAt);

Jwt idToken = new Jwt("id-token", issuedAt, expiresAt, headers, claims);
Jwt idToken = new Jwt("id-token", headers, Collections.unmodifiableMap(attributes));

JwtDecoder jwtDecoder = mock(JwtDecoder.class);
when(jwtDecoder.decode(anyString())).thenReturn(idToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,22 @@ public class OidcAuthorizationCodeReactiveAuthenticationManagerTests {
private OAuth2AuthorizationResponse.Builder authorizationResponseBldr = OAuth2AuthorizationResponse
.success("code")
.state("state");

private Map<String, Object> withInstants(final Map<String, Object> claims, final Instant iat, final Instant exp) {
Map<String, Object> attributes = new HashMap<>(claims);
if(iat != null) {
attributes.put(IdTokenClaimNames.IAT, iat);
}
if(exp != null) {
attributes.put(IdTokenClaimNames.EXP, exp);
}
return attributes;
}

private OidcIdToken idToken = new OidcIdToken("token123", Instant.now(),
Instant.now().plusSeconds(3600), Collections.singletonMap(IdTokenClaimNames.SUB, "sub123"));
private OidcIdToken idToken = new OidcIdToken("token123", withInstants(
Collections.singletonMap(IdTokenClaimNames.SUB, "sub123"),
Instant.now(),
Instant.now().plusSeconds(3600)));

private OidcAuthorizationCodeReactiveAuthenticationManager manager;

Expand Down Expand Up @@ -167,13 +180,15 @@ public void authenticationWhenOAuth2UserNotFoundThenEmpty() {
.additionalParameters(Collections.singletonMap(OidcParameterNames.ID_TOKEN, "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ."))
.build();

Instant issuedAt = Instant.now();
Instant expiresAt = Instant.from(issuedAt).plusSeconds(3600);
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);
Jwt idToken = new Jwt("id-token", issuedAt, expiresAt, claims, claims);
claims.put(IdTokenClaimNames.IAT, issuedAt);
claims.put(IdTokenClaimNames.EXP, expiresAt);
Jwt idToken = new Jwt("id-token", claims, claims);

when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(Mono.just(accessTokenResponse));
when(this.userService.loadUser(any())).thenReturn(Mono.empty());
Expand All @@ -189,13 +204,15 @@ public void authenticationWhenOAuth2UserFoundThenSuccess() {
.additionalParameters(Collections.singletonMap(OidcParameterNames.ID_TOKEN, this.idToken.getTokenValue()))
.build();

Instant issuedAt = Instant.now();
Instant expiresAt = Instant.from(issuedAt).plusSeconds(3600);
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);
Jwt idToken = new Jwt("id-token", issuedAt, expiresAt, claims, claims);
claims.put(IdTokenClaimNames.IAT, issuedAt);
claims.put(IdTokenClaimNames.EXP, expiresAt);
Jwt idToken = new Jwt("id-token", claims, claims);

when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(Mono.just(accessTokenResponse));
DefaultOidcUser user = new DefaultOidcUser(AuthorityUtils.createAuthorityList("ROLE_USER"), this.idToken);
Expand All @@ -218,13 +235,15 @@ public void authenticationWhenRefreshTokenThenRefreshTokenInAuthorizedClient() {
.refreshToken("refresh-token")
.build();

Instant issuedAt = Instant.now();
Instant expiresAt = Instant.from(issuedAt).plusSeconds(3600);
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);
Jwt idToken = new Jwt("id-token", issuedAt, expiresAt, claims, claims);
claims.put(IdTokenClaimNames.IAT, issuedAt);
claims.put(IdTokenClaimNames.EXP, expiresAt);
Jwt idToken = new Jwt("id-token", claims, claims);

when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(Mono.just(accessTokenResponse));
DefaultOidcUser user = new DefaultOidcUser(AuthorityUtils.createAuthorityList("ROLE_USER"), this.idToken);
Expand Down Expand Up @@ -253,13 +272,15 @@ public void authenticateWhenTokenSuccessResponseThenAdditionalParametersAddedToU
.additionalParameters(additionalParameters)
.build();

Instant issuedAt = Instant.now();
Instant expiresAt = Instant.from(issuedAt).plusSeconds(3600);
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(clientRegistration.getClientId()));
Instant issuedAt = Instant.now();
Instant expiresAt = Instant.from(issuedAt).plusSeconds(3600);
Jwt idToken = new Jwt("id-token", issuedAt, expiresAt, claims, claims);
claims.put(IdTokenClaimNames.IAT, issuedAt);
claims.put(IdTokenClaimNames.EXP, expiresAt);
Jwt idToken = new Jwt("id-token", claims, claims);

when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(Mono.just(accessTokenResponse));
DefaultOidcUser user = new DefaultOidcUser(AuthorityUtils.createAuthorityList("ROLE_USER"), this.idToken);
Expand Down
Loading