Fix ID Token auth_time validation
Closes gh-18839
This commit is contained in:
+5
-1
@@ -300,7 +300,11 @@ public final class OidcAuthorizedClientRefreshedEventListener
|
||||
return;
|
||||
}
|
||||
|
||||
if (!idToken.getAuthenticatedAt().equals(existingOidcUser.getIdToken().getAuthenticatedAt())) {
|
||||
// The auth_time claim MUST represent the time of the original authentication OR
|
||||
// the most recent time when the end-user reauthenticated when "prompt=login" is
|
||||
// passed in the authentication request
|
||||
if (!idToken.getAuthenticatedAt().equals(existingOidcUser.getIdToken().getAuthenticatedAt())
|
||||
&& !idToken.getAuthenticatedAt().isAfter(existingOidcUser.getIdToken().getAuthenticatedAt())) {
|
||||
OAuth2Error oauth2Error = new OAuth2Error(INVALID_ID_TOKEN_ERROR_CODE, "Invalid authenticated at time",
|
||||
REFRESH_TOKEN_RESPONSE_ERROR_URI);
|
||||
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
|
||||
|
||||
+21
-3
@@ -419,8 +419,8 @@ public class OidcAuthorizedClientRefreshedEventListenerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onApplicationEventWhenIdTokenAuthenticatedAtDoesNotMatchThenThrowsOAuth2AuthenticationException() {
|
||||
Instant authTime = this.oidcUser.getAuthenticatedAt().plus(5, ChronoUnit.SECONDS);
|
||||
public void onApplicationEventWhenIdTokenAuthenticatedAtBeforeCurrentAuthenticatedAtThenThrowsOAuth2AuthenticationException() {
|
||||
Instant authTime = this.oidcUser.getAuthenticatedAt().minus(5, ChronoUnit.MINUTES);
|
||||
Jwt jwt = createJwt().claim(IdTokenClaimNames.AUTH_TIME, authTime).build();
|
||||
SecurityContextImpl securityContext = new SecurityContextImpl(this.authentication);
|
||||
given(this.securityContextHolderStrategy.getContext()).willReturn(securityContext);
|
||||
@@ -440,8 +440,26 @@ public class OidcAuthorizedClientRefreshedEventListenerTests {
|
||||
verifyNoInteractions(this.userService, this.applicationEventPublisher);
|
||||
}
|
||||
|
||||
// gh-18839
|
||||
@Test
|
||||
public void onApplicationEventWhenIdTokenAuthenticatedAtMatchesThenOidcUserRefreshedEventPublished() {
|
||||
public void onApplicationEventWhenIdTokenAuthenticatedAtAfterCurrentAuthenticatedAtThenOidcUserRefreshedEventPublished() {
|
||||
Instant authTime = this.oidcUser.getAuthenticatedAt().plus(5, ChronoUnit.MINUTES);
|
||||
Jwt jwt = createJwt().claim(IdTokenClaimNames.AUTH_TIME, authTime).build();
|
||||
SecurityContextImpl securityContext = new SecurityContextImpl(this.authentication);
|
||||
given(this.securityContextHolderStrategy.getContext()).willReturn(securityContext);
|
||||
given(this.jwtDecoder.decode(anyString())).willReturn(jwt);
|
||||
given(this.userService.loadUser(any(OidcUserRequest.class))).willReturn(this.oidcUser);
|
||||
|
||||
OAuth2AuthorizedClientRefreshedEvent authorizedClientRefreshedEvent = new OAuth2AuthorizedClientRefreshedEvent(
|
||||
this.accessTokenResponse, this.authorizedClient);
|
||||
this.eventListener.onApplicationEvent(authorizedClientRefreshedEvent);
|
||||
|
||||
verify(this.applicationEventPublisher).publishEvent(any(OidcUserRefreshedEvent.class));
|
||||
verifyNoMoreInteractions(this.applicationEventPublisher);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onApplicationEventWhenIdTokenAuthenticatedAtMatchesCurrentAuthenticatedAtThenOidcUserRefreshedEventPublished() {
|
||||
Instant authTime = this.authentication.getPrincipal().getAttribute(IdTokenClaimNames.AUTH_TIME);
|
||||
Jwt jwt = createJwt().claim(IdTokenClaimNames.AUTH_TIME, authTime).build();
|
||||
SecurityContextImpl securityContext = new SecurityContextImpl(this.authentication);
|
||||
|
||||
Reference in New Issue
Block a user