diff --git a/components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/authz/OAuth2AuthzEndpoint.java b/components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/authz/OAuth2AuthzEndpoint.java index f69d6b224a..99dc948576 100644 --- a/components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/authz/OAuth2AuthzEndpoint.java +++ b/components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/authz/OAuth2AuthzEndpoint.java @@ -112,6 +112,7 @@ import org.wso2.carbon.identity.oauth2.scopeservice.ScopeMetadataService; import org.wso2.carbon.identity.oauth2.token.bindings.TokenBinder; import org.wso2.carbon.identity.oauth2.util.OAuth2Util; +import org.wso2.carbon.identity.oauth2.util.RequestUtil; import org.wso2.carbon.identity.oidc.session.OIDCSessionState; import org.wso2.carbon.identity.oidc.session.util.OIDCSessionManagementUtil; import org.wso2.carbon.identity.openidconnect.OIDCConstants; @@ -280,11 +281,15 @@ public Response authorize(@Context HttpServletRequest request, @Context HttpServ // Using a separate try-catch block as this next try block has operations in the final block. try { + request = RequestUtil.buildRequest(request); oAuthMessage = buildOAuthMessage(request, response); } catch (InvalidRequestParentException e) { EndpointUtil.triggerOnAuthzRequestException(e, request); throw e; + } catch (OAuthProblemException e) { + EndpointUtil.triggerOnAuthzRequestException(e, request); + throw new InvalidRequestException(e.getMessage(), OAuth2ErrorCodes.INVALID_REQUEST); } try { @@ -1955,7 +1960,7 @@ private String handleOAuthAuthorizationRequest(OAuthMessage oAuthMessage) setSPAttributeToRequest(oAuthMessage.getRequest(), validationResponse.getApplicationName(), tenantDomain); } - OAuthAuthzRequest oauthRequest = getOAuthAuthzRequest(oAuthMessage.getRequest()); + OAuthAuthzRequest oauthRequest = EndpointUtil.getOAuthAuthzRequest(oAuthMessage.getRequest()); OAuth2Parameters params = new OAuth2Parameters(); String sessionDataKey = UUID.randomUUID().toString(); diff --git a/components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/par/OAuth2ParEndpoint.java b/components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/par/OAuth2ParEndpoint.java index 2fb62ed712..d0a42b4bcf 100644 --- a/components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/par/OAuth2ParEndpoint.java +++ b/components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/par/OAuth2ParEndpoint.java @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, @@ -22,11 +22,13 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.cxf.interceptor.InInterceptors; -import org.apache.oltu.oauth2.common.error.OAuthError; +import org.apache.oltu.oauth2.common.exception.OAuthProblemException; +import org.apache.oltu.oauth2.common.exception.OAuthSystemException; import org.json.JSONObject; import org.wso2.carbon.identity.oauth.client.authn.filter.OAuthClientAuthenticatorProxy; import org.wso2.carbon.identity.oauth.common.OAuth2ErrorCodes; import org.wso2.carbon.identity.oauth.common.OAuthConstants; +import org.wso2.carbon.identity.oauth.common.exception.InvalidOAuthRequestException; import org.wso2.carbon.identity.oauth.endpoint.util.EndpointUtil; import org.wso2.carbon.identity.oauth.par.common.ParConstants; import org.wso2.carbon.identity.oauth.par.exceptions.ParClientException; @@ -51,6 +53,7 @@ import javax.ws.rs.core.Response; import static org.wso2.carbon.identity.oauth.endpoint.util.EndpointUtil.getOAuth2Service; +import static org.wso2.carbon.identity.oauth.endpoint.util.EndpointUtil.validateParams; /** * REST implementation for OAuth2 PAR endpoint. @@ -141,17 +144,12 @@ private Response handleParCoreException(ParCoreException parCoreException) { } private void handleValidation(HttpServletRequest request, MultivaluedMap params) - throws ParClientException { + throws ParCoreException { - OAuth2ClientValidationResponseDTO validationResponse = getOAuth2Service().validateClientInfo(request); - - if (!validationResponse.isValidClient()) { - throw new ParClientException(validationResponse.getErrorCode(), validationResponse.getErrorMsg()); - } - if (isRequestUriProvided(params)) { - throw new ParClientException(OAuth2ErrorCodes.INVALID_REQUEST, - ParConstants.REQUEST_URI_IN_REQUEST_BODY_ERROR); - } + validateInputParameters(request); + validateClient(request, params); + validateRepeatedParams(request, params); + validateAuthzRequest(request); } private boolean isRequestUriProvided(MultivaluedMap params) { @@ -169,6 +167,10 @@ private void checkClientAuthentication(HttpServletRequest request) throws ParCor if (OAuth2ErrorCodes.SERVER_ERROR.equals(oAuthClientAuthnContext.getErrorCode())) { throw new ParCoreException(oAuthClientAuthnContext.getErrorCode(), oAuthClientAuthnContext.getErrorMessage()); + } else if (OAuth2ErrorCodes.INVALID_CLIENT.equals(oAuthClientAuthnContext.getErrorCode())) { + throw new ParClientException(oAuthClientAuthnContext.getErrorCode(), + "A valid OAuth client could not be found for client_id: " + + oAuthClientAuthnContext.getClientId()); } throw new ParClientException(oAuthClientAuthnContext.getErrorCode(), oAuthClientAuthnContext.getErrorMessage()); @@ -191,7 +193,50 @@ private OAuthClientAuthnContext createNewOAuthClientAuthnContext() { OAuthClientAuthnContext oAuthClientAuthnContext = new OAuthClientAuthnContext(); oAuthClientAuthnContext.setAuthenticated(false); oAuthClientAuthnContext.setErrorMessage(PAR_CLIENT_AUTH_ERROR); - oAuthClientAuthnContext.setErrorCode(OAuthError.TokenResponse.INVALID_REQUEST); + oAuthClientAuthnContext.setErrorCode(OAuth2ErrorCodes.INVALID_REQUEST); return oAuthClientAuthnContext; } + + private void validateClient(HttpServletRequest request, MultivaluedMap params) + throws ParClientException { + + OAuth2ClientValidationResponseDTO validationResponse = getOAuth2Service().validateClientInfo(request); + + if (!validationResponse.isValidClient()) { + throw new ParClientException(validationResponse.getErrorCode(), + "Cannot find an application associated with the given consumer key."); + } + if (isRequestUriProvided(params)) { + throw new ParClientException(OAuth2ErrorCodes.INVALID_REQUEST, + ParConstants.REQUEST_URI_IN_REQUEST_BODY_ERROR); + } + } + + private void validateRepeatedParams(HttpServletRequest request, Map> paramMap) + throws ParClientException { + + if (!validateParams(request, paramMap)) { + throw new ParClientException(OAuth2ErrorCodes.INVALID_REQUEST, "Invalid request with repeated parameters."); + } + } + + private void validateAuthzRequest(HttpServletRequest request) throws ParCoreException { + + try { + EndpointUtil.getOAuthAuthzRequest(request); + } catch (OAuthProblemException e) { + throw new ParClientException(e.getError(), e.getDescription()); + } catch (OAuthSystemException e) { + throw new ParCoreException(OAuth2ErrorCodes.SERVER_ERROR, e.getMessage()); + } + } + + private void validateInputParameters(HttpServletRequest request) throws ParClientException { + + try { + getOAuth2Service().validateInputParameters(request); + } catch (InvalidOAuthRequestException e) { + throw new ParClientException(e.getErrorCode(), e.getMessage()); + } + } } diff --git a/components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/util/EndpointUtil.java b/components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/util/EndpointUtil.java index 206af726a4..bbf9204cee 100644 --- a/components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/util/EndpointUtil.java +++ b/components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/util/EndpointUtil.java @@ -31,6 +31,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.http.NameValuePair; import org.apache.http.client.utils.URIBuilder; +import org.apache.oltu.oauth2.as.request.OAuthAuthzRequest; import org.apache.oltu.oauth2.as.response.OAuthASResponse; import org.apache.oltu.oauth2.common.OAuth; import org.apache.oltu.oauth2.common.exception.OAuthProblemException; @@ -93,6 +94,7 @@ import org.wso2.carbon.identity.oauth2.bean.OAuthClientAuthnContext; import org.wso2.carbon.identity.oauth2.bean.Scope; import org.wso2.carbon.identity.oauth2.dto.OAuth2ClientValidationResponseDTO; +import org.wso2.carbon.identity.oauth2.model.CarbonOAuthAuthzRequest; import org.wso2.carbon.identity.oauth2.model.OAuth2Parameters; import org.wso2.carbon.identity.oauth2.model.OAuth2ScopeConsentResponse; import org.wso2.carbon.identity.oauth2.scopeservice.OAuth2Resource; @@ -110,6 +112,8 @@ import java.io.IOException; import java.io.Serializable; import java.io.UnsupportedEncodingException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import java.net.URISyntaxException; import java.net.URLEncoder; import java.util.ArrayList; @@ -167,6 +171,7 @@ public class EndpointUtil { private static IdpManager idpManager; private static final String ALLOW_ADDITIONAL_PARAMS_FROM_ERROR_URL = "OAuth.AllowAdditionalParamsFromErrorUrl"; private static final String IDP_ENTITY_ID = "IdPEntityId"; + private static Class oAuthAuthzRequestClass; public static void setIdpManager(IdpManager idpManager) { @@ -1804,4 +1809,57 @@ public static boolean isExternalConsentPageEnabledForSP(ServiceProvider serviceP public static boolean isConsentPageRedirectParamsAllowed() { return FileBasedConfigurationBuilder.getInstance().isConsentPageRedirectParamsAllowed(); } + + public static OAuthAuthzRequest getOAuthAuthzRequest(HttpServletRequest request) + throws OAuthProblemException, OAuthSystemException { + + OAuthAuthzRequest oAuthAuthzRequest; + + if (isDefaultOAuthAuthzRequestClassConfigured()) { + oAuthAuthzRequest = new CarbonOAuthAuthzRequest(request); + } else { + try { + Class clazz = getOAuthAuthzRequestClass(); + // Validations will be performed when initializing the class instance. + Constructor constructor = clazz.getConstructor(HttpServletRequest.class); + oAuthAuthzRequest = (OAuthAuthzRequest) constructor.newInstance(request); + } catch (InvocationTargetException e) { + // Handle OAuthProblemException & OAuthSystemException thrown from extended class. + if (e.getTargetException() instanceof OAuthProblemException) { + throw (OAuthProblemException) e.getTargetException(); + } else if (e.getTargetException() instanceof OAuthSystemException) { + throw (OAuthSystemException) e.getTargetException(); + } else { + log.warn("Failed to initiate OAuthAuthzRequest from identity.xml. " + + "Hence initiating the default implementation"); + oAuthAuthzRequest = new CarbonOAuthAuthzRequest(request); + } + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | + NoSuchMethodException e) { + log.warn("Failed to initiate OAuthAuthzRequest from identity.xml. " + + "Hence initiating the default implementation"); + oAuthAuthzRequest = new CarbonOAuthAuthzRequest(request); + } + } + return oAuthAuthzRequest; + } + + private static boolean isDefaultOAuthAuthzRequestClassConfigured() { + + String oauthAuthzRequestClassName = OAuthServerConfiguration.getInstance().getOAuthAuthzRequestClassName(); + return OAuthServerConfiguration.DEFAULT_OAUTH_AUTHZ_REQUEST_CLASSNAME.equals(oauthAuthzRequestClassName); + } + + private static Class getOAuthAuthzRequestClass() throws ClassNotFoundException { + + if (oAuthAuthzRequestClass == null) { + + String oauthAuthzRequestClassName = + OAuthServerConfiguration.getInstance().getOAuthAuthzRequestClassName(); + oAuthAuthzRequestClass = (Class) Thread.currentThread() + .getContextClassLoader().loadClass(oauthAuthzRequestClassName); + + } + return oAuthAuthzRequestClass; + } } diff --git a/components/org.wso2.carbon.identity.oauth.par/pom.xml b/components/org.wso2.carbon.identity.oauth.par/pom.xml index b52126558a..eff477561f 100644 --- a/components/org.wso2.carbon.identity.oauth.par/pom.xml +++ b/components/org.wso2.carbon.identity.oauth.par/pom.xml @@ -56,7 +56,10 @@ org.wso2.carbon.identity.inbound.auth.oauth2 org.wso2.carbon.identity.oauth.common - + + org.wso2.carbon.identity.inbound.auth.oauth2 + org.wso2.carbon.identity.oauth + org.wso2.carbon.identity.framework org.wso2.carbon.identity.application.mgt @@ -114,6 +117,7 @@ org.apache.commons.lang; version="${commons-lang.wso2.osgi.version.range}", org.wso2.carbon.identity.oauth.common.*;version="${identity.inbound.auth.oauth.exp.pkg.version}" org.apache.oltu.oauth2.common.*; version="${oltu.package.import.version.range}", + org.wso2.carbon.identity.oauth2.*;version="${identity.inbound.auth.oauth.exp.pkg.version}", org.osgi.framework; version="${osgi.framework.imp.pkg.version.range}", org.osgi.service.component; version="${osgi.service.component.imp.pkg.version.range}", org.wso2.carbon.identity.application.authentication.framework.cache; version="${carbon.identity.framework.imp.pkg.version.range}", diff --git a/components/org.wso2.carbon.identity.oauth.par/src/main/java/org/wso2/carbon/identity/oauth/par/core/ParRequestBuilder.java b/components/org.wso2.carbon.identity.oauth.par/src/main/java/org/wso2/carbon/identity/oauth/par/core/ParRequestBuilder.java new file mode 100644 index 0000000000..1696220ab9 --- /dev/null +++ b/components/org.wso2.carbon.identity.oauth.par/src/main/java/org/wso2/carbon/identity/oauth/par/core/ParRequestBuilder.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (https://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.oauth.par.core; + +import org.apache.commons.lang.StringUtils; +import org.apache.oltu.oauth2.common.exception.OAuthProblemException; +import org.wso2.carbon.identity.oauth.common.OAuthConstants; +import org.wso2.carbon.identity.oauth.par.model.OAuthParRequestWrapper; +import org.wso2.carbon.identity.oauth2.AbstractRequestBuilder; + +import javax.servlet.http.HttpServletRequest; + +/** + * This is a global level interface for building requests. + */ +public class ParRequestBuilder implements AbstractRequestBuilder { + + private static final String REQUEST_BUILDER_NAME = "Pushed authorization request builder"; + + @Override + public HttpServletRequest buildRequest(HttpServletRequest request) throws OAuthProblemException { + + return new OAuthParRequestWrapper(request); + } + + @Override + public boolean canHandle(HttpServletRequest request) { + + return StringUtils.isNotBlank(request.getParameter(OAuthConstants.OAuth20Params.REQUEST_URI)); + } + + @Override + public String getName() { + + return REQUEST_BUILDER_NAME; + } + +} diff --git a/components/org.wso2.carbon.identity.oauth.par/src/main/java/org/wso2/carbon/identity/oauth/par/internal/ParServiceComponent.java b/components/org.wso2.carbon.identity.oauth.par/src/main/java/org/wso2/carbon/identity/oauth/par/internal/ParServiceComponent.java index e1e167ab84..d58800348b 100644 --- a/components/org.wso2.carbon.identity.oauth.par/src/main/java/org/wso2/carbon/identity/oauth/par/internal/ParServiceComponent.java +++ b/components/org.wso2.carbon.identity.oauth.par/src/main/java/org/wso2/carbon/identity/oauth/par/internal/ParServiceComponent.java @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, @@ -15,15 +15,16 @@ * specific language governing permissions and limitations * under the License. */ - package org.wso2.carbon.identity.oauth.par.internal; +import com.hazelcast.org.apache.hc.core5.http.support.AbstractRequestBuilder; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.osgi.service.component.ComponentContext; import org.osgi.service.component.annotations.Component; import org.wso2.carbon.identity.oauth.par.core.ParAuthService; import org.wso2.carbon.identity.oauth.par.core.ParAuthServiceImpl; +import org.wso2.carbon.identity.oauth.par.core.ParRequestBuilder; /** * Service component for PAR. @@ -41,6 +42,8 @@ protected void activate(ComponentContext context) { try { context.getBundleContext().registerService(ParAuthService.class.getName(), new ParAuthServiceImpl(), null); + context.getBundleContext().registerService(AbstractRequestBuilder.class.getName(), + new ParRequestBuilder(), null); log.debug("PAR component bundle is activated."); } catch (Throwable e) { log.error("Error occurred while activating PAR component.", e); diff --git a/components/org.wso2.carbon.identity.oauth.par/src/main/java/org/wso2/carbon/identity/oauth/par/model/OAuthParRequestWrapper.java b/components/org.wso2.carbon.identity.oauth.par/src/main/java/org/wso2/carbon/identity/oauth/par/model/OAuthParRequestWrapper.java index 520190560e..d653d0ee36 100644 --- a/components/org.wso2.carbon.identity.oauth.par/src/main/java/org/wso2/carbon/identity/oauth/par/model/OAuthParRequestWrapper.java +++ b/components/org.wso2.carbon.identity.oauth.par/src/main/java/org/wso2/carbon/identity/oauth/par/model/OAuthParRequestWrapper.java @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, @@ -20,10 +20,10 @@ import org.apache.oltu.oauth2.common.exception.OAuthProblemException; import org.wso2.carbon.identity.oauth.common.OAuthConstants; import org.wso2.carbon.identity.oauth.par.common.ParConstants; -import org.wso2.carbon.identity.oauth.par.core.ParAuthService; import org.wso2.carbon.identity.oauth.par.exceptions.ParAuthFailureException; import org.wso2.carbon.identity.oauth.par.exceptions.ParClientException; import org.wso2.carbon.identity.oauth.par.exceptions.ParCoreException; +import org.wso2.carbon.identity.oauth.par.util.ParUtil; import java.util.Map; @@ -43,27 +43,23 @@ public class OAuthParRequestWrapper extends HttpServletRequestWrapper { * Wraps the request with parameters obtained from the PAR endpoint. * * @param request HttpServletRequest. - * @param parAuthService ParAuthService. * @throws OAuthProblemException OAuthProblemException. */ - public OAuthParRequestWrapper(HttpServletRequest request, ParAuthService parAuthService) + public OAuthParRequestWrapper(HttpServletRequest request) throws OAuthProblemException { super(request); - //get only uuid from request_uri + // Get only uuid from request_uri. String requestUri = request.getParameter(OAuthConstants.OAuth20Params.REQUEST_URI); String uuid = requestUri.replaceFirst(ParConstants.REQUEST_URI_PREFIX, ""); try { - if (parAuthService == null) { - throw new ParAuthFailureException("ParAuthService is not initialized properly"); - } - params = parAuthService.retrieveParams(uuid, - request.getParameter(OAuthConstants.OAuth20Params.CLIENT_ID)); + params = ParUtil.getParAuthService() + .retrieveParams(uuid, request.getParameter(OAuthConstants.OAuth20Params.CLIENT_ID)); params.put(OAuthConstants.ALLOW_REQUEST_URI_AND_REQUEST_OBJECT_IN_REQUEST, "true"); - // set request_uri to empty string to avoid conflicting with OIDC flow + // Set request_uri to empty string to avoid conflicting with OIDC flow. params.put(OAuthConstants.OAuth20Params.REQUEST_URI, ""); } catch (ParClientException e) { throw new ParAuthFailureException(e.getMessage()); diff --git a/components/org.wso2.carbon.identity.oauth.par/src/main/java/org/wso2/carbon/identity/oauth/par/util/ParUtil.java b/components/org.wso2.carbon.identity.oauth.par/src/main/java/org/wso2/carbon/identity/oauth/par/util/ParUtil.java new file mode 100644 index 0000000000..327c7aa8bc --- /dev/null +++ b/components/org.wso2.carbon.identity.oauth.par/src/main/java/org/wso2/carbon/identity/oauth/par/util/ParUtil.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (https://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.oauth.par.util; + +import org.wso2.carbon.identity.oauth.par.core.ParAuthService; +import org.wso2.carbon.identity.oauth.par.core.ParAuthServiceImpl; + +/** + * Util class for PAR. + */ +public class ParUtil { + + private ParUtil() { + // private constructor + } + + private static ParAuthService parAuthService = new ParAuthServiceImpl(); + + /** + * Get instance of parAuthService. + * + * @return Instance of parAuthService. + */ + public static ParAuthService getParAuthService() { + + return parAuthService; + } + + /** + * Set instance of parAuthService. + * + * @param parAuthService Instance of parAuthService. + */ + public static void setParAuthService(ParAuthService parAuthService) { + + ParUtil.parAuthService = parAuthService; + } +} diff --git a/components/org.wso2.carbon.identity.oauth/pom.xml b/components/org.wso2.carbon.identity.oauth/pom.xml index 8961208452..758dcf1496 100644 --- a/components/org.wso2.carbon.identity.oauth/pom.xml +++ b/components/org.wso2.carbon.identity.oauth/pom.xml @@ -142,10 +142,6 @@ org.wso2.carbon.identity.inbound.auth.oauth2 org.wso2.carbon.identity.oauth.common - - org.wso2.carbon.identity.inbound.auth.oauth2 - org.wso2.carbon.identity.oauth.par - org.wso2.carbon.identity.framework org.wso2.carbon.idp.mgt @@ -431,7 +427,6 @@ !org.wso2.carbon.identity.oauth.internal, !org.wso2.carbon.identity.oauth.common.*, - !org.wso2.carbon.identity.oauth.par.*, org.wso2.carbon.identity.oauth.*; version="${identity.inbound.auth.oauth.exp.pkg.version}", org.wso2.carbon.identity.oauth2.*; version="${identity.inbound.auth.oauth.exp.pkg.version}", org.wso2.carbon.identity.openidconnect.*;version="${identity.inbound.auth.oauth.exp.pkg.version}", diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/AbstractRequestBuilder.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/AbstractRequestBuilder.java new file mode 100644 index 0000000000..bbafa93ce6 --- /dev/null +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/AbstractRequestBuilder.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (https://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.oauth2; + +import org.apache.oltu.oauth2.common.exception.OAuthProblemException; + +import javax.servlet.http.HttpServletRequest; + +/** + * This is a global level interface for building requests. + */ +public interface AbstractRequestBuilder { + + /** + * Build the request. + * + * @param request Incoming HttpServletRequest. + * @return Built HttpServletRequest. + * @throws OAuthProblemException OAuthProblemException. + */ + HttpServletRequest buildRequest(HttpServletRequest request) throws OAuthProblemException; + + /** + * Check whether the request builder can handle the incoming request. + * + * @param request Incoming HttpServletRequest. + * @return True if the request builder can handle the request. + */ + boolean canHandle(HttpServletRequest request); + + /** + * Get the friendly name of the implemented request builder. + * + * @return Name of the request builder. + */ + String getName(); + +} diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponent.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponent.java index 62176f4b22..bdc924772b 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponent.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponent.java @@ -47,7 +47,7 @@ import org.wso2.carbon.identity.oauth.config.OAuthServerConfiguration; import org.wso2.carbon.identity.oauth.dto.ScopeDTO; import org.wso2.carbon.identity.oauth.internal.OAuthComponentServiceHolder; -import org.wso2.carbon.identity.oauth.par.core.ParAuthService; +import org.wso2.carbon.identity.oauth2.AbstractRequestBuilder; import org.wso2.carbon.identity.oauth2.OAuth2ScopeService; import org.wso2.carbon.identity.oauth2.OAuth2Service; import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService; @@ -146,21 +146,26 @@ protected void setAuthenticationMethodNameTranslator( } @Reference( - name = "identity.oauth.par.service.component", - service = ParAuthService.class, - cardinality = ReferenceCardinality.MANDATORY, + name = "request.builder.service", + service = AbstractRequestBuilder.class, + cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC, - unbind = "unsetParService" + unbind = "removeRequestBuilderService" ) - protected void setParService(ParAuthService parAuthService) { + protected void addRequestBuilderService(AbstractRequestBuilder abstractRequestBuilder) { - log.debug("Setting ParAuthService Service."); - OAuth2ServiceComponentHolder.setParAuthService(parAuthService); + if (log.isDebugEnabled()) { + log.debug("Adding the Request builder Service : " + abstractRequestBuilder.getName()); + } + OAuth2ServiceComponentHolder.getInstance().addRequestBuilder(abstractRequestBuilder); } - protected void unsetParService(ParAuthService parAuthService) { + protected void removeRequestBuilderService(AbstractRequestBuilder abstractRequestBuilder) { - OAuth2ServiceComponentHolder.setParAuthService(null); + if (log.isDebugEnabled()) { + log.debug("Removing the Request builder Service : " + abstractRequestBuilder.getName()); + } + OAuth2ServiceComponentHolder.getInstance().removeRequestBuilder(abstractRequestBuilder); } protected void unsetAuthenticationMethodNameTranslator( diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponentHolder.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponentHolder.java index 400597bad2..08da0ab977 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponentHolder.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/internal/OAuth2ServiceComponentHolder.java @@ -28,7 +28,7 @@ import org.wso2.carbon.identity.event.services.IdentityEventService; import org.wso2.carbon.identity.oauth.OAuthAdminServiceImpl; import org.wso2.carbon.identity.oauth.dto.ScopeDTO; -import org.wso2.carbon.identity.oauth.par.core.ParAuthService; +import org.wso2.carbon.identity.oauth2.AbstractRequestBuilder; import org.wso2.carbon.identity.oauth2.authz.validators.ResponseTypeRequestValidator; import org.wso2.carbon.identity.oauth2.bean.Scope; import org.wso2.carbon.identity.oauth2.client.authentication.OAuthClientAuthenticator; @@ -61,7 +61,6 @@ public class OAuth2ServiceComponentHolder { private static OAuth2ServiceComponentHolder instance = new OAuth2ServiceComponentHolder(); private static ApplicationManagementService applicationMgtService; - private static ParAuthService parAuthService; private static boolean pkceEnabled = false; private static boolean audienceEnabled = false; private static RegistryService registryService; @@ -94,6 +93,7 @@ public class OAuth2ServiceComponentHolder { private static boolean restrictUnassignedScopes; private static ConfigurationContextService configurationContextService; private List jwtAccessTokenClaimProviders = new ArrayList<>(); + private final List abstractRequestBuilders = new ArrayList<>(); private boolean isOrganizationManagementEnabled = false; private OAuth2ServiceComponentHolder() { @@ -125,26 +125,6 @@ public static void setApplicationMgtService(ApplicationManagementService applica OAuth2ServiceComponentHolder.applicationMgtService = applicationMgtService; } - /** - * Get ParAuth service. - * - * @return Instance of ParAuthService. - */ - public static ParAuthService getParAuthService() { - - return parAuthService; - } - - /** - * Set parAuth service. - * - * @param parAuthService Instance of ParAuthService. - */ - public static void setParAuthService(ParAuthService parAuthService) { - - OAuth2ServiceComponentHolder.parAuthService = parAuthService; - } - @Deprecated public static boolean isPkceEnabled() { @@ -650,4 +630,34 @@ public static ResponseModeProvider getResponseModeProvider(String responseMode) } return responseModeProvider; } + + /** + * Get the list of request builder implementations available. + * + * @return List returns a list ot request builders. + */ + public List getRequestBuilders() { + + return abstractRequestBuilders; + } + + /** + * Add request builder implementation. + * + * @param abstractRequestBuilder Request builder implementation. + */ + public void addRequestBuilder(AbstractRequestBuilder abstractRequestBuilder) { + + abstractRequestBuilders.add(abstractRequestBuilder); + } + + /** + * Remove request builder implementation. + * + * @param abstractRequestBuilder Request builder implementation. + */ + public void removeRequestBuilder(AbstractRequestBuilder abstractRequestBuilder) { + + abstractRequestBuilders.remove(abstractRequestBuilder); + } } diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/model/CarbonOAuthAuthzRequest.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/model/CarbonOAuthAuthzRequest.java index 643c47c33e..5606abd326 100644 --- a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/model/CarbonOAuthAuthzRequest.java +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/model/CarbonOAuthAuthzRequest.java @@ -29,8 +29,6 @@ import org.wso2.carbon.identity.central.log.mgt.utils.LoggerUtils; import org.wso2.carbon.identity.oauth.common.OAuthConstants; import org.wso2.carbon.identity.oauth.config.OAuthServerConfiguration; -import org.wso2.carbon.identity.oauth.par.model.OAuthParRequestWrapper; -import org.wso2.carbon.identity.oauth2.internal.OAuth2ServiceComponentHolder; import java.util.HashMap; import java.util.Map; @@ -48,22 +46,7 @@ public class CarbonOAuthAuthzRequest extends OAuthAuthzRequest { public CarbonOAuthAuthzRequest(HttpServletRequest request) throws OAuthSystemException, OAuthProblemException { - super(buildRequest(request)); - } - - /* - If request_uri parameter is present in the parameter map, consider request as a PAR request and - use OAuthParRequestWrapper to make the request's parameter map contain the parameter map obtained from - the PAR endpoint as parameters such as response_type are only provided in the PAR request, - but are needed in the Authorization request for validations. - */ - private static HttpServletRequest buildRequest(HttpServletRequest request) throws OAuthProblemException { - - // If request_uri is there consider as par request. - if (request.getParameter(OAuthConstants.OAuth20Params.REQUEST_URI) != null) { - return new OAuthParRequestWrapper(request, OAuth2ServiceComponentHolder.getParAuthService()); - } - return request; + super(request); } protected OAuthValidator initValidator() throws OAuthProblemException, OAuthSystemException { diff --git a/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/RequestUtil.java b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/RequestUtil.java new file mode 100644 index 0000000000..8b99708058 --- /dev/null +++ b/components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/util/RequestUtil.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (https://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.oauth2.util; + +import org.apache.oltu.oauth2.common.exception.OAuthProblemException; +import org.wso2.carbon.identity.oauth2.AbstractRequestBuilder; +import org.wso2.carbon.identity.oauth2.internal.OAuth2ServiceComponentHolder; + +import java.util.List; + +import javax.servlet.http.HttpServletRequest; + +/** + * This is a util class for building the request. + */ +public class RequestUtil { + + /** + * This method builds the request according to the type which can handle it. + * + * @param request Incoming HttpServletRequest. + * @return Built HttpServletRequest instance. + * @throws OAuthProblemException OAuthProblemException. + */ + public static HttpServletRequest buildRequest(HttpServletRequest request) throws OAuthProblemException { + + List abstractRequestBuilders = + OAuth2ServiceComponentHolder.getInstance().getRequestBuilders(); + AbstractRequestBuilder requestBuilder; + + for (AbstractRequestBuilder abstractRequestBuilder : abstractRequestBuilders) { + requestBuilder = abstractRequestBuilder; + if (requestBuilder.canHandle(request)) { + return requestBuilder.buildRequest(request); + } + } + + return request; + } + + private RequestUtil() { + + } + +}