1515import tools .jackson .databind .JsonNode ;
1616import tools .jackson .databind .ObjectMapper ;
1717
18+ import java .time .Instant ;
1819import java .util .Arrays ;
1920import java .util .Collections ;
2021import java .util .HashMap ;
22+ import java .util .Map ;
2123import java .util .Optional ;
2224import java .util .stream .Stream ;
2325
@@ -73,8 +75,9 @@ private Mono<OAuth2AuthenticatedPrincipal> parseAndValidate(String introspection
7375
7476 // Extract all claims from the introspection result.
7577 var attributes = objectMapper .convertValue (root , new TypeReference <HashMap <String , Object >>() {});
78+ normalizeTemporalClaims (attributes );
7679
77- // Build "scope" or "roles" claim in second argument, for role based authorization? Check token.
80+ // Authorities are intentionally empty; access is enforced by authenticated token validation .
7881 return Mono .just (new OAuth2IntrospectionAuthenticatedPrincipal (attributes , Collections .emptyList ()));
7982
8083 } catch (Exception e ) {
@@ -84,6 +87,30 @@ private Mono<OAuth2AuthenticatedPrincipal> parseAndValidate(String introspection
8487
8588 }
8689
90+ private void normalizeTemporalClaims (Map <String , Object > attributes ) {
91+ normalizeTemporalClaim (attributes , "exp" );
92+ normalizeTemporalClaim (attributes , "iat" );
93+ normalizeTemporalClaim (attributes , "nbf" );
94+ }
95+
96+ private void normalizeTemporalClaim (Map <String , Object > attributes , String claimName ) {
97+ Optional
98+ .ofNullable (attributes .get (claimName ))
99+ .ifPresent (value -> {
100+ if (value instanceof Number numberValue ) {
101+ attributes .put (claimName , Instant .ofEpochSecond (numberValue .longValue ()));
102+ return ;
103+ }
104+ if (value instanceof String stringValue ) {
105+ try {
106+ attributes .put (claimName , Instant .ofEpochSecond (Long .parseLong (stringValue )));
107+ } catch (NumberFormatException ignored ) {
108+ log .warn ("Could not parse claim '{}' as epoch seconds" , claimName );
109+ }
110+ }
111+ });
112+ }
113+
87114
88115 /**
89116 * Applies opaque token-based resource server security to the given {@link ServerHttpSecurity} builder.
0 commit comments