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

@@ -38,12 +38,13 @@ 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.ErrorObject;
import com.nimbusds.oauth2.sdk.ParseException; import com.nimbusds.oauth2.sdk.ParseException;
import com.nimbusds.oauth2.sdk.token.BearerAccessToken; import com.nimbusds.oauth2.sdk.token.BearerAccessToken;
import com.nimbusds.openid.connect.sdk.UserInfoErrorResponse;
import com.nimbusds.openid.connect.sdk.UserInfoRequest; import com.nimbusds.openid.connect.sdk.UserInfoRequest;
import com.nimbusds.openid.connect.sdk.UserInfoResponse; import com.nimbusds.openid.connect.sdk.UserInfoResponse;
import com.nimbusds.openid.connect.sdk.UserInfoSuccessResponse; import com.nimbusds.openid.connect.sdk.UserInfoSuccessResponse;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.Converter;
@@ -83,15 +84,15 @@ class SpringBasedIdentityServiceFacade implements IdentityServiceFacade
private final JwtDecoder jwtDecoder; private final JwtDecoder jwtDecoder;
SpringBasedIdentityServiceFacade(RestOperations restOperations, ClientRegistration clientRegistration, SpringBasedIdentityServiceFacade(RestOperations restOperations, ClientRegistration clientRegistration,
JwtDecoder jwtDecoder) JwtDecoder jwtDecoder)
{ {
requireNonNull(restOperations); requireNonNull(restOperations);
this.clientRegistration = requireNonNull(clientRegistration); this.clientRegistration = requireNonNull(clientRegistration);
this.jwtDecoder = requireNonNull(jwtDecoder); this.jwtDecoder = requireNonNull(jwtDecoder);
this.clients = Map.of( this.clients = Map.of(
AuthorizationGrantType.AUTHORIZATION_CODE, createAuthorizationCodeClient(restOperations), AuthorizationGrantType.AUTHORIZATION_CODE, createAuthorizationCodeClient(restOperations),
AuthorizationGrantType.REFRESH_TOKEN, createRefreshTokenClient(restOperations), AuthorizationGrantType.REFRESH_TOKEN, createRefreshTokenClient(restOperations),
AuthorizationGrantType.PASSWORD, createPasswordClient(restOperations, clientRegistration)); AuthorizationGrantType.PASSWORD, createPasswordClient(restOperations, clientRegistration));
} }
@Override @Override
@@ -123,38 +124,48 @@ class SpringBasedIdentityServiceFacade implements IdentityServiceFacade
public Optional<OIDCUserInfo> getUserInfo(String tokenParameter, String principalAttribute) public Optional<OIDCUserInfo> getUserInfo(String tokenParameter, String principalAttribute)
{ {
return Optional.ofNullable(tokenParameter) return Optional.ofNullable(tokenParameter)
.filter(Predicate.not(String::isEmpty)) .filter(Predicate.not(String::isEmpty))
.flatMap(token -> Optional.ofNullable(clientRegistration) .flatMap(token -> Optional.ofNullable(clientRegistration)
.map(ClientRegistration::getProviderDetails) .map(ClientRegistration::getProviderDetails)
.map(ClientRegistration.ProviderDetails::getUserInfoEndpoint) .map(ClientRegistration.ProviderDetails::getUserInfoEndpoint)
.map(ClientRegistration.ProviderDetails.UserInfoEndpoint::getUri) .map(ClientRegistration.ProviderDetails.UserInfoEndpoint::getUri)
.flatMap(uri -> { .flatMap(uri -> {
try try
{ {
return Optional.of( return Optional.of(
new UserInfoRequest(new URI(uri), new BearerAccessToken(token)).toHTTPRequest().send()); 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()); LOGGER.warn("Failed to get user information. Reason: " + e.getMessage());
return Optional.empty(); return Optional.empty();
} }
}) })
.flatMap(httpResponse -> { .flatMap(httpResponse -> {
try 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()); String errorMessage = Optional.ofNullable(userInfoErrorResponse.getErrorObject())
return Optional.empty(); .map(ErrorObject::getDescription)
} .orElse("No error description found");
}) LOGGER.warn("User Info Request failed: " + errorMessage);
.map(UserInfoResponse::toSuccessResponse) throw new UserInfoException(errorMessage);
.map(UserInfoSuccessResponse::getUserInfo)) }
.map(userInfo -> new OIDCUserInfo(userInfo.getStringClaim(principalAttribute), userInfo.getGivenName(), return Optional.of(userInfoResponse);
userInfo.getFamilyName(), userInfo.getEmailAddress())); }
catch (ParseException e)
{
LOGGER.warn("Failed to parse user info response. Reason: " + e.getMessage());
return Optional.empty();
}
})
.map(UserInfoResponse::toSuccessResponse)
.map(UserInfoSuccessResponse::getUserInfo))
.map(userInfo -> new OIDCUserInfo(userInfo.getStringClaim(principalAttribute), userInfo.getGivenName(),
userInfo.getFamilyName(), userInfo.getEmailAddress()));
} }
@Override @Override
@@ -192,29 +203,28 @@ class SpringBasedIdentityServiceFacade implements IdentityServiceFacade
if (grant.isRefreshToken()) if (grant.isRefreshToken())
{ {
final OAuth2AccessToken expiredAccessToken = new OAuth2AccessToken( final OAuth2AccessToken expiredAccessToken = new OAuth2AccessToken(
TokenType.BEARER, TokenType.BEARER,
"JUST_FOR_FULFILLING_THE_SPRING_API", "JUST_FOR_FULFILLING_THE_SPRING_API",
SOME_INSIGNIFICANT_DATE_IN_THE_PAST, SOME_INSIGNIFICANT_DATE_IN_THE_PAST,
SOME_INSIGNIFICANT_DATE_IN_THE_PAST.plusSeconds(1)); SOME_INSIGNIFICANT_DATE_IN_THE_PAST.plusSeconds(1));
final OAuth2RefreshToken refreshToken = new OAuth2RefreshToken(grant.getRefreshToken(), null); final OAuth2RefreshToken refreshToken = new OAuth2RefreshToken(grant.getRefreshToken(), null);
return new OAuth2RefreshTokenGrantRequest(clientRegistration, expiredAccessToken, refreshToken, return new OAuth2RefreshTokenGrantRequest(clientRegistration, expiredAccessToken, refreshToken,
clientRegistration.getScopes()); clientRegistration.getScopes());
} }
if (grant.isAuthorizationCode()) if (grant.isAuthorizationCode())
{ {
final OAuth2AuthorizationExchange authzExchange = new OAuth2AuthorizationExchange( final OAuth2AuthorizationExchange authzExchange = new OAuth2AuthorizationExchange(
OAuth2AuthorizationRequest.authorizationCode() OAuth2AuthorizationRequest.authorizationCode()
.clientId(clientRegistration.getClientId()) .clientId(clientRegistration.getClientId())
.authorizationUri(clientRegistration.getProviderDetails().getAuthorizationUri()) .authorizationUri(clientRegistration.getProviderDetails().getAuthorizationUri())
.redirectUri(grant.getRedirectUri()) .redirectUri(grant.getRedirectUri())
.scopes(clientRegistration.getScopes()) .scopes(clientRegistration.getScopes())
.build(), .build(),
OAuth2AuthorizationResponse.success(grant.getAuthorizationCode()) OAuth2AuthorizationResponse.success(grant.getAuthorizationCode())
.redirectUri(grant.getRedirectUri()) .redirectUri(grant.getRedirectUri())
.build() .build());
);
return new OAuth2AuthorizationCodeGrantRequest(clientRegistration, authzExchange); return new OAuth2AuthorizationCodeGrantRequest(clientRegistration, authzExchange);
} }
@@ -233,7 +243,7 @@ class SpringBasedIdentityServiceFacade implements IdentityServiceFacade
} }
private static OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> createAuthorizationCodeClient( private static OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> createAuthorizationCodeClient(
RestOperations rest) RestOperations rest)
{ {
final DefaultAuthorizationCodeTokenResponseClient client = new DefaultAuthorizationCodeTokenResponseClient(); final DefaultAuthorizationCodeTokenResponseClient client = new DefaultAuthorizationCodeTokenResponseClient();
client.setRestOperations(rest); client.setRestOperations(rest);
@@ -241,7 +251,7 @@ class SpringBasedIdentityServiceFacade implements IdentityServiceFacade
} }
private static OAuth2AccessTokenResponseClient<OAuth2RefreshTokenGrantRequest> createRefreshTokenClient( private static OAuth2AccessTokenResponseClient<OAuth2RefreshTokenGrantRequest> createRefreshTokenClient(
RestOperations rest) RestOperations rest)
{ {
final DefaultRefreshTokenTokenResponseClient client = new DefaultRefreshTokenTokenResponseClient(); final DefaultRefreshTokenTokenResponseClient client = new DefaultRefreshTokenTokenResponseClient();
client.setRestOperations(rest); client.setRestOperations(rest);
@@ -249,26 +259,26 @@ class SpringBasedIdentityServiceFacade implements IdentityServiceFacade
} }
private static OAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> createPasswordClient(RestOperations rest, private static OAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> createPasswordClient(RestOperations rest,
ClientRegistration clientRegistration) ClientRegistration clientRegistration)
{ {
final DefaultPasswordTokenResponseClient client = new DefaultPasswordTokenResponseClient(); final DefaultPasswordTokenResponseClient client = new DefaultPasswordTokenResponseClient();
client.setRestOperations(rest); client.setRestOperations(rest);
Optional.of(clientRegistration) Optional.of(clientRegistration)
.map(ClientRegistration::getProviderDetails) .map(ClientRegistration::getProviderDetails)
.map(ProviderDetails::getConfigurationMetadata) .map(ProviderDetails::getConfigurationMetadata)
.map(metadata -> metadata.get(AUDIENCE.getValue())) .map(metadata -> metadata.get(AUDIENCE.getValue()))
.filter(String.class::isInstance) .filter(String.class::isInstance)
.map(String.class::cast) .map(String.class::cast)
.ifPresent(audienceValue -> { .ifPresent(audienceValue -> {
final OAuth2PasswordGrantRequestEntityConverter requestEntityConverter = new OAuth2PasswordGrantRequestEntityConverter(); final OAuth2PasswordGrantRequestEntityConverter requestEntityConverter = new OAuth2PasswordGrantRequestEntityConverter();
requestEntityConverter.addParametersConverter(audienceParameterConverter(audienceValue)); requestEntityConverter.addParametersConverter(audienceParameterConverter(audienceValue));
client.setRequestEntityConverter(requestEntityConverter); client.setRequestEntityConverter(requestEntityConverter);
}); });
return client; return client;
} }
private static Converter<OAuth2PasswordGrantRequest, MultiValueMap<String, String>> audienceParameterConverter( private static Converter<OAuth2PasswordGrantRequest, MultiValueMap<String, String>> audienceParameterConverter(
String audienceValue) String audienceValue)
{ {
return (grantRequest) -> { return (grantRequest) -> {
MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>(); MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();
@@ -297,9 +307,9 @@ class SpringBasedIdentityServiceFacade implements IdentityServiceFacade
public String getRefreshTokenValue() public String getRefreshTokenValue()
{ {
return Optional.of(tokenResponse) return Optional.of(tokenResponse)
.map(OAuth2AccessTokenResponse::getRefreshToken) .map(OAuth2AccessTokenResponse::getRefreshToken)
.map(AbstractOAuth2Token::getTokenValue) .map(AbstractOAuth2Token::getTokenValue)
.orElse(null); .orElse(null);
} }
} }