Added device scope validation

4.x.x
ayyoob 9 years ago
parent 1373e995fb
commit 0c2de7965f

@ -54,6 +54,14 @@
<groupId>com.googlecode.json-simple.wso2</groupId> <groupId>com.googlecode.json-simple.wso2</groupId>
<artifactId>json-simple</artifactId> <artifactId>json-simple</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.wso2.carbon.identity</groupId>
<artifactId>org.wso2.carbon.identity.oauth2.grant.jwt</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.core</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>
@ -118,7 +126,9 @@
org.wso2.carbon.identity.oauth.config, org.wso2.carbon.identity.oauth.config,
org.wso2.carbon.identity.oauth2.dao, org.wso2.carbon.identity.oauth2.dao,
org.wso2.carbon.utils.multitenancy, org.wso2.carbon.utils.multitenancy,
org.wso2.carbon.base org.wso2.carbon.base,
org.wso2.carbon.identity.oauth2.grant.jwt.*,
org.wso2.carbon.device.mgt.core.*
</Import-Package> </Import-Package>
</instructions> </instructions>
</configuration> </configuration>

@ -24,6 +24,9 @@ import org.wso2.carbon.apimgt.api.APIManagementException;
import org.wso2.carbon.apimgt.impl.APIConstants; import org.wso2.carbon.apimgt.impl.APIConstants;
import org.wso2.carbon.apimgt.impl.dao.ApiMgtDAO; import org.wso2.carbon.apimgt.impl.dao.ApiMgtDAO;
import org.wso2.carbon.apimgt.impl.utils.APIUtil; import org.wso2.carbon.apimgt.impl.utils.APIUtil;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.oauth.extensions.internal.OAuthExtensionsDataHolder; import org.wso2.carbon.device.mgt.oauth.extensions.internal.OAuthExtensionsDataHolder;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil; import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext; import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext;
@ -48,7 +51,7 @@ public class OAuthExtUtils {
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"; private static final String REST_API_SCOPE_CACHE = "REST_API_SCOPE_CACHE";
private static final int START_INDEX = 0; private static final int START_INDEX = 0;
private static final String CDMF_SCOPE_SEPERATOR = "/";
/** /**
* This method is used to get the tenant id when given tenant domain. * This method is used to get the tenant id when given tenant domain.
* *
@ -59,7 +62,8 @@ public class OAuthExtUtils {
int tenantId = 0; int tenantId = 0;
if (tenantDomain != null) { if (tenantDomain != null) {
try { try {
TenantManager tenantManager = OAuthExtensionsDataHolder.getInstance().getRealmService().getTenantManager(); TenantManager tenantManager =
OAuthExtensionsDataHolder.getInstance().getRealmService().getTenantManager();
tenantId = tenantManager.getTenantId(tenantDomain); tenantId = tenantManager.getTenantId(tenantDomain);
} catch (UserStoreException e) { } catch (UserStoreException e) {
String errorMsg = "Error when getting the tenant id from the tenant domain : " + String errorMsg = "Error when getting the tenant id from the tenant domain : " +
@ -162,6 +166,20 @@ public class OAuthExtUtils {
return false; return false;
} }
/**
* Determines if the scope is specified with CDMF device scope prefix.
*
* @param scope - The scope key to check
* @return - 'true' if the scope has the prefix. 'false' if not.
*/
private static boolean isCDMFDeviceSpecificScope(String scope) {
// load white listed scopes
if (scope.startsWith(OAuthExtensionsDataHolder.getInstance().getDeviceScope())) {
return true;
}
return false;
}
/** /**
* Get the set of default scopes. If a requested scope is matches with the patterns specified in the white list, * Get the set of default scopes. If a requested scope is matches with the patterns specified in the white list,
* then such scopes will be issued without further validation. If the scope list is empty, * then such scopes will be issued without further validation. If the scope list is empty,
@ -213,7 +231,8 @@ public class OAuthExtUtils {
tenantId = IdentityTenantUtil.getTenantIdOfUser(username); tenantId = IdentityTenantUtil.getTenantIdOfUser(username);
} }
UserRealm userRealm = OAuthExtensionsDataHolder.getInstance().getRealmService().getTenantUserRealm(tenantId); UserRealm userRealm = OAuthExtensionsDataHolder.getInstance().getRealmService().getTenantUserRealm(
tenantId);
//Iterate the requested scopes list. //Iterate the requested scopes list.
for (String scope : reqScopeList) { for (String scope : reqScopeList) {
@ -222,9 +241,11 @@ public class OAuthExtUtils {
//Get the set of roles associated with the requested scope. //Get the set of roles associated with the requested scope.
String appPermissions = appScopes.get(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 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) { if (appPermissions != null && appPermissions.length() != 0) {
List<String> permissions = new ArrayList<>(Arrays.asList(appPermissions.replaceAll(" ", "").split(","))); List<String> permissions = new ArrayList<>(Arrays.asList(appPermissions.replaceAll(" ", "").split(
",")));
//Check if user has at least one of the permission associated with the scope //Check if user has at least one of the permission associated with the scope
if (!permissions.isEmpty()) { if (!permissions.isEmpty()) {
@ -254,6 +275,27 @@ public class OAuthExtUtils {
else if (appScopes.containsKey(scope) || isWhiteListedScope(scope)) { else if (appScopes.containsKey(scope) || isWhiteListedScope(scope)) {
authorizedScopes.add(scope); authorizedScopes.add(scope);
} }
//check whether is device specific scope (CDMF)
else if (isCDMFDeviceSpecificScope(scope)) {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId, true);
try {
String deviceId[] = scope.split(CDMF_SCOPE_SEPERATOR);
DeviceIdentifier deviceIdentifier = new DeviceIdentifier(deviceId[2], deviceId[1]);
boolean enrolled = OAuthExtensionsDataHolder.getInstance().getDeviceManagementService().isEnrolled(
deviceIdentifier, tokReqMsgCtx.getAuthorizedUser().getUserName());
if (enrolled) {
authorizedScopes.add(scope);
}
} catch (DeviceManagementException e) {
log.error("Error occurred while checking device scope with CDMF", e);
} catch (ArrayIndexOutOfBoundsException e) {
log.error("Invalid scope format, have to adhere [prefix/devicetype/deviceId]", e);
}finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
} }
} catch (UserStoreException e) { } catch (UserStoreException e) {
log.error("Error occurred while initializing user store.", e); log.error("Error occurred while initializing user store.", e);

@ -0,0 +1,14 @@
package org.wso2.carbon.device.mgt.oauth.extensions.handlers.grant;
import org.wso2.carbon.device.mgt.oauth.extensions.OAuthExtUtils;
import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception;
import org.wso2.carbon.identity.oauth2.grant.jwt.JWTBearerGrantHandler;
import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext;
public class ExtendedJWTBearerGrantHandler extends JWTBearerGrantHandler {
@Override
public boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) throws IdentityOAuth2Exception {
return OAuthExtUtils.setScopes(tokReqMsgCtx);
}
}

@ -25,6 +25,7 @@ import org.wso2.carbon.apimgt.api.APIManagementException;
import org.wso2.carbon.apimgt.impl.APIConstants; import org.wso2.carbon.apimgt.impl.APIConstants;
import org.wso2.carbon.apimgt.impl.APIManagerConfiguration; import org.wso2.carbon.apimgt.impl.APIManagerConfiguration;
import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagerService; import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagerService;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService; import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService;
import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.user.core.service.RealmService;
import org.wso2.carbon.utils.CarbonUtils; import org.wso2.carbon.utils.CarbonUtils;
@ -53,6 +54,12 @@ import java.util.List;
* policy="dynamic" * policy="dynamic"
* bind="setPermissionManagerService" * bind="setPermissionManagerService"
* unbind="unsetPermissionManagerService" * unbind="unsetPermissionManagerService"
* @scr.reference name="org.wso2.carbon.device.manager"
* interface="org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService"
* cardinality="1..1"
* policy="dynamic"
* bind="setDeviceManagementService"
* unbind="unsetDeviceManagementService"
*/ */
public class OAuthExtensionServiceComponent { public class OAuthExtensionServiceComponent {
@ -60,6 +67,8 @@ public class OAuthExtensionServiceComponent {
private static final String REPOSITORY = "repository"; private static final String REPOSITORY = "repository";
private static final String CONFIGURATION = "conf"; private static final String CONFIGURATION = "conf";
private static final String APIM_CONF_FILE = "api-manager.xml"; private static final String APIM_CONF_FILE = "api-manager.xml";
private static final String API_KEY_MANGER_DEVICE_SCOPE = "APIKeyValidator.DeviceScope";
private static final String CDMF_DEVICE_SCOPE_PREFIX = "cdmf_";
@SuppressWarnings("unused") @SuppressWarnings("unused")
@ -94,6 +103,15 @@ public class OAuthExtensionServiceComponent {
OAuthExtensionsDataHolder.getInstance().setWhitelistedScopes(whiteList); OAuthExtensionsDataHolder.getInstance().setWhitelistedScopes(whiteList);
// Read device scope(Specific to CDMF) from Configuration.
String deviceScope = configuration.getFirstProperty(API_KEY_MANGER_DEVICE_SCOPE);
if (deviceScope == null) {
deviceScope = CDMF_DEVICE_SCOPE_PREFIX;
}
OAuthExtensionsDataHolder.getInstance().setDeviceScope(deviceScope);
} catch (APIManagementException e) { } catch (APIManagementException e) {
log.error("Error occurred while loading APIM configurations", e); log.error("Error occurred while loading APIM configurations", e);
} }
@ -178,4 +196,26 @@ public class OAuthExtensionServiceComponent {
OAuthExtensionsDataHolder.getInstance().setPermissionManagerService(null); OAuthExtensionsDataHolder.getInstance().setPermissionManagerService(null);
} }
/**
* Set DeviceManagementProviderService
* @param deviceManagerService An instance of PermissionManagerService
*/
protected void setDeviceManagementService(DeviceManagementProviderService deviceManagerService) {
if (log.isDebugEnabled()) {
log.debug("Setting Device Management Service");
}
OAuthExtensionsDataHolder.getInstance().setDeviceManagementService(deviceManagerService);
}
/**
* unset DeviceManagementProviderService
* @param deviceManagementService An instance of PermissionManagerService
*/
protected void unsetDeviceManagementService(DeviceManagementProviderService deviceManagementService) {
if (log.isDebugEnabled()) {
log.debug("Removing Device Management Service");
}
OAuthExtensionsDataHolder.getInstance().setDeviceManagementService(null);
}
} }

@ -19,6 +19,7 @@
package org.wso2.carbon.device.mgt.oauth.extensions.internal; package org.wso2.carbon.device.mgt.oauth.extensions.internal;
import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagerService; import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagerService;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService; import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService;
import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.user.core.service.RealmService;
@ -33,6 +34,8 @@ public class OAuthExtensionsDataHolder {
private OAuth2TokenValidationService oAuth2TokenValidationService; private OAuth2TokenValidationService oAuth2TokenValidationService;
private PermissionManagerService permissionManagerService; private PermissionManagerService permissionManagerService;
private List<String> whitelistedScopes; private List<String> whitelistedScopes;
private String deviceScope;
private DeviceManagementProviderService deviceManagementService;
private static OAuthExtensionsDataHolder thisInstance = new OAuthExtensionsDataHolder(); private static OAuthExtensionsDataHolder thisInstance = new OAuthExtensionsDataHolder();
@ -83,4 +86,20 @@ public class OAuthExtensionsDataHolder {
public void setWhitelistedScopes(List<String> whitelistedScopes) { public void setWhitelistedScopes(List<String> whitelistedScopes) {
this.whitelistedScopes = whitelistedScopes; this.whitelistedScopes = whitelistedScopes;
} }
public void setDeviceScope(String deviceScope) {
this.deviceScope = deviceScope;
}
public String getDeviceScope() {
return deviceScope;
}
public DeviceManagementProviderService getDeviceManagementService() {
return deviceManagementService;
}
public void setDeviceManagementService(DeviceManagementProviderService deviceManagementService) {
this.deviceManagementService = deviceManagementService;
}
} }

Loading…
Cancel
Save