fix/MNT-24542 class cast exception (#3092)

* [MNT-24542] fix class cast exception

* pre-commit-issue

* removed else part

* address review comments

* fix-conflict
This commit is contained in:
Manish Kumar
2025-01-09 14:07:27 +05:30
committed by GitHub
parent f9be67add6
commit 38b796f9ce

View File

@@ -1,344 +1,354 @@
/* /*
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited * Copyright (C) 2005 - 2025 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is * the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms: * provided under the following open source license terms:
* *
* Alfresco is free software: you can redistribute it and/or modify * Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by * it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Alfresco is distributed in the hope that it will be useful, * Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. * GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L% * #L%
*/ */
package org.alfresco.repo.security.authentication.identityservice; package org.alfresco.repo.security.authentication.identityservice;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
import static org.alfresco.repo.security.authentication.identityservice.IdentityServiceMetadataKey.AUDIENCE; import static org.alfresco.repo.security.authentication.identityservice.IdentityServiceMetadataKey.AUDIENCE;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.time.Instant; import java.time.Instant;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.function.Predicate; import java.util.function.Predicate;
import com.nimbusds.oauth2.sdk.ParseException; import com.nimbusds.oauth2.sdk.ErrorObject;
import com.nimbusds.oauth2.sdk.token.BearerAccessToken; import com.nimbusds.oauth2.sdk.ParseException;
import com.nimbusds.openid.connect.sdk.UserInfoRequest; import com.nimbusds.oauth2.sdk.token.BearerAccessToken;
import com.nimbusds.openid.connect.sdk.UserInfoResponse; import com.nimbusds.openid.connect.sdk.UserInfoErrorResponse;
import com.nimbusds.openid.connect.sdk.UserInfoSuccessResponse; import com.nimbusds.openid.connect.sdk.UserInfoRequest;
import com.nimbusds.openid.connect.sdk.UserInfoResponse;
import org.apache.commons.logging.Log; import com.nimbusds.openid.connect.sdk.UserInfoSuccessResponse;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.Log;
import org.springframework.core.convert.converter.Converter; import org.apache.commons.logging.LogFactory;
import org.springframework.security.oauth2.client.endpoint.AbstractOAuth2AuthorizationGrantRequest; import org.springframework.core.convert.converter.Converter;
import org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient; import org.springframework.security.oauth2.client.endpoint.AbstractOAuth2AuthorizationGrantRequest;
import org.springframework.security.oauth2.client.endpoint.DefaultPasswordTokenResponseClient; import org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.DefaultRefreshTokenTokenResponseClient; import org.springframework.security.oauth2.client.endpoint.DefaultPasswordTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient; import org.springframework.security.oauth2.client.endpoint.DefaultRefreshTokenTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest; import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequest; import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest;
import org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequestEntityConverter; import org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequest;
import org.springframework.security.oauth2.client.endpoint.OAuth2RefreshTokenGrantRequest; import org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequestEntityConverter;
import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.client.endpoint.OAuth2RefreshTokenGrantRequest;
import org.springframework.security.oauth2.client.registration.ClientRegistration.ProviderDetails; import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.core.AbstractOAuth2Token; import org.springframework.security.oauth2.client.registration.ClientRegistration.ProviderDetails;
import org.springframework.security.oauth2.core.AuthorizationGrantType; import org.springframework.security.oauth2.core.AbstractOAuth2Token;
import org.springframework.security.oauth2.core.OAuth2AccessToken; import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.OAuth2AccessToken.TokenType; import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.oauth2.core.OAuth2AuthorizationException; import org.springframework.security.oauth2.core.OAuth2AccessToken.TokenType;
import org.springframework.security.oauth2.core.OAuth2RefreshToken; import org.springframework.security.oauth2.core.OAuth2AuthorizationException;
import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; import org.springframework.security.oauth2.core.OAuth2RefreshToken;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationExchange; import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationExchange;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationResponse; import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
import org.springframework.security.oauth2.jwt.Jwt; import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationResponse;
import org.springframework.security.oauth2.jwt.JwtDecoder; import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.util.LinkedMultiValueMap; import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.util.MultiValueMap; import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.client.RestOperations; import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestOperations;
class SpringBasedIdentityServiceFacade implements IdentityServiceFacade
{ class SpringBasedIdentityServiceFacade implements IdentityServiceFacade
private static final Log LOGGER = LogFactory.getLog(SpringBasedIdentityServiceFacade.class); {
private static final Instant SOME_INSIGNIFICANT_DATE_IN_THE_PAST = Instant.MIN.plusSeconds(12345); private static final Log LOGGER = LogFactory.getLog(SpringBasedIdentityServiceFacade.class);
private final Map<AuthorizationGrantType, OAuth2AccessTokenResponseClient> clients; private static final Instant SOME_INSIGNIFICANT_DATE_IN_THE_PAST = Instant.MIN.plusSeconds(12345);
private final ClientRegistration clientRegistration; private final Map<AuthorizationGrantType, OAuth2AccessTokenResponseClient> clients;
private final JwtDecoder jwtDecoder; private final ClientRegistration clientRegistration;
private final JwtDecoder jwtDecoder;
SpringBasedIdentityServiceFacade(RestOperations restOperations, ClientRegistration clientRegistration,
JwtDecoder jwtDecoder) SpringBasedIdentityServiceFacade(RestOperations restOperations, ClientRegistration clientRegistration,
{ JwtDecoder jwtDecoder)
requireNonNull(restOperations); {
this.clientRegistration = requireNonNull(clientRegistration); requireNonNull(restOperations);
this.jwtDecoder = requireNonNull(jwtDecoder); this.clientRegistration = requireNonNull(clientRegistration);
this.clients = Map.of( this.jwtDecoder = requireNonNull(jwtDecoder);
AuthorizationGrantType.AUTHORIZATION_CODE, createAuthorizationCodeClient(restOperations), this.clients = Map.of(
AuthorizationGrantType.REFRESH_TOKEN, createRefreshTokenClient(restOperations), AuthorizationGrantType.AUTHORIZATION_CODE, createAuthorizationCodeClient(restOperations),
AuthorizationGrantType.PASSWORD, createPasswordClient(restOperations, clientRegistration)); AuthorizationGrantType.REFRESH_TOKEN, createRefreshTokenClient(restOperations),
} AuthorizationGrantType.PASSWORD, createPasswordClient(restOperations, clientRegistration));
}
@Override
public AccessTokenAuthorization authorize(AuthorizationGrant authorizationGrant) @Override
{ public AccessTokenAuthorization authorize(AuthorizationGrant authorizationGrant)
final AbstractOAuth2AuthorizationGrantRequest request = createRequest(authorizationGrant); {
final OAuth2AccessTokenResponseClient client = getClient(request); final AbstractOAuth2AuthorizationGrantRequest request = createRequest(authorizationGrant);
final OAuth2AccessTokenResponseClient client = getClient(request);
final OAuth2AccessTokenResponse response;
try final OAuth2AccessTokenResponse response;
{ try
response = client.getTokenResponse(request); {
} response = client.getTokenResponse(request);
catch (OAuth2AuthorizationException e) }
{ catch (OAuth2AuthorizationException e)
LOGGER.debug("Failed to authorize against Authorization Server. Reason: " + e.getError() + "."); {
throw new AuthorizationException("Failed to obtain access token. " + e.getError(), e); LOGGER.debug("Failed to authorize against Authorization Server. Reason: " + e.getError() + ".");
} throw new AuthorizationException("Failed to obtain access token. " + e.getError(), e);
catch (RuntimeException e) }
{ catch (RuntimeException e)
LOGGER.warn("Failed to authorize against Authorization Server. Reason: " + e.getMessage()); {
throw new AuthorizationException("Failed to obtain access token.", e); LOGGER.warn("Failed to authorize against Authorization Server. Reason: " + e.getMessage());
} throw new AuthorizationException("Failed to obtain access token.", e);
}
return new SpringAccessTokenAuthorization(response);
} return new SpringAccessTokenAuthorization(response);
}
@Override
public Optional<OIDCUserInfo> getUserInfo(String tokenParameter, String principalAttribute) @Override
{ public Optional<OIDCUserInfo> getUserInfo(String tokenParameter, String principalAttribute)
return Optional.ofNullable(tokenParameter) {
.filter(Predicate.not(String::isEmpty)) return Optional.ofNullable(tokenParameter)
.flatMap(token -> Optional.ofNullable(clientRegistration) .filter(Predicate.not(String::isEmpty))
.map(ClientRegistration::getProviderDetails) .flatMap(token -> Optional.ofNullable(clientRegistration)
.map(ClientRegistration.ProviderDetails::getUserInfoEndpoint) .map(ClientRegistration::getProviderDetails)
.map(ClientRegistration.ProviderDetails.UserInfoEndpoint::getUri) .map(ClientRegistration.ProviderDetails::getUserInfoEndpoint)
.flatMap(uri -> { .map(ClientRegistration.ProviderDetails.UserInfoEndpoint::getUri)
try .flatMap(uri -> {
{ try
return Optional.of( {
new UserInfoRequest(new URI(uri), new BearerAccessToken(token)).toHTTPRequest().send()); return Optional.of(
} new UserInfoRequest(new URI(uri), new BearerAccessToken(token)).toHTTPRequest().send());
catch (IOException | URISyntaxException e) }
{ catch (IOException | URISyntaxException e)
LOGGER.warn("Failed to get user information. Reason: " + e.getMessage()); {
return Optional.empty(); LOGGER.warn("Failed to get user information. Reason: " + e.getMessage());
} return Optional.empty();
}) }
.flatMap(httpResponse -> { })
try .flatMap(httpResponse -> {
{ try
return Optional.of(UserInfoResponse.parse(httpResponse)); {
} UserInfoResponse userInfoResponse = UserInfoResponse.parse(httpResponse);
catch (ParseException e)
{ if (userInfoResponse instanceof UserInfoErrorResponse userInfoErrorResponse)
LOGGER.warn("Failed to parse user info response. Reason: " + e.getMessage()); {
return Optional.empty(); String errorMessage = Optional.ofNullable(userInfoErrorResponse.getErrorObject())
} .map(ErrorObject::getDescription)
}) .orElse("No error description found");
.map(UserInfoResponse::toSuccessResponse) LOGGER.warn("User Info Request failed: " + errorMessage);
.map(UserInfoSuccessResponse::getUserInfo)) throw new UserInfoException(errorMessage);
.map(userInfo -> new OIDCUserInfo(userInfo.getStringClaim(principalAttribute), userInfo.getGivenName(), }
userInfo.getFamilyName(), userInfo.getEmailAddress())); return Optional.of(userInfoResponse);
} }
catch (ParseException e)
@Override {
public ClientRegistration getClientRegistration() LOGGER.warn("Failed to parse user info response. Reason: " + e.getMessage());
{ return Optional.empty();
return clientRegistration; }
} })
.map(UserInfoResponse::toSuccessResponse)
@Override .map(UserInfoSuccessResponse::getUserInfo))
public DecodedAccessToken decodeToken(String token) .map(userInfo -> new OIDCUserInfo(userInfo.getStringClaim(principalAttribute), userInfo.getGivenName(),
{ userInfo.getFamilyName(), userInfo.getEmailAddress()));
final Jwt validToken; }
try
{ @Override
validToken = jwtDecoder.decode(token); public ClientRegistration getClientRegistration()
} {
catch (RuntimeException e) return clientRegistration;
{ }
throw new TokenDecodingException("Failed to decode token. " + e.getMessage(), e);
} @Override
if (LOGGER.isDebugEnabled()) public DecodedAccessToken decodeToken(String token)
{ {
LOGGER.debug("Bearer token outcome: " + validToken.getClaims()); final Jwt validToken;
} try
return new SpringDecodedAccessToken(validToken); {
} validToken = jwtDecoder.decode(token);
}
private AbstractOAuth2AuthorizationGrantRequest createRequest(AuthorizationGrant grant) catch (RuntimeException e)
{ {
if (grant.isPassword()) throw new TokenDecodingException("Failed to decode token. " + e.getMessage(), e);
{ }
return new OAuth2PasswordGrantRequest(clientRegistration, grant.getUsername(), grant.getPassword()); if (LOGGER.isDebugEnabled())
} {
LOGGER.debug("Bearer token outcome: " + validToken.getClaims());
if (grant.isRefreshToken()) }
{ return new SpringDecodedAccessToken(validToken);
final OAuth2AccessToken expiredAccessToken = new OAuth2AccessToken( }
TokenType.BEARER,
"JUST_FOR_FULFILLING_THE_SPRING_API", private AbstractOAuth2AuthorizationGrantRequest createRequest(AuthorizationGrant grant)
SOME_INSIGNIFICANT_DATE_IN_THE_PAST, {
SOME_INSIGNIFICANT_DATE_IN_THE_PAST.plusSeconds(1)); if (grant.isPassword())
final OAuth2RefreshToken refreshToken = new OAuth2RefreshToken(grant.getRefreshToken(), null); {
return new OAuth2PasswordGrantRequest(clientRegistration, grant.getUsername(), grant.getPassword());
return new OAuth2RefreshTokenGrantRequest(clientRegistration, expiredAccessToken, refreshToken, }
clientRegistration.getScopes());
} if (grant.isRefreshToken())
{
if (grant.isAuthorizationCode()) final OAuth2AccessToken expiredAccessToken = new OAuth2AccessToken(
{ TokenType.BEARER,
final OAuth2AuthorizationExchange authzExchange = new OAuth2AuthorizationExchange( "JUST_FOR_FULFILLING_THE_SPRING_API",
OAuth2AuthorizationRequest.authorizationCode() SOME_INSIGNIFICANT_DATE_IN_THE_PAST,
.clientId(clientRegistration.getClientId()) SOME_INSIGNIFICANT_DATE_IN_THE_PAST.plusSeconds(1));
.authorizationUri(clientRegistration.getProviderDetails().getAuthorizationUri()) final OAuth2RefreshToken refreshToken = new OAuth2RefreshToken(grant.getRefreshToken(), null);
.redirectUri(grant.getRedirectUri())
.scopes(clientRegistration.getScopes()) return new OAuth2RefreshTokenGrantRequest(clientRegistration, expiredAccessToken, refreshToken,
.build(), clientRegistration.getScopes());
OAuth2AuthorizationResponse.success(grant.getAuthorizationCode()) }
.redirectUri(grant.getRedirectUri())
.build() if (grant.isAuthorizationCode())
); {
return new OAuth2AuthorizationCodeGrantRequest(clientRegistration, authzExchange); final OAuth2AuthorizationExchange authzExchange = new OAuth2AuthorizationExchange(
} OAuth2AuthorizationRequest.authorizationCode()
.clientId(clientRegistration.getClientId())
throw new UnsupportedOperationException("Unsupported grant type."); .authorizationUri(clientRegistration.getProviderDetails().getAuthorizationUri())
} .redirectUri(grant.getRedirectUri())
.scopes(clientRegistration.getScopes())
private OAuth2AccessTokenResponseClient getClient(AbstractOAuth2AuthorizationGrantRequest request) .build(),
{ OAuth2AuthorizationResponse.success(grant.getAuthorizationCode())
final AuthorizationGrantType grantType = request.getGrantType(); .redirectUri(grant.getRedirectUri())
final OAuth2AccessTokenResponseClient client = clients.get(grantType); .build());
if (client == null) return new OAuth2AuthorizationCodeGrantRequest(clientRegistration, authzExchange);
{ }
throw new UnsupportedOperationException("Unsupported grant type `" + grantType + "`.");
} throw new UnsupportedOperationException("Unsupported grant type.");
return client; }
}
private OAuth2AccessTokenResponseClient getClient(AbstractOAuth2AuthorizationGrantRequest request)
private static OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> createAuthorizationCodeClient( {
RestOperations rest) final AuthorizationGrantType grantType = request.getGrantType();
{ final OAuth2AccessTokenResponseClient client = clients.get(grantType);
final DefaultAuthorizationCodeTokenResponseClient client = new DefaultAuthorizationCodeTokenResponseClient(); if (client == null)
client.setRestOperations(rest); {
return client; throw new UnsupportedOperationException("Unsupported grant type `" + grantType + "`.");
} }
return client;
private static OAuth2AccessTokenResponseClient<OAuth2RefreshTokenGrantRequest> createRefreshTokenClient( }
RestOperations rest)
{ private static OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> createAuthorizationCodeClient(
final DefaultRefreshTokenTokenResponseClient client = new DefaultRefreshTokenTokenResponseClient(); RestOperations rest)
client.setRestOperations(rest); {
return client; final DefaultAuthorizationCodeTokenResponseClient client = new DefaultAuthorizationCodeTokenResponseClient();
} client.setRestOperations(rest);
return client;
private static OAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> createPasswordClient(RestOperations rest, }
ClientRegistration clientRegistration)
{ private static OAuth2AccessTokenResponseClient<OAuth2RefreshTokenGrantRequest> createRefreshTokenClient(
final DefaultPasswordTokenResponseClient client = new DefaultPasswordTokenResponseClient(); RestOperations rest)
client.setRestOperations(rest); {
Optional.of(clientRegistration) final DefaultRefreshTokenTokenResponseClient client = new DefaultRefreshTokenTokenResponseClient();
.map(ClientRegistration::getProviderDetails) client.setRestOperations(rest);
.map(ProviderDetails::getConfigurationMetadata) return client;
.map(metadata -> metadata.get(AUDIENCE.getValue())) }
.filter(String.class::isInstance)
.map(String.class::cast) private static OAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> createPasswordClient(RestOperations rest,
.ifPresent(audienceValue -> { ClientRegistration clientRegistration)
final OAuth2PasswordGrantRequestEntityConverter requestEntityConverter = new OAuth2PasswordGrantRequestEntityConverter(); {
requestEntityConverter.addParametersConverter(audienceParameterConverter(audienceValue)); final DefaultPasswordTokenResponseClient client = new DefaultPasswordTokenResponseClient();
client.setRequestEntityConverter(requestEntityConverter); client.setRestOperations(rest);
}); Optional.of(clientRegistration)
return client; .map(ClientRegistration::getProviderDetails)
} .map(ProviderDetails::getConfigurationMetadata)
.map(metadata -> metadata.get(AUDIENCE.getValue()))
private static Converter<OAuth2PasswordGrantRequest, MultiValueMap<String, String>> audienceParameterConverter( .filter(String.class::isInstance)
String audienceValue) .map(String.class::cast)
{ .ifPresent(audienceValue -> {
return (grantRequest) -> { final OAuth2PasswordGrantRequestEntityConverter requestEntityConverter = new OAuth2PasswordGrantRequestEntityConverter();
MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>(); requestEntityConverter.addParametersConverter(audienceParameterConverter(audienceValue));
parameters.set("audience", audienceValue); client.setRequestEntityConverter(requestEntityConverter);
});
return parameters; return client;
}; }
}
private static Converter<OAuth2PasswordGrantRequest, MultiValueMap<String, String>> audienceParameterConverter(
private static class SpringAccessTokenAuthorization implements AccessTokenAuthorization String audienceValue)
{ {
private final OAuth2AccessTokenResponse tokenResponse; return (grantRequest) -> {
MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();
private SpringAccessTokenAuthorization(OAuth2AccessTokenResponse tokenResponse) parameters.set("audience", audienceValue);
{
this.tokenResponse = requireNonNull(tokenResponse); return parameters;
} };
}
@Override
public AccessToken getAccessToken() private static class SpringAccessTokenAuthorization implements AccessTokenAuthorization
{ {
return new SpringAccessToken(tokenResponse.getAccessToken()); private final OAuth2AccessTokenResponse tokenResponse;
}
private SpringAccessTokenAuthorization(OAuth2AccessTokenResponse tokenResponse)
@Override {
public String getRefreshTokenValue() this.tokenResponse = requireNonNull(tokenResponse);
{ }
return Optional.of(tokenResponse)
.map(OAuth2AccessTokenResponse::getRefreshToken) @Override
.map(AbstractOAuth2Token::getTokenValue) public AccessToken getAccessToken()
.orElse(null); {
} return new SpringAccessToken(tokenResponse.getAccessToken());
} }
private static class SpringAccessToken implements AccessToken @Override
{ public String getRefreshTokenValue()
private final AbstractOAuth2Token token; {
return Optional.of(tokenResponse)
private SpringAccessToken(AbstractOAuth2Token token) .map(OAuth2AccessTokenResponse::getRefreshToken)
{ .map(AbstractOAuth2Token::getTokenValue)
this.token = requireNonNull(token); .orElse(null);
} }
}
@Override
public String getTokenValue() private static class SpringAccessToken implements AccessToken
{ {
return token.getTokenValue(); private final AbstractOAuth2Token token;
}
private SpringAccessToken(AbstractOAuth2Token token)
@Override {
public Instant getExpiresAt() this.token = requireNonNull(token);
{ }
return token.getExpiresAt();
} @Override
} public String getTokenValue()
{
private static class SpringDecodedAccessToken extends SpringAccessToken implements DecodedAccessToken return token.getTokenValue();
{ }
private final Jwt jwt;
@Override
private SpringDecodedAccessToken(Jwt jwt) public Instant getExpiresAt()
{ {
super(jwt); return token.getExpiresAt();
this.jwt = jwt; }
} }
@Override private static class SpringDecodedAccessToken extends SpringAccessToken implements DecodedAccessToken
public Object getClaim(String claim) {
{ private final Jwt jwt;
return jwt.getClaim(claim);
} private SpringDecodedAccessToken(Jwt jwt)
} {
} super(jwt);
this.jwt = jwt;
}
@Override
public Object getClaim(String claim)
{
return jwt.getClaim(claim);
}
}
}