mirror of
https://repository.entgra.net/community/device-mgt-core.git
synced 2025-10-06 02:01:45 +00:00
Fix dcr and token endpoint related issues
This commit is contained in:
parent
9225512874
commit
0d43e7d6aa
@ -49,6 +49,7 @@ public class APIUtil {
|
||||
private static final String DEFAULT_ANALYTICS_ARTIFACT_TAG = "analytics_artifacts_management";
|
||||
private static final String DEFAULT_TRANSPORT_MGT_TAG = "transport_management";
|
||||
private static final String DEFAULT_ENTERPRISE_TAG= "androidforwork";
|
||||
private static final String DEFAULT_ANALYTICS_MGT_TAG= "analytics_management";
|
||||
|
||||
public static final String PERMISSION_PROPERTY_NAME = "name";
|
||||
|
||||
@ -119,6 +120,7 @@ public class APIUtil {
|
||||
allowedApisTags.add(DEFAULT_APP_MGT_SUB_MGT_TAG);
|
||||
allowedApisTags.add(DEFAULT_ANALYTICS_ARTIFACT_TAG);
|
||||
allowedApisTags.add(DEFAULT_TRANSPORT_MGT_TAG);
|
||||
allowedApisTags.add(DEFAULT_ANALYTICS_MGT_TAG);
|
||||
// In an environment only super tenant should be capable of calling this API tag
|
||||
if (PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId() ==
|
||||
MultitenantConstants.SUPER_TENANT_ID) {
|
||||
|
||||
@ -28,9 +28,9 @@ import javax.xml.bind.annotation.XmlRootElement;
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class DCRRequest {
|
||||
@XmlElement(required = true)
|
||||
private String clientName;
|
||||
private String applicationName;
|
||||
@XmlElement(required = true)
|
||||
private String owner;
|
||||
private String username;
|
||||
@XmlElement(required = true)
|
||||
private String grantTypes;
|
||||
@XmlElement
|
||||
@ -40,20 +40,20 @@ public class DCRRequest {
|
||||
@XmlElement
|
||||
private boolean isSaasApp;
|
||||
|
||||
public String getClientName() {
|
||||
return clientName;
|
||||
public String getApplicationName() {
|
||||
return applicationName;
|
||||
}
|
||||
|
||||
public void setClientName(String clientName) {
|
||||
this.clientName = clientName;
|
||||
public void setApplicationName(String applicationName) {
|
||||
this.applicationName = applicationName;
|
||||
}
|
||||
|
||||
public String getOwner() {
|
||||
return owner;
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setOwner(String owner) {
|
||||
this.owner = owner;
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getGrantTypes() {
|
||||
|
||||
@ -20,6 +20,7 @@ package org.wso2.carbon.apimgt.keymgt.extension.api;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.FormParam;
|
||||
import javax.ws.rs.HeaderParam;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
@ -38,9 +39,12 @@ public interface KeyManagerService {
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
@Path("/token")
|
||||
Response generateAccessToken(@FormParam("client_id") String clientId,
|
||||
Response generateAccessToken(@HeaderParam("Authorization") String basicAuthHeader,
|
||||
@FormParam("client_id") String clientId,
|
||||
@FormParam("client_secret") String clientSecret,
|
||||
@FormParam("refresh_token") String refreshToken,
|
||||
@FormParam("scope") String scope,
|
||||
@FormParam("grant_type") String grantType);
|
||||
@FormParam("grant_type") String grantType,
|
||||
@FormParam("assertion") String assertion,
|
||||
@FormParam("admin_access_token") String admin_access_token);
|
||||
}
|
||||
|
||||
@ -27,14 +27,17 @@ import org.wso2.carbon.apimgt.keymgt.extension.exception.BadRequestException;
|
||||
import org.wso2.carbon.apimgt.keymgt.extension.exception.KeyMgtException;
|
||||
import org.wso2.carbon.apimgt.keymgt.extension.service.KeyMgtService;
|
||||
import org.wso2.carbon.apimgt.keymgt.extension.service.KeyMgtServiceImpl;
|
||||
import org.wso2.carbon.device.mgt.common.exceptions.UnAuthorizedException;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.FormParam;
|
||||
import javax.ws.rs.HeaderParam;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.util.Base64;
|
||||
|
||||
public class KeyManagerServiceImpl implements KeyManagerService {
|
||||
|
||||
@ -46,7 +49,7 @@ public class KeyManagerServiceImpl implements KeyManagerService {
|
||||
public Response dynamicClientRegistration(DCRRequest dcrRequest) {
|
||||
try {
|
||||
KeyMgtService keyMgtService = new KeyMgtServiceImpl();
|
||||
DCRResponse resp = keyMgtService.dynamicClientRegistration(dcrRequest.getClientName(), dcrRequest.getOwner(),
|
||||
DCRResponse resp = keyMgtService.dynamicClientRegistration(dcrRequest.getApplicationName(), dcrRequest.getUsername(),
|
||||
dcrRequest.getGrantTypes(), dcrRequest.getCallBackUrl(), dcrRequest.getTags(), dcrRequest.getIsSaasApp());
|
||||
return Response.status(Response.Status.CREATED).entity(resp).build();
|
||||
} catch (KeyMgtException e) {
|
||||
@ -58,20 +61,32 @@ public class KeyManagerServiceImpl implements KeyManagerService {
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
@Path("/token")
|
||||
public Response generateAccessToken(@FormParam("client_id") String clientId,
|
||||
public Response generateAccessToken(@HeaderParam("Authorization") String basicAuthHeader,
|
||||
@FormParam("client_id") String clientId,
|
||||
@FormParam("client_secret") String clientSecret,
|
||||
@FormParam("refresh_token") String refreshToken,
|
||||
@FormParam("scope") String scope,
|
||||
@FormParam("grant_type") String grantType) {
|
||||
@FormParam("grant_type") String grantType,
|
||||
@FormParam("assertion") String assertion,
|
||||
@FormParam("admin_access_token") String admin_access_token) {
|
||||
try {
|
||||
if (basicAuthHeader == null) {
|
||||
String msg = "Invalid credentials. Make sure your API call is invoked with a Basic Authorization header.";
|
||||
throw new UnAuthorizedException(msg);
|
||||
}
|
||||
String encodedClientCredentials = new String(Base64.getDecoder().decode(basicAuthHeader.split(" ")[1]));
|
||||
KeyMgtService keyMgtService = new KeyMgtServiceImpl();
|
||||
TokenResponse resp = keyMgtService.generateAccessToken(
|
||||
new TokenRequest(clientId, clientSecret, refreshToken, scope, grantType));
|
||||
new TokenRequest(encodedClientCredentials.split(":")[0],
|
||||
encodedClientCredentials.split(":")[1], refreshToken, scope,
|
||||
grantType, assertion,admin_access_token));
|
||||
return Response.status(Response.Status.CREATED).entity(resp).build();
|
||||
} catch (KeyMgtException e) {
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (UnAuthorizedException e) {
|
||||
return Response.status(Response.Status.UNAUTHORIZED).entity(e.getMessage()).build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,27 +19,27 @@
|
||||
package org.wso2.carbon.apimgt.keymgt.extension;
|
||||
|
||||
public class DCRResponse {
|
||||
String clientId;
|
||||
String clientSecret;
|
||||
String client_id;
|
||||
String client_secret;
|
||||
|
||||
public DCRResponse(String clientId, String clientSecret) {
|
||||
this.clientId = clientId;
|
||||
this.clientSecret = clientSecret;
|
||||
public DCRResponse(String client_id, String client_secret) {
|
||||
this.client_id = client_id;
|
||||
this.client_secret = client_secret;
|
||||
}
|
||||
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
return client_id;
|
||||
}
|
||||
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
public void setClientId(String client_id) {
|
||||
this.client_id = client_id;
|
||||
}
|
||||
|
||||
public String getClientSecret() {
|
||||
return clientSecret;
|
||||
return client_secret;
|
||||
}
|
||||
|
||||
public void setClientSecret(String clientSecret) {
|
||||
this.clientSecret = clientSecret;
|
||||
public void setClientSecret(String client_secret) {
|
||||
this.client_secret = client_secret;
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,13 +24,18 @@ public class TokenRequest {
|
||||
private String refreshToken;
|
||||
private String scope;
|
||||
private String grantType;
|
||||
private String assertion;
|
||||
private String admin_access_token;
|
||||
|
||||
public TokenRequest(String clientId, String clientSecret, String refreshToken, String scope, String grantType) {
|
||||
public TokenRequest(String clientId, String clientSecret, String refreshToken, String scope, String grantType,
|
||||
String assertion, String admin_access_token) {
|
||||
this.clientId = clientId;
|
||||
this.clientSecret = clientSecret;
|
||||
this.refreshToken = refreshToken;
|
||||
this.scope = scope;
|
||||
this.grantType = grantType;
|
||||
this.assertion = assertion;
|
||||
this.admin_access_token = admin_access_token;
|
||||
}
|
||||
|
||||
public String getClientId() {
|
||||
@ -72,4 +77,20 @@ public class TokenRequest {
|
||||
public void setRefreshToken(String refreshToken) {
|
||||
this.refreshToken = refreshToken;
|
||||
}
|
||||
|
||||
public String getAssertion() {
|
||||
return assertion;
|
||||
}
|
||||
|
||||
public void setAssertion(String assertion) {
|
||||
this.assertion = assertion;
|
||||
}
|
||||
|
||||
public String getAdminAccessToken() {
|
||||
return admin_access_token;
|
||||
}
|
||||
|
||||
public void setAdminAccessToken(String admin_access_token) {
|
||||
this.admin_access_token = admin_access_token;
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,14 +22,14 @@ public class TokenResponse {
|
||||
private String access_token;
|
||||
private String refresh_token;
|
||||
private String scope;
|
||||
private String tokenType;
|
||||
private String token_type;
|
||||
private int expires_in;
|
||||
|
||||
public TokenResponse(String access_token, String refresh_token, String scope, String tokenType, int expires_in) {
|
||||
public TokenResponse(String access_token, String refresh_token, String scope, String token_type, int expires_in) {
|
||||
this.access_token = access_token;
|
||||
this.refresh_token = refresh_token;
|
||||
this.scope = scope;
|
||||
this.tokenType = tokenType;
|
||||
this.token_type = token_type;
|
||||
this.expires_in = expires_in;
|
||||
}
|
||||
|
||||
@ -57,12 +57,12 @@ public class TokenResponse {
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
public String getTokenType() {
|
||||
return tokenType;
|
||||
public String getToken_Type() {
|
||||
return token_type;
|
||||
}
|
||||
|
||||
public void setTokenType(String tokenType) {
|
||||
this.tokenType = tokenType;
|
||||
public void setTokenType(String token_type) {
|
||||
this.token_type = token_type;
|
||||
}
|
||||
|
||||
public int getExpiresIn() {
|
||||
|
||||
@ -20,6 +20,7 @@ package org.wso2.carbon.apimgt.keymgt.extension.service;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import okhttp3.Credentials;
|
||||
import okhttp3.FormBody;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
@ -41,7 +42,6 @@ import org.wso2.carbon.apimgt.keymgt.extension.KeyMgtConstants;
|
||||
import org.wso2.carbon.apimgt.keymgt.extension.OAuthApplication;
|
||||
import org.wso2.carbon.apimgt.keymgt.extension.TokenRequest;
|
||||
import org.wso2.carbon.apimgt.keymgt.extension.TokenResponse;
|
||||
import org.wso2.carbon.apimgt.keymgt.extension.exception.BadRequestException;
|
||||
import org.wso2.carbon.apimgt.keymgt.extension.exception.KeyMgtException;
|
||||
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
||||
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
|
||||
@ -53,9 +53,7 @@ import org.wso2.carbon.user.api.UserStoreManager;
|
||||
import org.wso2.carbon.user.core.service.RealmService;
|
||||
import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
@ -82,6 +80,17 @@ public class KeyMgtServiceImpl implements KeyMgtService {
|
||||
public DCRResponse dynamicClientRegistration(String clientName, String owner, String grantTypes, String callBackUrl,
|
||||
String[] tags, boolean isSaasApp) throws KeyMgtException {
|
||||
|
||||
if (owner == null) {
|
||||
PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
|
||||
try {
|
||||
owner = APIUtil.getTenantAdminUserName(threadLocalCarbonContext.getTenantDomain());
|
||||
} catch (APIManagementException e) {
|
||||
String msg = "Error occurred while retrieving admin user for the tenant " + threadLocalCarbonContext.getTenantDomain();
|
||||
log.error(msg, e);
|
||||
throw new KeyMgtException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
String tenantDomain = MultitenantUtils.getTenantDomain(owner);
|
||||
int tenantId;
|
||||
|
||||
@ -97,10 +106,8 @@ public class KeyMgtServiceImpl implements KeyMgtService {
|
||||
kmConfig = getKeyManagerConfig();
|
||||
|
||||
if (KeyMgtConstants.SUPER_TENANT.equals(tenantDomain)) {
|
||||
OAuthApplication superTenantOauthApp = createOauthApplication(
|
||||
KeyMgtConstants.RESERVED_OAUTH_APP_NAME_PREFIX + KeyMgtConstants.SUPER_TENANT,
|
||||
kmConfig.getAdminUsername(), tags);
|
||||
return new DCRResponse(superTenantOauthApp.getClientId(), superTenantOauthApp.getClientSecret());
|
||||
OAuthApplication dcrApplication = createOauthApplication(clientName, kmConfig.getAdminUsername(), tags);
|
||||
return new DCRResponse(dcrApplication.getClientId(), dcrApplication.getClientSecret());
|
||||
} else {
|
||||
// super-tenant admin dcr and token generation
|
||||
OAuthApplication superTenantOauthApp = createOauthApplication(
|
||||
@ -141,7 +148,7 @@ public class KeyMgtServiceImpl implements KeyMgtService {
|
||||
}
|
||||
}
|
||||
|
||||
public TokenResponse generateAccessToken(TokenRequest tokenRequest) throws KeyMgtException, BadRequestException {
|
||||
public TokenResponse generateAccessToken(TokenRequest tokenRequest) throws KeyMgtException {
|
||||
try {
|
||||
Application application = APIUtil.getApplicationByClientId(tokenRequest.getClientId());
|
||||
String tenantDomain = MultitenantUtils.getTenantDomain(application.getOwner());
|
||||
@ -167,20 +174,43 @@ public class KeyMgtServiceImpl implements KeyMgtService {
|
||||
}
|
||||
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
if ("client_credentials".equals(tokenRequest.getGrantType())) {
|
||||
jsonObject.put("grant_type", "password");
|
||||
jsonObject.put("username", username);
|
||||
jsonObject.put("password", password);
|
||||
} else if ("refresh_token".equals(tokenRequest.getGrantType())) {
|
||||
jsonObject.put("grant_type", "refresh_token");
|
||||
jsonObject.put("refresh_token", tokenRequest.getRefreshToken());
|
||||
} else {
|
||||
msg = "Invalid grant type: " + tokenRequest.getGrantType();
|
||||
throw new BadRequestException(msg);
|
||||
RequestBody appTokenPayload;
|
||||
switch (tokenRequest.getGrantType()) {
|
||||
case "client_credentials":
|
||||
case "password":
|
||||
appTokenPayload = new FormBody.Builder()
|
||||
.add("grant_type", "password")
|
||||
.add("username", username)
|
||||
.add("password", password)
|
||||
.add("scope", tokenRequest.getScope()).build();
|
||||
break;
|
||||
|
||||
case "refresh_token":
|
||||
appTokenPayload = new FormBody.Builder()
|
||||
.add("grant_type", "refresh_token")
|
||||
.add("refresh_token", tokenRequest.getRefreshToken())
|
||||
.add("scope", tokenRequest.getScope()).build();
|
||||
break;
|
||||
case "urn:ietf:params:oauth:grant-type:jwt-bearer":
|
||||
appTokenPayload = new FormBody.Builder()
|
||||
.add("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer")
|
||||
.add("assertion", tokenRequest.getAssertion())
|
||||
.add("scope", tokenRequest.getScope()).build();
|
||||
break;
|
||||
case "access_token":
|
||||
appTokenPayload = new FormBody.Builder()
|
||||
.add("grant_type", "access_token")
|
||||
.add("admin_access_token", tokenRequest.getAdminAccessToken())
|
||||
.add("scope", tokenRequest.getScope()).build();
|
||||
break;
|
||||
default:
|
||||
appTokenPayload = new FormBody.Builder()
|
||||
.add("grant_type", tokenRequest.getGrantType())
|
||||
.add("scope", tokenRequest.getScope()).build();
|
||||
break;
|
||||
}
|
||||
jsonObject.put("scope", tokenRequest.getScope());
|
||||
|
||||
RequestBody appTokenPayload = RequestBody.Companion.create(jsonObject.toString(), JSON);
|
||||
kmConfig = getKeyManagerConfig();
|
||||
String appTokenEndpoint = kmConfig.getServerUrl() + KeyMgtConstants.OAUTH2_TOKEN_ENDPOINT;
|
||||
Request request = new Request.Builder()
|
||||
@ -449,12 +479,7 @@ public class KeyMgtServiceImpl implements KeyMgtService {
|
||||
};
|
||||
return new OkHttpClient.Builder()
|
||||
.sslSocketFactory(getSimpleTrustedSSLSocketFactory(), trustAllCerts)
|
||||
.hostnameVerifier(new HostnameVerifier() {
|
||||
@Override
|
||||
public boolean verify(String s, SSLSession sslSession) {
|
||||
return true;
|
||||
}
|
||||
}).build();
|
||||
.hostnameVerifier((hostname, sslSession) -> true).build();
|
||||
}
|
||||
|
||||
private static SSLSocketFactory getSimpleTrustedSSLSocketFactory() {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
instructions.configure = \
|
||||
org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../deployment/server/webapps/);\
|
||||
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.apimgt.keymgt.extension_${feature.version}/webapps/api-key-management.war,target:${installFolder}/../../deployment/server/webapps/api-key-management.war,overwrite:true);\
|
||||
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.apimgt.keymgt.extension_${feature.version}/synapse-configs/default/api/_API_Key_Management_.xml,target:${installFolder}/../../deployment/server/synapse-configs/default/api/_API_Key_Management_.xml,overwrite:true);\
|
||||
|
||||
@ -0,0 +1,46 @@
|
||||
<!--
|
||||
~ /*
|
||||
~ * Copyright (c) 2022, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
|
||||
~ *
|
||||
~ * Entgra (Pvt) Ltd. 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.
|
||||
~ */
|
||||
~
|
||||
-->
|
||||
|
||||
<api xmlns="http://ws.apache.org/ns/synapse" name="_API_Key_Management_" context="/api-application-registration/register">
|
||||
<resource methods="POST" url-mapping="" faultSequence="_api_registration_fault_">
|
||||
<inSequence>
|
||||
<property name="uri.var.portnum" expression="get-property('system','iot.core.https.port')"/>
|
||||
<property name="uri.var.hostname" expression="get-property('system','iot.core.host')"/>
|
||||
<send>
|
||||
<endpoint>
|
||||
<http uri-template="https://{uri.var.hostname}:{uri.var.portnum}/api-key-management/dynamic-client-registration">
|
||||
<timeout>
|
||||
<duration>60000</duration>
|
||||
<responseAction>fault</responseAction>
|
||||
</timeout>
|
||||
</http>
|
||||
</endpoint>
|
||||
</send>
|
||||
</inSequence>
|
||||
<outSequence>
|
||||
<send/>
|
||||
</outSequence>
|
||||
</resource>
|
||||
<handlers>
|
||||
<handler class="org.wso2.carbon.apimgt.gateway.handlers.ext.APIManagerCacheExtensionHandler"/>
|
||||
<handler class="org.wso2.carbon.apimgt.gateway.handlers.common.SynapsePropertiesHandler"/>
|
||||
</handlers>
|
||||
</api>
|
||||
Loading…
Reference in New Issue
Block a user