Skip to content

Commit

Permalink
Improve userinfo response to return roles without internal domain app…
Browse files Browse the repository at this point in the history
…ended
  • Loading branch information
sadilchamishka committed Jan 16, 2025
1 parent f11275f commit 63e5358
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2024, WSO2 LLC. (http://www.wso2.com).
* Copyright (c) 2013-2025, WSO2 LLC. (http://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
Expand Down Expand Up @@ -233,6 +233,8 @@ public class OAuthServerConfiguration {
private List<String> supportedIdTokenEncryptionMethods = new ArrayList<>();
private String userInfoJWTSignatureAlgorithm = "SHA256withRSA";
private boolean userInfoMultiValueSupportEnabled = true;
private boolean userInfoInternalPrefixedRolesClaimEnabled = true;

private String authContextTTL = "15L";
// property added to fix IDENTITY-4551 in backward compatible manner
private boolean useMultiValueSeparatorForAuthContextToken = true;
Expand Down Expand Up @@ -1575,6 +1577,16 @@ public boolean getUserInfoMultiValueSupportEnabled() {
return userInfoMultiValueSupportEnabled;
}

/**
* Returns whether Internal prefix should be appended for roles claim of the userinfo response.
*
* @return True if Internal prefix value should be appended for the role claim of userinfo response.
*/
public boolean getUserInfoInternalPrefixedRolesClaimEnabled() {

return userInfoInternalPrefixedRolesClaimEnabled;
}

public String getConsumerDialectURI() {
return consumerDialectURI;
}
Expand Down Expand Up @@ -3503,6 +3515,15 @@ private void parseOpenIDConnectConfig(OMElement oauthConfigElem) {
userInfoMultiValueSupportEnabled = Boolean.parseBoolean(
userInfoMultiValueSupportEnabledElem.getText().trim());
}

OMElement userInfoInternalPrefixedRolesClaim = openIDConnectConfigElem
.getFirstChildWithName(getQNameWithIdentityNS(ConfigElements
.OPENID_CONNECT_USERINFO_INTERNAL_PREFIXED_ROLE_CLAIM_ENABLED));
if (userInfoInternalPrefixedRolesClaim != null) {
userInfoInternalPrefixedRolesClaimEnabled = Boolean.parseBoolean(
userInfoInternalPrefixedRolesClaim.getText().trim());
}

if (openIDConnectConfigElem.getFirstChildWithName(
getQNameWithIdentityNS(ConfigElements.OPENID_CONNECT_SIGN_JWT_WITH_SP_KEY)) != null) {
isJWTSignedWithSPKey = Boolean.parseBoolean(openIDConnectConfigElem.getFirstChildWithName(
Expand Down Expand Up @@ -4132,6 +4153,8 @@ private class ConfigElements {
public static final String OPENID_CONNECT_USERINFO_JWT_SIGNATURE_ALGORITHM = "UserInfoJWTSignatureAlgorithm";
public static final String OPENID_CONNECT_USERINFO_MULTI_VALUE_SUPPORT_ENABLED =
"UserInfoMultiValueSupportEnabled";
public static final String OPENID_CONNECT_USERINFO_INTERNAL_PREFIXED_ROLE_CLAIM_ENABLED =
"UserInfoInternalPrefixedRolesClaimEnabled";
public static final String OPENID_CONNECT_SIGN_JWT_WITH_SP_KEY = "SignJWTWithSPKey";
public static final String OPENID_CONNECT_IDTOKEN_CUSTOM_CLAIM_CALLBACK_HANDLER =
"IDTokenCustomClaimsCallBackHandler";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@
import org.wso2.carbon.identity.application.common.model.ServiceProvider;
import org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants;
import org.wso2.carbon.identity.application.mgt.ApplicationManagementService;
import org.wso2.carbon.identity.core.util.IdentityUtil;
import org.wso2.carbon.identity.oauth.cache.AuthorizationGrantCache;
import org.wso2.carbon.identity.oauth.cache.AuthorizationGrantCacheEntry;
import org.wso2.carbon.identity.oauth.cache.AuthorizationGrantCacheKey;
import org.wso2.carbon.identity.oauth.common.exception.InvalidOAuthClientException;
import org.wso2.carbon.identity.oauth.config.OAuthServerConfiguration;
import org.wso2.carbon.identity.oauth.dao.OAuthAppDO;
import org.wso2.carbon.identity.oauth.user.UserInfoEndpointException;
import org.wso2.carbon.identity.oauth.user.UserInfoResponseBuilder;
Expand All @@ -40,6 +42,8 @@
import org.wso2.carbon.identity.oauth2.util.OAuth2Util;
import org.wso2.carbon.identity.openidconnect.internal.OpenIDConnectServiceComponentHolder;
import org.wso2.carbon.identity.openidconnect.model.RequestedClaim;
import org.wso2.carbon.user.core.UserCoreConstants;
import org.wso2.carbon.user.core.util.UserCoreUtil;

import java.util.ArrayList;
import java.util.HashMap;
Expand All @@ -50,6 +54,7 @@
import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
import static org.apache.commons.lang.StringUtils.isNotEmpty;
import static org.wso2.carbon.identity.oauth.common.OAuthConstants.OAuth20Params.USERINFO;
import static org.wso2.carbon.identity.oauth.common.OAuthConstants.OIDCClaims.ROLES;

/**
* Abstract user info response builder.
Expand All @@ -76,6 +81,9 @@ public String getResponseString(OAuth2TokenValidationResponseDTO tokenResponse)
Map<String, Object> userClaims = retrieveUserClaims(tokenResponse);
Map<String, Object> filteredUserClaims = filterOIDCClaims(tokenResponse, clientId, spTenantDomain, userClaims);

// Handle roles claim.
handleRolesClaim(filteredUserClaims);

// Handle subject claim.
String subjectClaim = getSubjectClaim(userClaims, clientId, spTenantDomain, tokenResponse);
subjectClaim = getOIDCSubjectClaim(clientId, spTenantDomain, subjectClaim);
Expand All @@ -84,6 +92,22 @@ public String getResponseString(OAuth2TokenValidationResponseDTO tokenResponse)
return buildResponse(tokenResponse, spTenantDomain, filteredUserClaims);
}

private void handleRolesClaim(Map<String, Object> filteredUserClaims) {

// This check is added for the backward compatibility of userinfo response.
if (OAuthServerConfiguration.getInstance().getUserInfoInternalPrefixedRolesClaimEnabled()) {
return;
}
String[] roles = (String[]) filteredUserClaims.get(ROLES);
for (int i = 0; i < roles.length; i++) {
String role = roles[i];
if (UserCoreConstants.INTERNAL_DOMAIN.equalsIgnoreCase(IdentityUtil.extractDomainFromName(role))) {
String domainRemovedRole = UserCoreUtil.removeDomainFromName(role);
roles[i] = domainRemovedRole;
}
}
}

private String getOIDCSubjectClaim(String clientId, String spTenantDomain, String subjectClaim)
throws UserInfoEndpointException {

Expand Down

0 comments on commit 63e5358

Please sign in to comment.