From b9e8ef6db232f403f0fc521ac8b3a8f40483a4b9 Mon Sep 17 00:00:00 2001 From: Thumimku Date: Fri, 10 Nov 2023 16:25:01 +0530 Subject: [PATCH] add application mgt service --- .../pom.xml | 8 ++ .../spotbugs-exclude.xml | 28 +++--- .../ApplicationManagementServiceFactory.java | 56 ++++++++++++ .../filter/ClientAttestationProxy.java | 85 +++++++++++++++++-- .../src/main/webapp/WEB-INF/cxf-servlet.xml | 2 + 5 files changed, 160 insertions(+), 19 deletions(-) create mode 100644 components/org.wso2.carbon.identity.client.attestation.filter/src/main/java/org/wso2/carbon/identity/client/attestation/filter/ApplicationManagementServiceFactory.java diff --git a/components/org.wso2.carbon.identity.client.attestation.filter/pom.xml b/components/org.wso2.carbon.identity.client.attestation.filter/pom.xml index 9b7742ec96..1982979c22 100644 --- a/components/org.wso2.carbon.identity.client.attestation.filter/pom.xml +++ b/components/org.wso2.carbon.identity.client.attestation.filter/pom.xml @@ -60,6 +60,14 @@ org.wso2.carbon.identity.framework org.wso2.carbon.identity.client.attestation.mgt + + org.wso2.carbon.identity.framework + org.wso2.carbon.identity.application.mgt + + + org.wso2.carbon.identity.framework + org.wso2.carbon.identity.application.common + org.wso2.carbon.identity.framework org.wso2.carbon.identity.core diff --git a/components/org.wso2.carbon.identity.client.attestation.filter/spotbugs-exclude.xml b/components/org.wso2.carbon.identity.client.attestation.filter/spotbugs-exclude.xml index 21f95d43ba..3449551fd0 100644 --- a/components/org.wso2.carbon.identity.client.attestation.filter/spotbugs-exclude.xml +++ b/components/org.wso2.carbon.identity.client.attestation.filter/spotbugs-exclude.xml @@ -1,20 +1,21 @@ @@ -24,4 +25,7 @@ + + + diff --git a/components/org.wso2.carbon.identity.client.attestation.filter/src/main/java/org/wso2/carbon/identity/client/attestation/filter/ApplicationManagementServiceFactory.java b/components/org.wso2.carbon.identity.client.attestation.filter/src/main/java/org/wso2/carbon/identity/client/attestation/filter/ApplicationManagementServiceFactory.java new file mode 100644 index 0000000000..c9dafe5157 --- /dev/null +++ b/components/org.wso2.carbon.identity.client.attestation.filter/src/main/java/org/wso2/carbon/identity/client/attestation/filter/ApplicationManagementServiceFactory.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * 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.identity.client.attestation.filter; + +import org.springframework.beans.factory.config.AbstractFactoryBean; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.identity.application.mgt.ApplicationManagementService; + +/** + * Factory Beans serves as a factory for creating other beans within the IOC container. This factory bean is used to + * instantiate the ApplicationManagementService type of object inside the container. + */ +public class ApplicationManagementServiceFactory extends AbstractFactoryBean { + + public ApplicationManagementService applicationManagementService; + + + @Override + public Class getObjectType() { + + return ApplicationManagementService.class; + } + + @Override + protected ApplicationManagementService createInstance() throws Exception { + + if (this.applicationManagementService != null) { + return this.applicationManagementService; + } else { + ApplicationManagementService applicationManagementService = + (ApplicationManagementService) PrivilegedCarbonContext + .getThreadLocalCarbonContext().getOSGiService(ApplicationManagementService.class, null); + if (applicationManagementService != null) { + this.applicationManagementService = applicationManagementService; + } + return applicationManagementService; + } + } +} diff --git a/components/org.wso2.carbon.identity.client.attestation.filter/src/main/java/org/wso2/carbon/identity/client/attestation/filter/ClientAttestationProxy.java b/components/org.wso2.carbon.identity.client.attestation.filter/src/main/java/org/wso2/carbon/identity/client/attestation/filter/ClientAttestationProxy.java index de9cc5c1e5..6d9803f1d9 100644 --- a/components/org.wso2.carbon.identity.client.attestation.filter/src/main/java/org/wso2/carbon/identity/client/attestation/filter/ClientAttestationProxy.java +++ b/components/org.wso2.carbon.identity.client.attestation.filter/src/main/java/org/wso2/carbon/identity/client/attestation/filter/ClientAttestationProxy.java @@ -26,7 +26,12 @@ import org.apache.cxf.message.Message; import org.apache.cxf.phase.AbstractPhaseInterceptor; import org.apache.cxf.phase.Phase; +import org.json.JSONObject; import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.identity.application.common.IdentityApplicationManagementException; +import org.wso2.carbon.identity.application.common.model.ServiceProvider; +import org.wso2.carbon.identity.application.mgt.ApplicationManagementService; +import org.wso2.carbon.identity.client.attestation.mgt.exceptions.ClientAttestationMgtException; import org.wso2.carbon.identity.client.attestation.mgt.model.ClientAttestationContext; import org.wso2.carbon.identity.client.attestation.mgt.services.ClientAttestationService; import org.wso2.carbon.identity.core.util.IdentityTenantUtil; @@ -35,12 +40,15 @@ import java.util.Optional; import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; import static org.wso2.carbon.identity.client.attestation.mgt.utils.Constants.ATTESTATION_HEADER; import static org.wso2.carbon.identity.client.attestation.mgt.utils.Constants.CLIENT_ATTESTATION_CONTEXT; import static org.wso2.carbon.identity.client.attestation.mgt.utils.Constants.CLIENT_ID; import static org.wso2.carbon.identity.client.attestation.mgt.utils.Constants.DIRECT; +import static org.wso2.carbon.identity.client.attestation.mgt.utils.Constants.OAUTH2; import static org.wso2.carbon.identity.client.attestation.mgt.utils.Constants.RESPONSE_MODE; /** @@ -64,6 +72,7 @@ public class ClientAttestationProxy extends AbstractPhaseInterceptor { private static final String HTTP_REQUEST = "HTTP.REQUEST"; private ClientAttestationService clientAttestationService; + private ApplicationManagementService applicationManagementService; public ClientAttestationProxy() { @@ -72,6 +81,16 @@ public ClientAttestationProxy() { super(Phase.PRE_INVOKE); } + public ApplicationManagementService getApplicationManagementService() { + + return applicationManagementService; + } + + public void setApplicationManagementService(ApplicationManagementService applicationManagementService) { + + this.applicationManagementService = applicationManagementService; + } + public ClientAttestationService getClientAttestationService() { return clientAttestationService; @@ -86,7 +105,6 @@ public void setClientAttestationService(ClientAttestationService clientAttestati * Handles the incoming JAX-RS message for the purpose of OAuth2 client authentication. * It extracts the HttpServletRequest from the incoming message, retrieves the attestation header * from the HTTP request, and extracts content parameters from the message. - * * If the incoming request is determined to be an API-based authentication request, it proceeds to: * 1. Validate the attestation header to establish client authenticity and obtain a client * attestation context. @@ -105,12 +123,42 @@ public void handleMessage(Message message) { // Check if this is an API-based authentication request if (isApiBasedAuthnRequest(bodyContentParams)) { - // Validate the attestation header and obtain client attestation context - ClientAttestationContext clientAttestationContext = - clientAttestationService.validateAttestation(attestationHeader, - getClientId(bodyContentParams), getTenantDomain()); - // Set the client attestation context in the HTTP request - setContextToRequest(request, clientAttestationContext); + + String clientId = getClientId(bodyContentParams); + if (StringUtils.isEmpty(clientId)) { + + String errorMessage = new JSONObject().put("error_description", "Client Id not found.") + .put("error", "Bad Request").toString(); + Response response = Response.status(Response.Status.BAD_REQUEST).entity(errorMessage) + .build(); + throw new WebApplicationException(response); + } else { + try { + ServiceProvider serviceProvider = getServiceProvider(clientId, getTenantDomain()); + // Validate the attestation header and obtain client attestation context + ClientAttestationContext clientAttestationContext = clientAttestationService + .validateAttestation(attestationHeader, + serviceProvider.getApplicationResourceId(), getTenantDomain()); + // Set the client attestation context in the HTTP request + setContextToRequest(request, clientAttestationContext); + if (!clientAttestationContext.isAttested()) { + String errorMessage = new JSONObject().put("error_description", + "Client Attestation validation failed.").put("error", "Bad Request").toString(); + Response response = Response.status(Response.Status.BAD_REQUEST).entity(errorMessage) + .build(); + throw new WebApplicationException(response); + } + } catch (ClientAttestationMgtException e) { + // Create a Response object with a 400 status code and a detailed message + Response response = Response + .status(Response.Status.BAD_REQUEST) + .entity("Invalid Request: " + e.getMessage()) + .build(); + + // Throw a WebApplicationException with the custom response + throw new WebApplicationException(e, response); + } + } } } @@ -176,4 +224,27 @@ private void setContextToRequest(HttpServletRequest request, ClientAttestationCo // Add the Client Attestation context as an attribute to the HttpServletRequest request.setAttribute(CLIENT_ATTESTATION_CONTEXT, clientAttestationContext); } + + private ServiceProvider getServiceProvider(String clientId, String tenantDomain) + throws ClientAttestationMgtException { + + ServiceProvider serviceProvider; + try { + serviceProvider = applicationManagementService.getServiceProviderByClientId(clientId, OAUTH2, tenantDomain); + } catch (IdentityApplicationManagementException e) { + String errorMessage = new JSONObject().put("error_description", "Internal Server Error when " + + "retrieving service provider.").put("error", "server_error").toString(); + Response response = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage) + .build(); + throw new WebApplicationException(response); + } + if (serviceProvider == null) { + String errorMessage = new JSONObject().put("error_description", "Service provider not found.") + .put("error", "Bad Request").toString(); + Response response = Response.status(Response.Status.BAD_REQUEST).entity(errorMessage) + .build(); + throw new WebApplicationException(response); + } + return serviceProvider; + } } diff --git a/components/org.wso2.carbon.identity.oauth.endpoint/src/main/webapp/WEB-INF/cxf-servlet.xml b/components/org.wso2.carbon.identity.oauth.endpoint/src/main/webapp/WEB-INF/cxf-servlet.xml index 7c6da2270b..9900173dcc 100644 --- a/components/org.wso2.carbon.identity.oauth.endpoint/src/main/webapp/WEB-INF/cxf-servlet.xml +++ b/components/org.wso2.carbon.identity.oauth.endpoint/src/main/webapp/WEB-INF/cxf-servlet.xml @@ -52,6 +52,7 @@ + @@ -69,6 +70,7 @@ +