1
0
mirror of synced 2026-05-22 21:33:16 +00:00

Merge branch '7.0.x'

This commit is contained in:
Joe Grandja
2026-03-25 13:23:11 -04:00
2 changed files with 27 additions and 4 deletions
@@ -316,7 +316,12 @@ public final class OidcAuthorizedClientRefreshedEventListener
return;
}
if (!Objects.equals(idToken.getAuthenticatedAt(), 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())
&& (existingOidcUser.getIdToken().getAuthenticatedAt() == null
|| !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());
@@ -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);