mirror of
https://repository.entgra.net/community/device-mgt-core.git
synced 2025-10-06 02:01:45 +00:00
added device mgt grant types
This commit is contained in:
parent
ba6e202442
commit
250ce1f77c
@ -202,18 +202,13 @@ public class DeviceAccessAuthorizationServiceImpl implements DeviceAccessAuthori
|
||||
throws DeviceAccessAuthorizationException {
|
||||
//Check for device ownership. If the user is the owner of the device we allow the access.
|
||||
try {
|
||||
Device device = DeviceManagementDataHolder.getInstance().getDeviceManagementProvider().
|
||||
getDevice(deviceIdentifier);
|
||||
EnrolmentInfo enrolmentInfo = device.getEnrolmentInfo();
|
||||
if (enrolmentInfo != null && username.equalsIgnoreCase(enrolmentInfo.getOwner())) {
|
||||
return true;
|
||||
}
|
||||
return DeviceManagementDataHolder.getInstance().getDeviceManagementProvider().
|
||||
isEnrolled(deviceIdentifier, username);
|
||||
} catch (DeviceManagementException e) {
|
||||
throw new DeviceAccessAuthorizationException("Unable to authorize the access to device : " +
|
||||
deviceIdentifier.getId() + " for the user : " +
|
||||
username, e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isAdminUser(String username, int tenantId) throws UserStoreException {
|
||||
|
||||
@ -50,6 +50,10 @@
|
||||
<groupId>org.wso2.carbon.apimgt</groupId>
|
||||
<artifactId>org.wso2.carbon.apimgt.impl</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.apimgt</groupId>
|
||||
<artifactId>org.wso2.carbon.apimgt.keymgt</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.googlecode.json-simple.wso2</groupId>
|
||||
<artifactId>json-simple</artifactId>
|
||||
@ -95,40 +99,41 @@
|
||||
org.wso2.carbon.device.mgt.*,
|
||||
org.wso2.carbon.identity.application.common.model,
|
||||
org.wso2.carbon.identity.oauth.callback,
|
||||
org.wso2.carbon.identity.oauth.common,
|
||||
org.wso2.carbon.identity.oauth2,
|
||||
org.wso2.carbon.identity.oauth2.model,
|
||||
org.wso2.carbon.identity.oauth2.validators,
|
||||
org.wso2.carbon.user.api,
|
||||
org.wso2.carbon.user.core.service,
|
||||
org.wso2.carbon.identity.application.common.model,
|
||||
org.wso2.carbon.identity.application.authentication.framework.model,
|
||||
org.wso2.carbon.user.core.tenant,
|
||||
org.json.simple,
|
||||
javax.cache,
|
||||
javax.xml.namespace,
|
||||
org.apache.axiom.om,
|
||||
org.wso2.carbon.apimgt.api,
|
||||
org.wso2.carbon.apimgt.impl,
|
||||
org.wso2.carbon.apimgt.impl.dao,
|
||||
org.wso2.carbon.apimgt.impl.utils,
|
||||
org.wso2.carbon.identity.application.common.cache,
|
||||
org.wso2.carbon.identity.core.util,
|
||||
org.wso2.carbon.identity.oauth2.dto,
|
||||
org.wso2.carbon.identity.oauth2.token,
|
||||
org.wso2.carbon.identity.oauth2.token.handlers.grant,
|
||||
org.wso2.carbon.user.core,
|
||||
org.wso2.carbon.user.core.config,
|
||||
org.wso2.carbon.user.core.util,
|
||||
org.apache.oltu.oauth2.common.validators,
|
||||
org.wso2.carbon.utils,
|
||||
org.wso2.carbon.context,
|
||||
org.wso2.carbon.identity.oauth.cache,
|
||||
org.wso2.carbon.identity.oauth.config,
|
||||
org.wso2.carbon.identity.oauth2.dao,
|
||||
org.wso2.carbon.utils.multitenancy,
|
||||
org.wso2.carbon.base,
|
||||
org.wso2.carbon.identity.oauth2.grant.jwt.*,
|
||||
org.wso2.carbon.device.mgt.core.*
|
||||
org.wso2.carbon.device.mgt.core.*,
|
||||
javax.xml.bind,
|
||||
javax.xml.bind.annotation,
|
||||
javax.xml.parsers,
|
||||
org.w3c.dom,
|
||||
org.wso2.carbon.apimgt.keymgt,
|
||||
org.wso2.carbon.apimgt.keymgt.handlers,
|
||||
com.google.gson,
|
||||
org.apache.commons.codec.binary,
|
||||
org.wso2.carbon.identity.application.authentication.framework.model,
|
||||
org.apache.oltu.oauth2.common,
|
||||
org.wso2.carbon.base
|
||||
</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
package org.wso2.carbon.device.mgt.oauth.extensions;
|
||||
|
||||
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class holds the request format for device for grant type.
|
||||
*/
|
||||
public class DeviceRequestDTO {
|
||||
|
||||
private List<DeviceIdentifier> deviceIdentifiers;
|
||||
private String scope;
|
||||
|
||||
public List<DeviceIdentifier> getDeviceIdentifiers() {
|
||||
return deviceIdentifiers;
|
||||
}
|
||||
|
||||
public void setDeviceIdentifiers(List<DeviceIdentifier> deviceIdentifiers) {
|
||||
this.deviceIdentifiers = deviceIdentifiers;
|
||||
}
|
||||
|
||||
public String getScope() {
|
||||
return scope;
|
||||
}
|
||||
|
||||
public void setScope(String scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
}
|
||||
@ -18,17 +18,25 @@
|
||||
|
||||
package org.wso2.carbon.device.mgt.oauth.extensions;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.w3c.dom.Document;
|
||||
import org.wso2.carbon.apimgt.api.APIManagementException;
|
||||
import org.wso2.carbon.apimgt.impl.APIConstants;
|
||||
import org.wso2.carbon.apimgt.impl.dao.ApiMgtDAO;
|
||||
import org.wso2.carbon.apimgt.impl.utils.APIUtil;
|
||||
import org.wso2.carbon.apimgt.keymgt.ScopesIssuer;
|
||||
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.common.authorization.DeviceAccessAuthorizationException;
|
||||
import org.wso2.carbon.device.mgt.common.authorization.DeviceAuthorizationResult;
|
||||
import org.wso2.carbon.device.mgt.oauth.extensions.config.DeviceMgtScopesConfig;
|
||||
import org.wso2.carbon.device.mgt.oauth.extensions.config.DeviceMgtScopesConfigurationFailedException;
|
||||
import org.wso2.carbon.device.mgt.oauth.extensions.internal.OAuthExtensionsDataHolder;
|
||||
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
|
||||
import org.wso2.carbon.identity.oauth2.model.RequestParameter;
|
||||
import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext;
|
||||
import org.wso2.carbon.user.api.TenantManager;
|
||||
import org.wso2.carbon.user.api.UserRealm;
|
||||
@ -36,6 +44,9 @@ import org.wso2.carbon.user.api.UserStoreException;
|
||||
import org.wso2.carbon.user.core.service.RealmService;
|
||||
|
||||
import javax.cache.Caching;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@ -51,7 +62,8 @@ public class OAuthExtUtils {
|
||||
private static final String UI_EXECUTE = "ui.execute";
|
||||
private static final String REST_API_SCOPE_CACHE = "REST_API_SCOPE_CACHE";
|
||||
private static final int START_INDEX = 0;
|
||||
private static final String CDMF_SCOPE_SEPERATOR = "/";
|
||||
private static final String DEFAULT_SCOPE_TAG = "device-mgt";
|
||||
|
||||
/**
|
||||
* This method is used to get the tenant id when given tenant domain.
|
||||
*
|
||||
@ -114,7 +126,7 @@ public class OAuthExtUtils {
|
||||
restAPIScopesOfCurrentTenant = APIUtil.
|
||||
getRESTAPIScopesFromConfig(APIUtil.getTenantRESTAPIScopesConfig(tenantDomain));
|
||||
|
||||
//call load tenant config for rest API.
|
||||
//call load tenant org.wso2.carbon.device.mgt.iot.output.adapter.ui.config for rest API.
|
||||
//then put cache
|
||||
appScopes.putAll(restAPIScopesOfCurrentTenant);
|
||||
Caching.getCacheManager(APIConstants.API_MANAGER_CACHE_MANAGER)
|
||||
@ -166,20 +178,6 @@ public class OAuthExtUtils {
|
||||
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,
|
||||
* then such scopes will be issued without further validation. If the scope list is empty,
|
||||
@ -275,27 +273,6 @@ public class OAuthExtUtils {
|
||||
else if (appScopes.containsKey(scope) || isWhiteListedScope(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) {
|
||||
log.error("Error occurred while initializing user store.", e);
|
||||
@ -311,4 +288,77 @@ public class OAuthExtUtils {
|
||||
return trimmedName.substring(START_INDEX, trimmedName.lastIndexOf('@'));
|
||||
}
|
||||
|
||||
public static boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) {
|
||||
boolean isScopesSet = ScopesIssuer.getInstance().setScopes(tokReqMsgCtx);
|
||||
if (isScopesSet) {
|
||||
PrivilegedCarbonContext.startTenantFlow();
|
||||
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(
|
||||
tokReqMsgCtx.getAuthorizedUser().getTenantDomain(), true);
|
||||
String username = tokReqMsgCtx.getAuthorizedUser().getUserName();
|
||||
PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(username);
|
||||
try {
|
||||
|
||||
DeviceRequestDTO deviceRequestDTO = null;
|
||||
RequestParameter parameters[] = tokReqMsgCtx.getOauth2AccessTokenReqDTO().getRequestParameters();
|
||||
for (RequestParameter parameter : parameters) {
|
||||
if (Constants.DEFAULT_DEVICE_ASSERTION.equals(parameter.getKey())) {
|
||||
String deviceJson = parameter.getValue()[0];
|
||||
Gson gson = new Gson();
|
||||
deviceRequestDTO = gson.fromJson(new String(Base64.decodeBase64(deviceJson)),
|
||||
DeviceRequestDTO.class);
|
||||
}
|
||||
}
|
||||
if (deviceRequestDTO != null) {
|
||||
String scopeName = deviceRequestDTO.getScope();
|
||||
List<DeviceIdentifier> deviceIdentifiers = deviceRequestDTO.getDeviceIdentifiers();
|
||||
DeviceAuthorizationResult deviceAuthorizationResult = OAuthExtensionsDataHolder.getInstance()
|
||||
.getDeviceAccessAuthorizationService()
|
||||
.isUserAuthorized(deviceIdentifiers, username, getPermissions(scopeName));
|
||||
if (deviceAuthorizationResult != null && deviceAuthorizationResult.getAuthorizedDevices() != null) {
|
||||
String scopes[] = tokReqMsgCtx.getScope();
|
||||
String authorizedScopes[] = new String[scopes.length + deviceAuthorizationResult
|
||||
.getAuthorizedDevices().size()];
|
||||
int scopeIndex = 0;
|
||||
for (String scope : scopes) {
|
||||
authorizedScopes[scopeIndex] = scope;
|
||||
scopeIndex++;
|
||||
}
|
||||
for (DeviceIdentifier deviceIdentifier : deviceAuthorizationResult.getAuthorizedDevices()) {
|
||||
authorizedScopes[scopeIndex] = DEFAULT_SCOPE_TAG + ":" + deviceIdentifier.getType() + ":" +
|
||||
deviceIdentifier.getId() + ":" + scopeName;
|
||||
scopeIndex++;
|
||||
}
|
||||
tokReqMsgCtx.setScope(authorizedScopes);
|
||||
}
|
||||
}
|
||||
} catch (DeviceAccessAuthorizationException e) {
|
||||
log.error("Error occurred while checking authorization for the user " + username, e);
|
||||
} finally {
|
||||
PrivilegedCarbonContext.endTenantFlow();
|
||||
}
|
||||
}
|
||||
return isScopesSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve the permission related to given scope.
|
||||
* @param scopeName requested scope action
|
||||
* @return set of permission associated with the given scope.
|
||||
*/
|
||||
private static String[] getPermissions(String scopeName) {
|
||||
return DeviceMgtScopesConfig.getInstance().getDeviceMgtScopePermissionMap().get(scopeName);
|
||||
}
|
||||
|
||||
public static Document convertToDocument(File file) throws DeviceMgtScopesConfigurationFailedException {
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setNamespaceAware(true);
|
||||
try {
|
||||
DocumentBuilder docBuilder = factory.newDocumentBuilder();
|
||||
return docBuilder.parse(file);
|
||||
} catch (Exception e) {
|
||||
throw new DeviceMgtScopesConfigurationFailedException("Error occurred while parsing file, while converting " +
|
||||
"to a org.w3c.dom.Document", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,90 @@
|
||||
|
||||
package org.wso2.carbon.device.mgt.oauth.extensions.config;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for Action complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType name="Action">
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element name="Permissions" type="{}Permissions"/>
|
||||
* </sequence>
|
||||
* <attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "Action", propOrder = {
|
||||
"permissions"
|
||||
})
|
||||
public class Action {
|
||||
|
||||
@XmlElement(name = "Permissions", required = true)
|
||||
protected Permissions permissions;
|
||||
@XmlAttribute(name = "name")
|
||||
protected String name;
|
||||
|
||||
/**
|
||||
* Gets the value of the permissions property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Permissions }
|
||||
*
|
||||
*/
|
||||
public Permissions getPermissions() {
|
||||
return permissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the permissions property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Permissions }
|
||||
*
|
||||
*/
|
||||
public void setPermissions(Permissions value) {
|
||||
this.permissions = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the name property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the name property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link String }
|
||||
*
|
||||
*/
|
||||
public void setName(String value) {
|
||||
this.name = value;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,67 @@
|
||||
|
||||
package org.wso2.carbon.device.mgt.oauth.extensions.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for DeviceMgtScopes complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType name="DeviceMgtScopes">
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element name="Action" type="{}Action" maxOccurs="unbounded" minOccurs="0"/>
|
||||
* </sequence>
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlRootElement(name = "DeviceMgtScopes")
|
||||
public class DeviceMgtScopes {
|
||||
|
||||
@XmlElement(name = "Action")
|
||||
protected List<Action> action;
|
||||
|
||||
/**
|
||||
* Gets the value of the action property.
|
||||
*
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the action property.
|
||||
*
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getAction().add(newItem);
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link Action }
|
||||
*
|
||||
*
|
||||
*/
|
||||
public List<Action> getAction() {
|
||||
if (action == null) {
|
||||
action = new ArrayList<Action>();
|
||||
}
|
||||
return this.action;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,67 @@
|
||||
|
||||
package org.wso2.carbon.device.mgt.oauth.extensions.config;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.wso2.carbon.device.mgt.oauth.extensions.OAuthExtUtils;
|
||||
import org.wso2.carbon.utils.CarbonUtils;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* This class represents the configuration that are needed for scopes to permission map.
|
||||
*/
|
||||
public class DeviceMgtScopesConfig {
|
||||
|
||||
private static DeviceMgtScopesConfig config = new DeviceMgtScopesConfig();
|
||||
private static Map<String, String[]> actionPermissionMap = new HashMap<>();
|
||||
|
||||
private static final String DEVICE_MGT_SCOPES_CONFIG_PATH =
|
||||
CarbonUtils.getEtcCarbonConfigDirPath() + File.separator + "device-mgt-scopes.xml";
|
||||
|
||||
private DeviceMgtScopesConfig() {
|
||||
}
|
||||
|
||||
public static DeviceMgtScopesConfig getInstance() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public static void init() throws DeviceMgtScopesConfigurationFailedException {
|
||||
try {
|
||||
File deviceMgtConfig = new File(DEVICE_MGT_SCOPES_CONFIG_PATH);
|
||||
Document doc = OAuthExtUtils.convertToDocument(deviceMgtConfig);
|
||||
|
||||
/* Un-marshaling DeviceMGtScope configuration */
|
||||
JAXBContext ctx = JAXBContext.newInstance(DeviceMgtScopes.class);
|
||||
Unmarshaller unmarshaller = ctx.createUnmarshaller();
|
||||
//unmarshaller.setSchema(getSchema());
|
||||
DeviceMgtScopes deviceMgtScopes = (DeviceMgtScopes) unmarshaller.unmarshal(doc);
|
||||
if (deviceMgtScopes != null) {
|
||||
for (Action action : deviceMgtScopes.getAction()) {
|
||||
Permissions permissions = action.getPermissions();
|
||||
if (permissions != null) {
|
||||
String permission[] = new String[permissions.getPermission().size()];
|
||||
int i = 0;
|
||||
for (String perm : permissions.getPermission()) {
|
||||
permission[i] = perm;
|
||||
i++;
|
||||
}
|
||||
actionPermissionMap.put(action.getName(), permission);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (JAXBException e) {
|
||||
throw new DeviceMgtScopesConfigurationFailedException("Error occurred while un-marshalling Device Scope" +
|
||||
" Config", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, String[]> getDeviceMgtScopePermissionMap() {
|
||||
return actionPermissionMap;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.oauth.extensions.config;
|
||||
|
||||
public class DeviceMgtScopesConfigurationFailedException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = -3151279312929070398L;
|
||||
|
||||
public DeviceMgtScopesConfigurationFailedException(String msg, Exception nestedEx) {
|
||||
super(msg, nestedEx);
|
||||
}
|
||||
|
||||
public DeviceMgtScopesConfigurationFailedException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public DeviceMgtScopesConfigurationFailedException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public DeviceMgtScopesConfigurationFailedException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public DeviceMgtScopesConfigurationFailedException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,78 @@
|
||||
|
||||
package org.wso2.carbon.device.mgt.oauth.extensions.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for Permissions complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType name="Permissions">
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element name="Permission" maxOccurs="unbounded" minOccurs="0">
|
||||
* <simpleType>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}string">
|
||||
* <enumeration value="/permission/device-mgt/user/groups/device_operation"/>
|
||||
* <enumeration value="/permission/device-mgt/admin/groups"/>
|
||||
* <enumeration value="/permission/device-mgt/user/groups"/>
|
||||
* <enumeration value="/permission/device-mgt/user/groups/device_monitor"/>
|
||||
* </restriction>
|
||||
* </simpleType>
|
||||
* </element>
|
||||
* </sequence>
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "Permissions", propOrder = {
|
||||
"permission"
|
||||
})
|
||||
public class Permissions {
|
||||
|
||||
@XmlElement(name = "Permission")
|
||||
protected List<String> permission;
|
||||
|
||||
/**
|
||||
* Gets the value of the permission property.
|
||||
*
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the permission property.
|
||||
*
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getPermission().add(newItem);
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link String }
|
||||
*
|
||||
*
|
||||
*/
|
||||
public List<String> getPermission() {
|
||||
if (permission == null) {
|
||||
permission = new ArrayList<String>();
|
||||
}
|
||||
return this.permission;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
package org.wso2.carbon.device.mgt.oauth.extensions;
|
||||
|
||||
|
||||
/**
|
||||
* This hold the constants related oauth extensions.
|
||||
*/
|
||||
public class Constants {
|
||||
|
||||
public static final String DEFAULT_DEVICE_ASSERTION = "device";
|
||||
public static final String DEFAULT_USERNAME_IDENTIFIER = "username";
|
||||
public static final String DEFAULT_PASSWORD_IDENTIFIER = "password";
|
||||
|
||||
}
|
||||
@ -5,10 +5,10 @@ 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 {
|
||||
public class ExtendedDeviceMgtJWTBearerGrantHandler extends JWTBearerGrantHandler {
|
||||
|
||||
@Override
|
||||
public boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) throws IdentityOAuth2Exception {
|
||||
return OAuthExtUtils.setScopes(tokReqMsgCtx);
|
||||
return OAuthExtUtils.validateScope(tokReqMsgCtx);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.oauth.extensions.handlers.grant;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.wso2.carbon.apimgt.keymgt.handlers.ExtendedPasswordGrantHandler;
|
||||
import org.wso2.carbon.device.mgt.oauth.extensions.Constants;
|
||||
import org.wso2.carbon.device.mgt.oauth.extensions.DeviceRequestDTO;
|
||||
import org.wso2.carbon.device.mgt.oauth.extensions.OAuthExtUtils;
|
||||
import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception;
|
||||
import org.wso2.carbon.identity.oauth2.model.RequestParameter;
|
||||
import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class ExtendedDeviceMgtPasswordGrantHandler extends ExtendedPasswordGrantHandler {
|
||||
|
||||
private static Log log = LogFactory.getLog(ExtendedDeviceMgtPasswordGrantHandler.class);
|
||||
|
||||
@Override
|
||||
public boolean validateGrant(OAuthTokenReqMessageContext tokReqMsgCtx) throws IdentityOAuth2Exception {
|
||||
RequestParameter parameters[] = tokReqMsgCtx.getOauth2AccessTokenReqDTO().getRequestParameters();
|
||||
for (RequestParameter parameter : parameters) {
|
||||
switch (parameter.getKey()) {
|
||||
case Constants.DEFAULT_USERNAME_IDENTIFIER:
|
||||
String username = parameter.getValue()[0];
|
||||
tokReqMsgCtx.getOauth2AccessTokenReqDTO().setResourceOwnerUsername(username);
|
||||
break;
|
||||
|
||||
case Constants.DEFAULT_PASSWORD_IDENTIFIER:
|
||||
String password = parameter.getValue()[0];
|
||||
tokReqMsgCtx.getOauth2AccessTokenReqDTO().setResourceOwnerPassword(password);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.validateGrant(tokReqMsgCtx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) {
|
||||
return OAuthExtUtils.validateScope(tokReqMsgCtx);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,328 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.oauth.extensions.handlers.grant;
|
||||
|
||||
import org.apache.axiom.om.OMElement;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.wso2.carbon.device.mgt.oauth.extensions.OAuthExtUtils;
|
||||
import org.wso2.carbon.device.mgt.oauth.extensions.internal.OAuthExtensionsDataHolder;
|
||||
import org.wso2.carbon.identity.application.common.cache.BaseCache;
|
||||
import org.wso2.carbon.identity.core.util.IdentityConfigParser;
|
||||
import org.wso2.carbon.identity.core.util.IdentityCoreConstants;
|
||||
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
|
||||
import org.wso2.carbon.identity.oauth.common.OAuthConstants;
|
||||
import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception;
|
||||
import org.wso2.carbon.identity.oauth2.ResponseHeader;
|
||||
import org.wso2.carbon.identity.oauth2.dto.OAuth2AccessTokenReqDTO;
|
||||
import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext;
|
||||
import org.wso2.carbon.identity.oauth2.token.handlers.grant.PasswordGrantHandler;
|
||||
import org.wso2.carbon.user.api.Claim;
|
||||
import org.wso2.carbon.user.api.UserStoreException;
|
||||
import org.wso2.carbon.user.api.UserStoreManager;
|
||||
import org.wso2.carbon.user.core.UserRealm;
|
||||
import org.wso2.carbon.user.core.config.RealmConfiguration;
|
||||
import org.wso2.carbon.user.core.service.RealmService;
|
||||
import org.wso2.carbon.user.core.util.UserCoreUtil;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class ExtendedPasswordGrantHandler extends PasswordGrantHandler {
|
||||
|
||||
private static Log log = LogFactory.getLog(ExtendedPasswordGrantHandler.class);
|
||||
|
||||
private static final String CONFIG_ELEM_OAUTH = "OAuth";
|
||||
|
||||
// Claims that are set as response headers of access token response
|
||||
private static final String REQUIRED_CLAIM_URIS = "RequiredRespHeaderClaimUris";
|
||||
private BaseCache<String, Claim[]> userClaimsCache;
|
||||
|
||||
// Primary/Secondary Login configuration
|
||||
private static final String CLAIM_URI = "ClaimUri";
|
||||
private static final String LOGIN_CONFIG = "LoginConfig";
|
||||
private static final String USERID_LOGIN = "UserIdLogin";
|
||||
private static final String EMAIL_LOGIN = "EmailLogin";
|
||||
private static final String PRIMARY_LOGIN = "primary";
|
||||
|
||||
private Map<String, Map<String, String>> loginConfiguration = new ConcurrentHashMap<>();
|
||||
|
||||
private List<String> requiredHeaderClaimUris = new ArrayList<>();
|
||||
|
||||
public void init() throws IdentityOAuth2Exception {
|
||||
|
||||
super.init();
|
||||
|
||||
IdentityConfigParser configParser;
|
||||
configParser = IdentityConfigParser.getInstance();
|
||||
OMElement oauthElem = configParser.getConfigElement(CONFIG_ELEM_OAUTH);
|
||||
|
||||
// Get the required claim uris that needs to be included in the response.
|
||||
parseRequiredHeaderClaimUris(oauthElem.getFirstChildWithName(getQNameWithIdentityNS(REQUIRED_CLAIM_URIS)));
|
||||
|
||||
// read login config
|
||||
parseLoginConfig(oauthElem);
|
||||
|
||||
userClaimsCache = new BaseCache<>("UserClaimsCache");
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Successfully created UserClaimsCache under " + OAuthConstants.OAUTH_CACHE_MANAGER);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateGrant(OAuthTokenReqMessageContext tokReqMsgCtx)
|
||||
throws IdentityOAuth2Exception {
|
||||
|
||||
OAuth2AccessTokenReqDTO oAuth2AccessTokenReqDTO = tokReqMsgCtx.getOauth2AccessTokenReqDTO();
|
||||
String username = oAuth2AccessTokenReqDTO.getResourceOwnerUsername();
|
||||
String loginUserName = getLoginUserName(username);
|
||||
tokReqMsgCtx.getOauth2AccessTokenReqDTO().setResourceOwnerUsername(loginUserName);
|
||||
|
||||
boolean isValidated = super.validateGrant(tokReqMsgCtx);
|
||||
|
||||
if (isValidated) {
|
||||
|
||||
int tenantId;
|
||||
tenantId = IdentityTenantUtil.getTenantIdOfUser(username);
|
||||
|
||||
RealmService realmService = OAuthExtensionsDataHolder.getInstance().getRealmService();
|
||||
UserStoreManager userStoreManager;
|
||||
try {
|
||||
userStoreManager = realmService.getTenantUserRealm(tenantId).getUserStoreManager();
|
||||
} catch (UserStoreException e) {
|
||||
log.error("Error when getting the tenant's UserStoreManager", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
List<ResponseHeader> respHeaders = new ArrayList<>();
|
||||
|
||||
if (oAuth2AccessTokenReqDTO.getResourceOwnerUsername() != null) {
|
||||
try {
|
||||
if (requiredHeaderClaimUris != null && !requiredHeaderClaimUris.isEmpty()) {
|
||||
// Get user's claim values from the default profile.
|
||||
String userStoreDomain = tokReqMsgCtx.getAuthorizedUser().getUserStoreDomain();
|
||||
|
||||
String endUsernameWithDomain = UserCoreUtil.
|
||||
addDomainToName(oAuth2AccessTokenReqDTO.getResourceOwnerUsername(), userStoreDomain);
|
||||
|
||||
Claim[] mapClaimValues = getUserClaimValues(endUsernameWithDomain, userStoreManager);
|
||||
|
||||
if (mapClaimValues != null && mapClaimValues.length > 0) {
|
||||
ResponseHeader header;
|
||||
for (String claimUri : requiredHeaderClaimUris) {
|
||||
for (Claim claim : mapClaimValues) {
|
||||
if (claimUri.equals(claim.getClaimUri())) {
|
||||
header = new ResponseHeader();
|
||||
header.setKey(claim.getDisplayTag());
|
||||
header.setValue(claim.getValue());
|
||||
respHeaders.add(header);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (log.isDebugEnabled()) {
|
||||
log.debug("No claim values for user : " + endUsernameWithDomain);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new IdentityOAuth2Exception("Error occurred while retrieving user claims", e);
|
||||
}
|
||||
}
|
||||
tokReqMsgCtx.addProperty("RESPONSE_HEADERS", respHeaders.toArray(new ResponseHeader[respHeaders.size()]));
|
||||
}
|
||||
|
||||
return isValidated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) {
|
||||
return OAuthExtUtils.setScopes(tokReqMsgCtx);
|
||||
}
|
||||
|
||||
private String getLoginUserName(String userID) {
|
||||
String loginUserName = userID;
|
||||
if (isSecondaryLogin(userID)) {
|
||||
loginUserName = getPrimaryFromSecondary(userID);
|
||||
}
|
||||
return loginUserName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Identify whether the logged in user used his Primary Login name or
|
||||
* Secondary login name
|
||||
*
|
||||
* @param userId - The username used to login.
|
||||
* @return <code>true</code> if secondary login name is used,
|
||||
* <code>false</code> if primary login name has been used
|
||||
*/
|
||||
private boolean isSecondaryLogin(String userId) {
|
||||
|
||||
if (loginConfiguration.get(EMAIL_LOGIN) != null) {
|
||||
Map<String, String> emailConf = loginConfiguration.get(EMAIL_LOGIN);
|
||||
if ("true".equalsIgnoreCase(emailConf.get(PRIMARY_LOGIN))) {
|
||||
return !isUserLoggedInEmail(userId);
|
||||
} else if ("false".equalsIgnoreCase(emailConf.get(PRIMARY_LOGIN))) {
|
||||
return isUserLoggedInEmail(userId);
|
||||
}
|
||||
} else if (loginConfiguration.get(USERID_LOGIN) != null) {
|
||||
Map<String, String> userIdConf = loginConfiguration.get(USERID_LOGIN);
|
||||
if ("true".equalsIgnoreCase(userIdConf.get(PRIMARY_LOGIN))) {
|
||||
return isUserLoggedInEmail(userId);
|
||||
} else if ("false".equalsIgnoreCase(userIdConf.get(PRIMARY_LOGIN))) {
|
||||
return !isUserLoggedInEmail(userId);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Identify whether the logged in user used his ordinal username or email
|
||||
*
|
||||
* @param userId - username used to login.
|
||||
* @return - <code>true</code> if userId contains '@'. <code>false</code> otherwise
|
||||
*/
|
||||
private boolean isUserLoggedInEmail(String userId) {
|
||||
return userId.contains("@");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the primaryLogin name using secondary login name. Primary secondary
|
||||
* Configuration is provided in the identitiy.xml. In the userstore, it is
|
||||
* users responsibility TO MAINTAIN THE SECONDARY LOGIN NAME AS UNIQUE for
|
||||
* each and every users. If it is not unique, we will pick the very first
|
||||
* entry from the userlist.
|
||||
*
|
||||
* @param login - username used to login.
|
||||
* @return -
|
||||
*/
|
||||
private String getPrimaryFromSecondary(String login) {
|
||||
|
||||
String claimURI, username = null;
|
||||
if (isUserLoggedInEmail(login)) {
|
||||
Map<String, String> emailConf = loginConfiguration.get(EMAIL_LOGIN);
|
||||
claimURI = emailConf.get(CLAIM_URI);
|
||||
} else {
|
||||
Map<String, String> userIdConf = loginConfiguration.get(USERID_LOGIN);
|
||||
claimURI = userIdConf.get(CLAIM_URI);
|
||||
}
|
||||
|
||||
try {
|
||||
RealmService realmSvc = OAuthExtensionsDataHolder.getInstance().getRealmService();
|
||||
RealmConfiguration config = new RealmConfiguration();
|
||||
UserRealm realm = realmSvc.getUserRealm(config);
|
||||
org.wso2.carbon.user.core.UserStoreManager storeManager = realm.getUserStoreManager();
|
||||
String[] user = storeManager.getUserList(claimURI, login, null);
|
||||
if (user.length > 0) {
|
||||
username = user[0];
|
||||
}
|
||||
} catch (UserStoreException e) {
|
||||
log.error("Error while retrieving the primaryLogin name using secondary login name : " + login, e);
|
||||
}
|
||||
return username;
|
||||
}
|
||||
|
||||
private Claim[] getUserClaimValues(String authorizedUser, UserStoreManager userStoreManager)
|
||||
throws
|
||||
UserStoreException {
|
||||
Claim[] userClaims = userClaimsCache.getValueFromCache(authorizedUser);
|
||||
if (userClaims != null) {
|
||||
return userClaims;
|
||||
} else {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Cache miss for user claims. Username :" + authorizedUser);
|
||||
}
|
||||
userClaims = userStoreManager.getUserClaimValues(
|
||||
authorizedUser, null);
|
||||
userClaimsCache.addToCache(authorizedUser, userClaims);
|
||||
return userClaims;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the required claim configuration from identity.xml
|
||||
*/
|
||||
private void parseRequiredHeaderClaimUris(OMElement requiredClaimUrisElem) {
|
||||
if (requiredClaimUrisElem == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Iterator claimUris = requiredClaimUrisElem.getChildrenWithLocalName(CLAIM_URI);
|
||||
if (claimUris != null) {
|
||||
while (claimUris.hasNext()) {
|
||||
OMElement claimUri = (OMElement) claimUris.next();
|
||||
if (claimUri != null) {
|
||||
requiredHeaderClaimUris.add(claimUri.getText());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the primary/secondary login configuration
|
||||
* <OAuth>
|
||||
* ....
|
||||
* <LoginConfig>
|
||||
* <UserIdLogin primary="true">
|
||||
* <ClaimUri></ClaimUri>
|
||||
* </UserIdLogin>
|
||||
* <EmailLogin primary="false">
|
||||
* <ClaimUri>http://wso2.org/claims/emailaddress</ClaimUri>
|
||||
* </EmailLogin>
|
||||
* </LoginConfig>
|
||||
* .....
|
||||
* </OAuth>
|
||||
*
|
||||
* @param oauthConfigElem - The '<LoginConfig>' xml configuration element in the api-manager.xml
|
||||
*/
|
||||
private void parseLoginConfig(OMElement oauthConfigElem) {
|
||||
OMElement loginConfigElem = oauthConfigElem.getFirstChildWithName(getQNameWithIdentityNS(LOGIN_CONFIG));
|
||||
if (loginConfigElem != null) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Login configuration is set ");
|
||||
}
|
||||
// Primary/Secondary supported login mechanisms
|
||||
OMElement emailConfigElem = loginConfigElem.getFirstChildWithName(getQNameWithIdentityNS(EMAIL_LOGIN));
|
||||
|
||||
OMElement userIdConfigElem = loginConfigElem.getFirstChildWithName(getQNameWithIdentityNS(USERID_LOGIN));
|
||||
|
||||
Map<String, String> emailConf = new HashMap<String, String>(2);
|
||||
emailConf.put(PRIMARY_LOGIN,
|
||||
emailConfigElem.getAttributeValue(new QName(PRIMARY_LOGIN)));
|
||||
emailConf.put(CLAIM_URI,
|
||||
emailConfigElem.getFirstChildWithName(getQNameWithIdentityNS(CLAIM_URI))
|
||||
.getText());
|
||||
|
||||
Map<String, String> userIdConf = new HashMap<String, String>(2);
|
||||
userIdConf.put(PRIMARY_LOGIN,
|
||||
userIdConfigElem.getAttributeValue(new QName(PRIMARY_LOGIN)));
|
||||
userIdConf.put(CLAIM_URI,
|
||||
userIdConfigElem.getFirstChildWithName(getQNameWithIdentityNS(CLAIM_URI))
|
||||
.getText());
|
||||
|
||||
loginConfiguration.put(EMAIL_LOGIN, emailConf);
|
||||
loginConfiguration.put(USERID_LOGIN, userIdConf);
|
||||
}
|
||||
}
|
||||
|
||||
private QName getQNameWithIdentityNS(String localPart) {
|
||||
return new QName(IdentityCoreConstants.IDENTITY_DEFAULT_NAMESPACE, localPart);
|
||||
}
|
||||
}
|
||||
@ -24,8 +24,12 @@ import org.osgi.service.component.ComponentContext;
|
||||
import org.wso2.carbon.apimgt.api.APIManagementException;
|
||||
import org.wso2.carbon.apimgt.impl.APIConstants;
|
||||
import org.wso2.carbon.apimgt.impl.APIManagerConfiguration;
|
||||
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException;
|
||||
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService;
|
||||
import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagerService;
|
||||
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
|
||||
import org.wso2.carbon.device.mgt.oauth.extensions.config.DeviceMgtScopesConfig;
|
||||
import org.wso2.carbon.device.mgt.oauth.extensions.config.DeviceMgtScopesConfigurationFailedException;
|
||||
import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService;
|
||||
import org.wso2.carbon.user.core.service.RealmService;
|
||||
import org.wso2.carbon.utils.CarbonUtils;
|
||||
@ -54,12 +58,12 @@ import java.util.List;
|
||||
* policy="dynamic"
|
||||
* bind="setPermissionManagerService"
|
||||
* unbind="unsetPermissionManagerService"
|
||||
* @scr.reference name="org.wso2.carbon.device.manager"
|
||||
* interface="org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService"
|
||||
* @scr.reference name="org.wso2.carbon.device.authorization"
|
||||
* interface="org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService"
|
||||
* cardinality="1..1"
|
||||
* policy="dynamic"
|
||||
* bind="setDeviceManagementService"
|
||||
* unbind="unsetDeviceManagementService"
|
||||
* bind="setDeviceAccessAuthorizationService"
|
||||
* unbind="unsetDeviceAccessAuthorizationService"
|
||||
*/
|
||||
public class OAuthExtensionServiceComponent {
|
||||
|
||||
@ -67,8 +71,6 @@ public class OAuthExtensionServiceComponent {
|
||||
private static final String REPOSITORY = "repository";
|
||||
private static final String CONFIGURATION = "conf";
|
||||
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")
|
||||
@ -77,6 +79,8 @@ public class OAuthExtensionServiceComponent {
|
||||
log.debug("Starting OAuthExtensionBundle");
|
||||
}
|
||||
try {
|
||||
DeviceMgtScopesConfig.init();
|
||||
|
||||
APIManagerConfiguration configuration = new APIManagerConfiguration();
|
||||
String filePath = new StringBuilder().
|
||||
append(CarbonUtils.getCarbonHome()).
|
||||
@ -102,18 +106,10 @@ public class OAuthExtensionServiceComponent {
|
||||
}
|
||||
|
||||
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) {
|
||||
log.error("Error occurred while loading APIM configurations", e);
|
||||
log.error("Error occurred while loading DeviceMgtConfig configurations", e);
|
||||
} catch (DeviceMgtScopesConfigurationFailedException e) {
|
||||
log.error("Failed to initialize device scope configuration.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -198,24 +194,24 @@ public class OAuthExtensionServiceComponent {
|
||||
|
||||
/**
|
||||
* Set DeviceManagementProviderService
|
||||
* @param deviceManagerService An instance of PermissionManagerService
|
||||
* @param deviceAccessAuthorizationService An instance of deviceAccessAuthorizationService
|
||||
*/
|
||||
protected void setDeviceManagementService(DeviceManagementProviderService deviceManagerService) {
|
||||
protected void setDeviceAccessAuthorizationService(DeviceAccessAuthorizationService deviceAccessAuthorizationService) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Setting Device Management Service");
|
||||
}
|
||||
OAuthExtensionsDataHolder.getInstance().setDeviceManagementService(deviceManagerService);
|
||||
OAuthExtensionsDataHolder.getInstance().setDeviceAccessAuthorizationService(deviceAccessAuthorizationService);
|
||||
}
|
||||
|
||||
/**
|
||||
* unset DeviceManagementProviderService
|
||||
* @param deviceManagementService An instance of PermissionManagerService
|
||||
* @param deviceAccessAuthorizationService An instance of deviceAccessAuthorizationService
|
||||
*/
|
||||
protected void unsetDeviceManagementService(DeviceManagementProviderService deviceManagementService) {
|
||||
protected void unsetDeviceAccessAuthorizationService(DeviceAccessAuthorizationService deviceAccessAuthorizationService) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Removing Device Management Service");
|
||||
}
|
||||
OAuthExtensionsDataHolder.getInstance().setDeviceManagementService(null);
|
||||
OAuthExtensionsDataHolder.getInstance().setDeviceAccessAuthorizationService(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
|
||||
package org.wso2.carbon.device.mgt.oauth.extensions.internal;
|
||||
|
||||
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService;
|
||||
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;
|
||||
@ -35,7 +36,7 @@ public class OAuthExtensionsDataHolder {
|
||||
private PermissionManagerService permissionManagerService;
|
||||
private List<String> whitelistedScopes;
|
||||
private String deviceScope;
|
||||
private DeviceManagementProviderService deviceManagementService;
|
||||
private DeviceAccessAuthorizationService deviceAccessAuthorizationService;
|
||||
|
||||
private static OAuthExtensionsDataHolder thisInstance = new OAuthExtensionsDataHolder();
|
||||
|
||||
@ -87,19 +88,15 @@ public class OAuthExtensionsDataHolder {
|
||||
this.whitelistedScopes = whitelistedScopes;
|
||||
}
|
||||
|
||||
public void setDeviceScope(String deviceScope) {
|
||||
this.deviceScope = deviceScope;
|
||||
}
|
||||
|
||||
public String getDeviceScope() {
|
||||
return deviceScope;
|
||||
}
|
||||
|
||||
public DeviceManagementProviderService getDeviceManagementService() {
|
||||
return deviceManagementService;
|
||||
public DeviceAccessAuthorizationService getDeviceAccessAuthorizationService() {
|
||||
return deviceAccessAuthorizationService;
|
||||
}
|
||||
|
||||
public void setDeviceManagementService(DeviceManagementProviderService deviceManagementService) {
|
||||
this.deviceManagementService = deviceManagementService;
|
||||
public void setDeviceAccessAuthorizationService(DeviceAccessAuthorizationService deviceAccessAuthorizationService) {
|
||||
this.deviceAccessAuthorizationService = deviceAccessAuthorizationService;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.oauth.extensions.validators;
|
||||
|
||||
import org.apache.oltu.oauth2.common.OAuth;
|
||||
import org.apache.oltu.oauth2.common.validators.AbstractValidator;
|
||||
import org.wso2.carbon.device.mgt.oauth.extensions.Constants;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* Grant validator for JSON Web Tokens
|
||||
* For JWT Grant to be valid the required parameters are
|
||||
* grant_type and assertion
|
||||
*/
|
||||
public class ExtendedDeviceJWTGrantValidator extends AbstractValidator<HttpServletRequest> {
|
||||
|
||||
public ExtendedDeviceJWTGrantValidator() {
|
||||
requiredParams.add(OAuth.OAUTH_GRANT_TYPE);
|
||||
requiredParams.add(OAuth.OAUTH_ASSERTION);
|
||||
requiredParams.add(Constants.DEFAULT_DEVICE_ASSERTION);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License
|
||||
*/
|
||||
|
||||
package org.wso2.carbon.device.mgt.oauth.extensions.validators;
|
||||
|
||||
import org.apache.oltu.oauth2.common.OAuth;
|
||||
import org.apache.oltu.oauth2.common.validators.AbstractValidator;
|
||||
import org.wso2.carbon.device.mgt.oauth.extensions.Constants;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* Grant validator for Device Object with Password Grant type
|
||||
*/
|
||||
public class ExtendedDevicePasswordGrantValidator extends AbstractValidator<HttpServletRequest> {
|
||||
|
||||
public ExtendedDevicePasswordGrantValidator() {
|
||||
requiredParams.add(OAuth.OAUTH_USERNAME);
|
||||
requiredParams.add(OAuth.OAUTH_PASSWORD);
|
||||
requiredParams.add(Constants.DEFAULT_DEVICE_ASSERTION);
|
||||
}
|
||||
}
|
||||
@ -23,7 +23,7 @@ package org.wso2.carbon.identity.jwt.client.extension.constant;
|
||||
public class JWTConstants {
|
||||
public static final String OAUTH_EXPIRES_IN = "expires_in";
|
||||
public static final String OAUTH_TOKEN_TYPE = "token_type";
|
||||
public static final String JWT_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer";
|
||||
public static final String JWT_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:device-mgt:jwt-bearer";
|
||||
public static final String GRANT_TYPE_PARAM_NAME = "grant_type";
|
||||
public static final String REFRESH_TOKEN_GRANT_TYPE = "refresh_token";
|
||||
public static final String REFRESH_TOKEN_GRANT_TYPE_PARAM_NAME = "refresh_token";
|
||||
|
||||
Loading…
Reference in New Issue
Block a user