Refactored and fixed findbug issues in OAuth extension

revert-70aa11f8
mharindu 9 years ago
parent 04fa0f4874
commit c824e63f1e

@ -46,7 +46,14 @@ public class OAuthExtUtils {
private static final Log log = LogFactory.getLog(OAuthExtUtils.class); private static final Log log = LogFactory.getLog(OAuthExtUtils.class);
private static final String DEFAULT_SCOPE_NAME = "default"; private static final String DEFAULT_SCOPE_NAME = "default";
private static final String UI_EXECUTE = "ui.execute"; private static final String UI_EXECUTE = "ui.execute";
private static final String REST_API_SCOPE_CACHE = "REST_API_SCOPE_CACHE";
/**
* This method is used to get the tenant id when given tenant domain.
*
* @param tenantDomain Tenant domain name.
* @return Returns the tenant id.
*/
public static int getTenantId(String tenantDomain) { public static int getTenantId(String tenantDomain) {
int tenantId = 0; int tenantId = 0;
if (tenantDomain != null) { if (tenantDomain != null) {
@ -62,9 +69,16 @@ public class OAuthExtUtils {
return tenantId; return tenantId;
} }
/**
* This method is used to set scopes that are authorized to the OAuth token request message context.
*
* @param tokReqMsgCtx OAuth token request message context
* @return Returns true if success.
*/
public static boolean setScopes(OAuthTokenReqMessageContext tokReqMsgCtx) { public static boolean setScopes(OAuthTokenReqMessageContext tokReqMsgCtx) {
String[] requestedScopes = tokReqMsgCtx.getScope(); String[] requestedScopes = tokReqMsgCtx.getScope();
String[] defaultScope = new String[]{DEFAULT_SCOPE_NAME}; String[] defaultScope = new String[]{DEFAULT_SCOPE_NAME};
//If no scopes were requested. //If no scopes were requested.
if (requestedScopes == null || requestedScopes.length == 0) { if (requestedScopes == null || requestedScopes.length == 0) {
tokReqMsgCtx.setScope(defaultScope); tokReqMsgCtx.setScope(defaultScope);
@ -72,7 +86,6 @@ public class OAuthExtUtils {
} }
String consumerKey = tokReqMsgCtx.getOauth2AccessTokenReqDTO().getClientId(); String consumerKey = tokReqMsgCtx.getOauth2AccessTokenReqDTO().getClientId();
String username = tokReqMsgCtx.getAuthorizedUser().getUserName();
List<String> reqScopeList = Arrays.asList(requestedScopes); List<String> reqScopeList = Arrays.asList(requestedScopes);
Map<String, String> restAPIScopesOfCurrentTenant; Map<String, String> restAPIScopesOfCurrentTenant;
@ -80,23 +93,27 @@ public class OAuthExtUtils {
Map<String, String> appScopes; Map<String, String> appScopes;
ApiMgtDAO apiMgtDAO = new ApiMgtDAO(); ApiMgtDAO apiMgtDAO = new ApiMgtDAO();
//Get all the scopes and roles against the scopes defined for the APIs subscribed to the application.
//Get all the scopes and permissions against the scopes defined for the APIs subscribed to the application.
appScopes = apiMgtDAO.getScopeRolesOfApplication(consumerKey); appScopes = apiMgtDAO.getScopeRolesOfApplication(consumerKey);
//Add API Manager rest API scopes set. This list should be loaded at server start up and keep //Add API Manager rest API scopes set. This list should be loaded at server start up and keep
//in memory and add it to each and every request coming. //in memory and add it to each and every request coming.
String tenantDomain = tokReqMsgCtx.getAuthorizedUser().getTenantDomain(); String tenantDomain = tokReqMsgCtx.getAuthorizedUser().getTenantDomain();
restAPIScopesOfCurrentTenant = (Map) Caching.getCacheManager(APIConstants.API_MANAGER_CACHE_MANAGER) restAPIScopesOfCurrentTenant = (Map) Caching.getCacheManager(APIConstants.API_MANAGER_CACHE_MANAGER)
.getCache("REST_API_SCOPE_CACHE") .getCache(REST_API_SCOPE_CACHE)
.get(tenantDomain); .get(tenantDomain);
if (restAPIScopesOfCurrentTenant != null) { if (restAPIScopesOfCurrentTenant != null) {
appScopes.putAll(restAPIScopesOfCurrentTenant); appScopes.putAll(restAPIScopesOfCurrentTenant);
} else { } else {
restAPIScopesOfCurrentTenant = APIUtil.getRESTAPIScopesFromConfig(APIUtil.getTenantRESTAPIScopesConfig(tenantDomain)); restAPIScopesOfCurrentTenant = APIUtil.
getRESTAPIScopesFromConfig(APIUtil.getTenantRESTAPIScopesConfig(tenantDomain));
//call load tenant config for rest API. //call load tenant config for rest API.
//then put cache //then put cache
appScopes.putAll(restAPIScopesOfCurrentTenant); appScopes.putAll(restAPIScopesOfCurrentTenant);
Caching.getCacheManager(APIConstants.API_MANAGER_CACHE_MANAGER) Caching.getCacheManager(APIConstants.API_MANAGER_CACHE_MANAGER)
.getCache("REST_API_SCOPE_CACHE") .getCache(REST_API_SCOPE_CACHE)
.put(tenantDomain, restAPIScopesOfCurrentTenant); .put(tenantDomain, restAPIScopesOfCurrentTenant);
} }
//If no scopes can be found in the context of the application //If no scopes can be found in the context of the application
@ -111,66 +128,9 @@ public class OAuthExtUtils {
return true; return true;
} }
int tenantId; // check for authorized scopes
RealmService realmService = OAuthExtensionsDataHolder.getInstance().getRealmService(); List<String> authorizedScopes = getAuthorizedScopes(tokReqMsgCtx, reqScopeList, appScopes);
try {
tenantId = realmService.getTenantManager().getTenantId(tenantDomain);
// If tenant Id is not set in the tokenReqContext, deriving it from username.
if (tenantId == 0 || tenantId == -1) {
tenantId = IdentityTenantUtil.getTenantIdOfUser(username);
}
} catch (UserStoreException e) {
//Log and return since we do not want to stop issuing the token in case of scope validation failures.
log.error("Error when getting the tenant's UserStoreManager or when getting roles of user ", e);
return false;
}
UserRealm userRealm = OAuthExtensionsDataHolder.getInstance().getRealmService().getTenantUserRealm(tenantId);
List<String> authorizedScopes = new ArrayList<>();
boolean status;
//List<String> userRoleList = new ArrayList<>(Arrays.asList(userRoles));
//Iterate the requested scopes list.
for (String scope : reqScopeList) {
status = false;
//Get the set of roles associated with the requested scope.
String appPermissions = appScopes.get(scope);
//If the scope has been defined in the context of the App and if roles have been defined for the scope
if (appPermissions != null && appPermissions.length() != 0) {
List<String> permissions = new ArrayList<>(Arrays.asList(appPermissions.replaceAll(" ", "").split(",")));
//Check if user has at least one of the roles associated with the scope
if (!permissions.isEmpty()) {
for (String permission : permissions) {
if (userRealm != null && userRealm.getAuthorizationManager() != null) {
String userStore = tokReqMsgCtx.getAuthorizedUser().getUserStoreDomain();
if (userStore != null) {
status = userRealm.getAuthorizationManager()
.isUserAuthorized(userStore + "/" + username, permission, UI_EXECUTE);
} else {
status = userRealm.getAuthorizationManager()
.isUserAuthorized(username, permission, UI_EXECUTE);
}
if (status) {
break;
}
}
}
if (status) {
authorizedScopes.add(scope);
}
}
}
//The requested scope is defined for the context of the App but no roles have been associated with the scope
//OR
//The scope string starts with 'device_'.
else if (appScopes.containsKey(scope) || isWhiteListedScope(scope)) {
authorizedScopes.add(scope);
}
}
if (!authorizedScopes.isEmpty()) { if (!authorizedScopes.isEmpty()) {
String[] authScopesArr = authorizedScopes.toArray(new String[authorizedScopes.size()]); String[] authScopesArr = authorizedScopes.toArray(new String[authorizedScopes.size()]);
tokReqMsgCtx.setScope(authScopesArr); tokReqMsgCtx.setScope(authScopesArr);
@ -180,8 +140,6 @@ public class OAuthExtUtils {
} catch (APIManagementException e) { } catch (APIManagementException e) {
log.error("Error while getting scopes of application " + e.getMessage()); log.error("Error while getting scopes of application " + e.getMessage());
return false; return false;
} catch (UserStoreException e) {
e.printStackTrace();
} }
return true; return true;
} }
@ -192,7 +150,7 @@ public class OAuthExtUtils {
* @param scope - The scope key to check * @param scope - The scope key to check
* @return - 'true' if the scope is white listed. 'false' if not. * @return - 'true' if the scope is white listed. 'false' if not.
*/ */
public static boolean isWhiteListedScope(String scope) { private static boolean isWhiteListedScope(String scope) {
// load white listed scopes // load white listed scopes
List<String> scopeSkipList = OAuthExtensionsDataHolder.getInstance().getWhitelistedScopes(); List<String> scopeSkipList = OAuthExtensionsDataHolder.getInstance().getWhitelistedScopes();
for (String scopeTobeSkipped : scopeSkipList) { for (String scopeTobeSkipped : scopeSkipList) {
@ -212,7 +170,7 @@ public class OAuthExtUtils {
* @return - The subset of scopes that are allowed * @return - The subset of scopes that are allowed
*/ */
private static String[] getAllowedScopes(List<String> requestedScopes) { private static String[] getAllowedScopes(List<String> requestedScopes) {
List<String> authorizedScopes = new ArrayList<String>(); List<String> authorizedScopes = new ArrayList<>();
//Iterate the requested scopes list. //Iterate the requested scopes list.
for (String scope : requestedScopes) { for (String scope : requestedScopes) {
@ -226,4 +184,80 @@ public class OAuthExtUtils {
return authorizedScopes.toArray(new String[authorizedScopes.size()]); return authorizedScopes.toArray(new String[authorizedScopes.size()]);
} }
/**
* This method is used to get the authorized scopes out of requested scopes. It checks requested scopes with app
* scopes whether user has permissions to take actions for the requested scopes.
*
* @param tokReqMsgCtx OAuth token request message context.
* @param reqScopeList Requested scope list.
* @param appScopes App scopes.
* @return Returns a list of scopes.
*/
private static List<String> getAuthorizedScopes(OAuthTokenReqMessageContext tokReqMsgCtx, List<String> reqScopeList,
Map<String, String> appScopes) {
boolean status;
List<String> authorizedScopes = new ArrayList<>();
int tenantId;
String username = tokReqMsgCtx.getAuthorizedUser().getUserName();
String tenantDomain = tokReqMsgCtx.getAuthorizedUser().getTenantDomain();
RealmService realmService = OAuthExtensionsDataHolder.getInstance().getRealmService();
try {
tenantId = realmService.getTenantManager().getTenantId(tenantDomain);
// If tenant Id is not set in the tokenReqContext, deriving it from username.
if (tenantId == 0 || tenantId == -1) {
tenantId = IdentityTenantUtil.getTenantIdOfUser(username);
}
UserRealm userRealm = OAuthExtensionsDataHolder.getInstance().getRealmService().getTenantUserRealm(tenantId);
//Iterate the requested scopes list.
for (String scope : reqScopeList) {
status = false;
//Get the set of roles associated with the requested scope.
String appPermissions = appScopes.get(scope);
//If the scope has been defined in the context of the App and if permissions have been defined for the scope
if (appPermissions != null && appPermissions.length() != 0) {
List<String> permissions = new ArrayList<>(Arrays.asList(appPermissions.replaceAll(" ", "").split(",")));
//Check if user has at least one of the permission associated with the scope
if (!permissions.isEmpty()) {
for (String permission : permissions) {
if (userRealm != null && userRealm.getAuthorizationManager() != null) {
String userStore = tokReqMsgCtx.getAuthorizedUser().getUserStoreDomain();
if (userStore != null) {
status = userRealm.getAuthorizationManager()
.isUserAuthorized(userStore + "/" + username, permission, UI_EXECUTE);
} else {
status = userRealm.getAuthorizationManager()
.isUserAuthorized(username, permission, UI_EXECUTE);
}
if (status) {
break;
}
}
}
if (status) {
authorizedScopes.add(scope);
}
}
}
//The scope string starts with 'device_'.
else if (appScopes.containsKey(scope) || isWhiteListedScope(scope)) {
authorizedScopes.add(scope);
}
}
} catch (UserStoreException e) {
log.error("Error occurred while initializing user store.", e);
}
return authorizedScopes;
}
} }

@ -42,12 +42,7 @@ import org.wso2.carbon.user.core.service.RealmService;
import org.wso2.carbon.user.core.util.UserCoreUtil; import org.wso2.carbon.user.core.util.UserCoreUtil;
import javax.xml.namespace.QName; import javax.xml.namespace.QName;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@ -120,16 +115,13 @@ public class ExtendedPasswordGrantHandler extends PasswordGrantHandler {
List<ResponseHeader> respHeaders = new ArrayList<>(); List<ResponseHeader> respHeaders = new ArrayList<>();
if (oAuth2AccessTokenReqDTO.getResourceOwnerUsername() != null) { if (oAuth2AccessTokenReqDTO.getResourceOwnerUsername() != null) {
try { try {
if (requiredHeaderClaimUris != null && !requiredHeaderClaimUris.isEmpty()) { if (requiredHeaderClaimUris != null && !requiredHeaderClaimUris.isEmpty()) {
// Get user's claim values from the default profile. // Get user's claim values from the default profile.
String userStoreDomain = tokReqMsgCtx.getAuthorizedUser().getUserStoreDomain(); String userStoreDomain = tokReqMsgCtx.getAuthorizedUser().getUserStoreDomain();
String endUsernameWithDomain = UserCoreUtil.addDomainToName String endUsernameWithDomain = UserCoreUtil.
(oAuth2AccessTokenReqDTO.getResourceOwnerUsername(), addDomainToName(oAuth2AccessTokenReqDTO.getResourceOwnerUsername(), userStoreDomain);
userStoreDomain);
Claim[] mapClaimValues = getUserClaimValues(endUsernameWithDomain, userStoreManager); Claim[] mapClaimValues = getUserClaimValues(endUsernameWithDomain, userStoreManager);
@ -146,19 +138,15 @@ public class ExtendedPasswordGrantHandler extends PasswordGrantHandler {
} }
} }
} }
} } else if (log.isDebugEnabled()) {
else if(log.isDebugEnabled()){
log.debug("No claim values for user : " + endUsernameWithDomain); log.debug("No claim values for user : " + endUsernameWithDomain);
} }
} }
} catch (Exception e) { } catch (Exception e) {
throw new IdentityOAuth2Exception(e.getMessage(), e); throw new IdentityOAuth2Exception("Error occurred while retrieving user claims", e);
} }
} }
tokReqMsgCtx.addProperty("RESPONSE_HEADERS", respHeaders.toArray(new ResponseHeader[respHeaders.size()]));
tokReqMsgCtx.addProperty("RESPONSE_HEADERS", respHeaders.toArray(
new ResponseHeader[respHeaders.size()]));
} }
return isValidated; return isValidated;
@ -191,17 +179,14 @@ public class ExtendedPasswordGrantHandler extends PasswordGrantHandler {
Map<String, String> emailConf = loginConfiguration.get(EMAIL_LOGIN); Map<String, String> emailConf = loginConfiguration.get(EMAIL_LOGIN);
if ("true".equalsIgnoreCase(emailConf.get(PRIMARY_LOGIN))) { if ("true".equalsIgnoreCase(emailConf.get(PRIMARY_LOGIN))) {
return !isUserLoggedInEmail(userId); return !isUserLoggedInEmail(userId);
} } else if ("false".equalsIgnoreCase(emailConf.get(PRIMARY_LOGIN))) {
else if ("false".equalsIgnoreCase(emailConf.get(PRIMARY_LOGIN))) {
return isUserLoggedInEmail(userId); return isUserLoggedInEmail(userId);
} }
} } else if (loginConfiguration.get(USERID_LOGIN) != null) {
else if (loginConfiguration.get(USERID_LOGIN) != null) {
Map<String, String> userIdConf = loginConfiguration.get(USERID_LOGIN); Map<String, String> userIdConf = loginConfiguration.get(USERID_LOGIN);
if ("true".equalsIgnoreCase(userIdConf.get(PRIMARY_LOGIN))) { if ("true".equalsIgnoreCase(userIdConf.get(PRIMARY_LOGIN))) {
return isUserLoggedInEmail(userId); return isUserLoggedInEmail(userId);
} } else if ("false".equalsIgnoreCase(userIdConf.get(PRIMARY_LOGIN))) {
else if ("false".equalsIgnoreCase(userIdConf.get(PRIMARY_LOGIN))) {
return !isUserLoggedInEmail(userId); return !isUserLoggedInEmail(userId);
} }
} }
@ -271,7 +256,9 @@ public class ExtendedPasswordGrantHandler extends PasswordGrantHandler {
} }
} }
// Read the required claim configuration from identity.xml /**
* Read the required claim configuration from identity.xml
*/
private void parseRequiredHeaderClaimUris(OMElement requiredClaimUrisElem) { private void parseRequiredHeaderClaimUris(OMElement requiredClaimUrisElem) {
if (requiredClaimUrisElem == null) { if (requiredClaimUrisElem == null) {
return; return;
@ -302,6 +289,7 @@ public class ExtendedPasswordGrantHandler extends PasswordGrantHandler {
* </LoginConfig> * </LoginConfig>
* ..... * .....
* </OAuth> * </OAuth>
*
* @param oauthConfigElem - The '<LoginConfig>' xml configuration element in the api-manager.xml * @param oauthConfigElem - The '<LoginConfig>' xml configuration element in the api-manager.xml
*/ */
private void parseLoginConfig(OMElement oauthConfigElem) { private void parseLoginConfig(OMElement oauthConfigElem) {

Loading…
Cancel
Save