diff --git a/modules/integration/tests-integration/tests-backend/pom.xml b/modules/integration/tests-integration/tests-backend/pom.xml
index 08f1be8d61e..6d184e0493c 100644
--- a/modules/integration/tests-integration/tests-backend/pom.xml
+++ b/modules/integration/tests-integration/tests-backend/pom.xml
@@ -98,6 +98,12 @@
usedefaultlisteners
false
+
+ registration.requests.location
+
+ ${basedir}/src/test/resources/registration-requests/
+
+
${basedir}/target/security-verifier/
${basedir}/target/emma
${basedir}/src/test/resources/instrumentation.txt
diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/oauth2/dcrm/api/FAPIDCRValidationsTestCase.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/oauth2/dcrm/api/FAPIDCRValidationsTestCase.java
new file mode 100644
index 00000000000..75bc1e558e9
--- /dev/null
+++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/oauth2/dcrm/api/FAPIDCRValidationsTestCase.java
@@ -0,0 +1,194 @@
+/**
+ * Copyright (c) 2024, 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.identity.integration.test.oauth2.dcrm.api;
+
+import org.apache.http.HttpHeaders;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.HttpClients;
+import org.json.simple.JSONObject;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Factory;
+import org.testng.annotations.Test;
+import org.wso2.carbon.automation.engine.context.AutomationContext;
+import org.wso2.carbon.automation.engine.context.TestUserMode;
+import org.wso2.carbon.integration.common.utils.mgt.ServerConfigurationManager;
+import org.wso2.identity.integration.common.utils.ISIntegrationTest;
+import org.wso2.identity.integration.test.oauth2.dcrm.api.util.DCRUtils;
+import org.wso2.identity.integration.test.oauth2.dcrm.api.util.OAuthDCRMConstants;
+import org.wso2.identity.integration.test.util.Utils;
+
+import java.io.File;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+/**
+ * FAPI validation test case for the DCR flow
+ */
+public class FAPIDCRValidationsTestCase extends ISIntegrationTest {
+
+ private HttpClient client;
+ private String client_id;
+ private String username;
+ private String password;
+ private String tenant;
+ private ServerConfigurationManager serverConfigurationManager;
+
+ @Factory(dataProvider = "dcrmConfigProvider")
+ public FAPIDCRValidationsTestCase(TestUserMode userMode) throws Exception {
+
+ AutomationContext context = new AutomationContext("IDENTITY", userMode);
+ this.username = context.getContextTenant().getTenantAdmin().getUserName();
+ this.password = context.getContextTenant().getTenantAdmin().getPassword();
+ this.tenant = context.getContextTenant().getDomain();
+
+ }
+
+ @DataProvider(name = "dcrmConfigProvider")
+ public static Object[][] dcrmConfigProvider() {
+
+ return new Object[][]{{TestUserMode.SUPER_TENANT_ADMIN}, {TestUserMode.TENANT_ADMIN}};
+ }
+
+ @BeforeClass(alwaysRun = true)
+ public void testInit() throws Exception {
+
+ super.init();
+ client = HttpClients.createDefault();
+ changeISConfiguration();
+ }
+
+ @DataProvider(name = "dcrConfigProvider")
+ private static Object[][] dcrConfigProvider() throws Exception {
+
+ String INVALID_CLIENT_METADATA = "invalid_client_metadata";
+ String INVALID_SOFTWARE_STATEMENT = "invalid_software_statement";
+ return new Object[][]{
+ {
+ DCRUtils.getRegisterRequestJSON("request1.json"), INVALID_CLIENT_METADATA,
+ "Invalid token endpoint authentication method requested."
+ },
+ {
+ DCRUtils.getRegisterRequestJSON("request2.json"), INVALID_CLIENT_METADATA,
+ "Invalid signature algorithm requested"
+ },
+ {
+ DCRUtils.getRegisterRequestJSON("request3.json"), INVALID_CLIENT_METADATA,
+ "Invalid encryption algorithm requested"
+ },
+ {
+ DCRUtils.getRegisterRequestJSON("request4.json"), INVALID_CLIENT_METADATA,
+ "Sector Identifier URI is mandatory if multiple redirect URIs with different" +
+ "hostnames are configured."
+ },
+ {
+ DCRUtils.getRegisterRequestJSON("request5.json"), INVALID_CLIENT_METADATA,
+ "Redirect URI missing in sector identifier URI set"
+ },
+ {
+ DCRUtils.getRegisterRequestJSON("request8.json"), INVALID_SOFTWARE_STATEMENT,
+ "Signature validation failed for the software statement"
+ }
+ };
+ }
+
+ private void changeISConfiguration() throws Exception {
+
+ log.info("Adding entity id of SSOService to deployment.toml file");
+ String carbonHome = Utils.getResidentCarbonHome();
+ File defaultConfigFile = getDeploymentTomlFile(carbonHome);
+ File configuredIdentityXML = new File(getISResourceLocation() + File.separator + "oauth"
+ + File.separator + "dcr-fapi-validation-enabled.toml");
+ serverConfigurationManager = new ServerConfigurationManager(isServer);
+ serverConfigurationManager.applyConfigurationWithoutRestart(configuredIdentityXML,
+ defaultConfigFile, true);
+ serverConfigurationManager.restartGracefully();
+ }
+
+ @Test(alwaysRun = true, groups = "wso2.is", priority = 1,
+ description = "Check FAPI validations, PPID and SSA during DCR", dataProvider = "dcrConfigProvider")
+ public void validateErrorScenarios(JSONObject requestJSON, String errorCode, String errorMessage) throws Exception {
+
+ HttpPost request = new HttpPost(getTenantQualifiedURL(OAuthDCRMConstants.DCR_ENDPOINT_HOST_PART , tenant));
+ request.addHeader(HttpHeaders.AUTHORIZATION, DCRUtils.getAuthzHeader(username, password));
+ request.addHeader(HttpHeaders.CONTENT_TYPE, OAuthDCRMConstants.CONTENT_TYPE);
+ StringEntity entity = new StringEntity(requestJSON.toJSONString());
+ request.setEntity(entity);
+ HttpResponse response = client.execute(request);
+
+ assertEquals(response.getStatusLine().getStatusCode(), 400, "Service Provider " +
+ "should not be created successfully");
+ JSONObject errorResponse = DCRUtils.getPayload(response);
+ assertEquals(errorResponse.get("error"), errorCode);
+ assertEquals(errorResponse.get("error_description"), errorMessage);
+ }
+
+ @Test(alwaysRun = true, groups = "wso2.is", priority = 2,
+ description = "Check FAPI validations, PPID and SSA during DCR", dataProvider = "dcrConfigProvider")
+ public void validateErrorScenariosForDCRUpdate(JSONObject requestJSON, String errorCode, String errorMessage)
+ throws Exception {
+
+ // Create application.
+ HttpPost request = new HttpPost(getTenantQualifiedURL(OAuthDCRMConstants.DCR_ENDPOINT_HOST_PART , tenant));
+ JSONObject registerRequestJSON = DCRUtils.getRegisterRequestJSON("request6.json");
+ // Removing sending sector identifier uri to validate error message during update request.
+ if (errorMessage.equals("Sector identifier URI is needed for PPID calculation")) {
+ registerRequestJSON.remove("sector_identifier_uri");
+ }
+ request.addHeader(HttpHeaders.AUTHORIZATION, DCRUtils.getAuthzHeader(username, password));
+ request.addHeader(HttpHeaders.CONTENT_TYPE, OAuthDCRMConstants.CONTENT_TYPE);
+ StringEntity entity = new StringEntity(registerRequestJSON.toJSONString());
+ request.setEntity(entity);
+
+ HttpResponse response = client.execute(request);
+ assertEquals(response.getStatusLine().getStatusCode(), 201, "Service Provider " +
+ "created successfully");
+ JSONObject createResponsePayload = DCRUtils.getPayload(response);
+ client_id = ((JSONObject) createResponsePayload).get("client_id").toString();
+ assertNotNull(client_id, "client_id cannot be null");
+
+ // Check error scenarios for update request.
+ HttpPut updateRequest = new HttpPut(getTenantQualifiedURL(OAuthDCRMConstants.DCR_ENDPOINT_HOST_PART ,
+ tenant) + client_id);
+ updateRequest.addHeader(HttpHeaders.AUTHORIZATION, DCRUtils.getAuthzHeader(username, password));
+ updateRequest.addHeader(HttpHeaders.CONTENT_TYPE, OAuthDCRMConstants.CONTENT_TYPE);
+ entity = new StringEntity(requestJSON.toJSONString());
+ updateRequest.setEntity(entity);
+
+ HttpResponse updateResponse = client.execute(updateRequest);
+ assertEquals(updateResponse.getStatusLine().getStatusCode(), 400, "Service Provider should " +
+ "not be created successfully");
+ JSONObject errorResponse = DCRUtils.getPayload(updateResponse);
+ assertEquals(errorResponse.get("error"), errorCode);
+ assertEquals(errorResponse.get("error_description"), errorMessage);
+
+ // Delete application.
+ HttpDelete deleteRequest = new HttpDelete(getTenantQualifiedURL(OAuthDCRMConstants.DCR_ENDPOINT_HOST_PART ,
+ tenant) + client_id);
+ deleteRequest.addHeader(HttpHeaders.AUTHORIZATION, DCRUtils.getAuthzHeader(username, password));
+ HttpResponse deleteResponse = client.execute(deleteRequest);
+ assertEquals(deleteResponse.getStatusLine().getStatusCode(), 204, "Service provider " +
+ "deletion failed");
+ }
+}
diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/oauth2/dcrm/api/OAuthDCRMTestCase.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/oauth2/dcrm/api/OAuthDCRMTestCase.java
index 99e0bfa0a3d..e95318d1672 100644
--- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/oauth2/dcrm/api/OAuthDCRMTestCase.java
+++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/oauth2/dcrm/api/OAuthDCRMTestCase.java
@@ -17,20 +17,20 @@
*/
package org.wso2.identity.integration.test.oauth2.dcrm.api;
-import org.apache.commons.codec.binary.Base64;
+import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
-import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Factory;
@@ -38,6 +38,7 @@
import org.wso2.carbon.automation.engine.context.AutomationContext;
import org.wso2.carbon.automation.engine.context.TestUserMode;
import org.wso2.identity.integration.common.utils.ISIntegrationTest;
+import org.wso2.identity.integration.test.oauth2.dcrm.api.util.DCRUtils;
import org.wso2.identity.integration.test.oauth2.dcrm.api.util.OAuthDCRMConstants;
import java.io.BufferedReader;
@@ -46,7 +47,6 @@
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
/**
* OAuth2 DCRM API Create process test case
@@ -79,13 +79,12 @@ public static Object[][] dcrmConfigProvider() {
public void testInit() throws Exception {
super.init();
client = HttpClients.createDefault();
-
}
-
@Test(alwaysRun = true, groups = "wso2.is", priority = 1, description = "Create a service provider successfully")
public void testCreateServiceProviderRequest() throws IOException {
- HttpPost request = new HttpPost(getPath());
- request.addHeader(HttpHeaders.AUTHORIZATION, getAuthzHeader());
+
+ HttpPost request = new HttpPost(getTenantQualifiedURL(OAuthDCRMConstants.DCR_ENDPOINT_HOST_PART , tenant));
+ request.addHeader(HttpHeaders.AUTHORIZATION, DCRUtils.getAuthzHeader(username, password));
request.addHeader(HttpHeaders.CONTENT_TYPE, OAuthDCRMConstants.CONTENT_TYPE);
JSONArray grantTypes = new JSONArray();
@@ -121,8 +120,9 @@ public void testCreateServiceProviderRequest() throws IOException {
@Test(alwaysRun = true, groups = "wso2.is", priority = 2, description =
"Create a service provider with already registered client name")
public void testCreateServiceProviderRequestWithExistingClientName() throws IOException {
- HttpPost request = new HttpPost(getPath());
- request.addHeader(HttpHeaders.AUTHORIZATION, getAuthzHeader());
+
+ HttpPost request = new HttpPost(getTenantQualifiedURL(OAuthDCRMConstants.DCR_ENDPOINT_HOST_PART , tenant));
+ request.addHeader(HttpHeaders.AUTHORIZATION, DCRUtils.getAuthzHeader(username, password));
request.addHeader(HttpHeaders.CONTENT_TYPE, OAuthDCRMConstants.CONTENT_TYPE);
JSONArray grantTypes = new JSONArray();
@@ -157,8 +157,8 @@ public void testCreateServiceProviderRequestWithExistingClientName() throws IOEx
@Test(alwaysRun = true, groups = "wso2.is", priority = 3, description = "Read service provider")
public void testReadServiceProvider() throws IOException {
- HttpGet request = new HttpGet(getPath() + client_id);
- request.addHeader(HttpHeaders.AUTHORIZATION, getAuthzHeader());
+ HttpGet request = new HttpGet(getTenantQualifiedURL(OAuthDCRMConstants.DCR_ENDPOINT_HOST_PART , tenant)+ client_id);
+ request.addHeader(HttpHeaders.AUTHORIZATION, DCRUtils.getAuthzHeader(username, password));
request.addHeader(HttpHeaders.CONTENT_TYPE, OAuthDCRMConstants.CONTENT_TYPE);
HttpResponse response = client.execute(request);
@@ -175,8 +175,9 @@ public void testReadServiceProvider() throws IOException {
@Test(alwaysRun = true, groups = "wso2.is", priority = 4, description = "Read request with an invalid client ID")
public void testReadServiceProviderWithInvalidClientID() throws IOException {
- HttpGet request = new HttpGet(getPath() + OAuthDCRMConstants.INVALID_CLIENT_ID);
- request.addHeader(HttpHeaders.AUTHORIZATION, getAuthzHeader());
+
+ HttpGet request = new HttpGet(getTenantQualifiedURL(OAuthDCRMConstants.DCR_ENDPOINT_HOST_PART , tenant) + OAuthDCRMConstants.INVALID_CLIENT_ID);
+ request.addHeader(HttpHeaders.AUTHORIZATION, DCRUtils.getAuthzHeader(username, password));
request.addHeader(HttpHeaders.CONTENT_TYPE, OAuthDCRMConstants.CONTENT_TYPE);
HttpResponse response = client.execute(request);
@@ -188,8 +189,9 @@ public void testReadServiceProviderWithInvalidClientID() throws IOException {
@Test(alwaysRun = true, groups = "wso2.is", priority = 5, description = "Delete Service Provider")
public void testDeleteServiceProvider() throws IOException {
- HttpDelete request = new HttpDelete(getPath() + client_id);
- request.addHeader(HttpHeaders.AUTHORIZATION, getAuthzHeader());
+ HttpDelete request = new HttpDelete(getTenantQualifiedURL(OAuthDCRMConstants.DCR_ENDPOINT_HOST_PART ,
+ tenant) + client_id);
+ request.addHeader(HttpHeaders.AUTHORIZATION, DCRUtils.getAuthzHeader(username, password));
HttpResponse response = client.execute(request);
assertEquals(response.getStatusLine().getStatusCode(), 204, "Service provider has not " +
@@ -197,8 +199,9 @@ public void testDeleteServiceProvider() throws IOException {
EntityUtils.consume(response.getEntity());
- HttpGet getRequest = new HttpGet(getPath() + client_id);
- getRequest.addHeader(HttpHeaders.AUTHORIZATION, getAuthzHeader());
+ HttpGet getRequest = new HttpGet(getTenantQualifiedURL(OAuthDCRMConstants.DCR_ENDPOINT_HOST_PART , tenant)
+ + client_id);
+ getRequest.addHeader(HttpHeaders.AUTHORIZATION, DCRUtils.getAuthzHeader(username, password));
getRequest.addHeader(HttpHeaders.CONTENT_TYPE, OAuthDCRMConstants.CONTENT_TYPE);
response = client.execute(request);
@@ -212,8 +215,10 @@ public void testDeleteServiceProvider() throws IOException {
@Test(alwaysRun = true, groups = "wso2.is", priority = 6, description = "Delete service provider request with " +
"invalid client id")
public void testDeleteRequestWithInvalidClientID() throws IOException {
- HttpDelete request = new HttpDelete(getPath() + OAuthDCRMConstants.INVALID_CLIENT_ID);
- request.addHeader(HttpHeaders.AUTHORIZATION, getAuthzHeader());
+
+ HttpDelete request = new HttpDelete(getTenantQualifiedURL(OAuthDCRMConstants.DCR_ENDPOINT_HOST_PART ,
+ tenant) + OAuthDCRMConstants.INVALID_CLIENT_ID);
+ request.addHeader(HttpHeaders.AUTHORIZATION, DCRUtils.getAuthzHeader(username, password));
HttpResponse response = client.execute(request);
assertEquals(response.getStatusLine().getStatusCode(), 401, "Service Provider delete request " +
@@ -225,8 +230,9 @@ public void testDeleteRequestWithInvalidClientID() throws IOException {
@Test(alwaysRun = true, groups = "wso2.is", description = "Try to register an OAuth app with authorization_code " +
"grant without any redirect uris.", priority = 7)
public void testRegisterAppWithAuthzCodeGrantAndNoRedirectUris() throws IOException {
- HttpPost request = new HttpPost(getPath());
- setRequestHeaders(request);
+
+ HttpPost request = new HttpPost(getTenantQualifiedURL(OAuthDCRMConstants.DCR_ENDPOINT_HOST_PART , tenant));
+ DCRUtils.setRequestHeaders(request, username, password);
JSONArray grantTypes = new JSONArray();
grantTypes.add(OAuthDCRMConstants.GRANT_TYPE_AUTHORIZATION_CODE);
@@ -249,6 +255,7 @@ public void testRegisterAppWithAuthzCodeGrantAndNoRedirectUris() throws IOExcept
@Test(alwaysRun = true, groups = "wso2.is", priority = 8, description = "Check whether created service providers " +
"are cleaned up when OAuth app creation fails.")
public void testRollbackOnInvalidRequest() throws IOException {
+
// Basic Request
JSONArray grantTypes = new JSONArray();
grantTypes.add(OAuthDCRMConstants.GRANT_TYPE_AUTHORIZATION_CODE);
@@ -258,8 +265,9 @@ public void testRollbackOnInvalidRequest() throws IOException {
requestBody.put(OAuthDCRMConstants.GRANT_TYPES, grantTypes);
//////////////////////// BAD REQUEST WITH EMPTY REDIRECT URI ///////////////////////////
- HttpPost badRequestWithoutRedirectUris = new HttpPost(getPath());
- setRequestHeaders(badRequestWithoutRedirectUris);
+ HttpPost badRequestWithoutRedirectUris = new HttpPost(getTenantQualifiedURL(
+ OAuthDCRMConstants.DCR_ENDPOINT_HOST_PART , tenant));
+ DCRUtils.setRequestHeaders(badRequestWithoutRedirectUris, username, password);
// We keep the redirect uris empty to make this a bad request.
JSONObject badRequestBody = (JSONObject) requestBody.clone();
badRequestBody.put(OAuthDCRMConstants.REDIRECT_URIS, new JSONArray());
@@ -272,8 +280,8 @@ public void testRollbackOnInvalidRequest() throws IOException {
EntityUtils.consume(failedResponse.getEntity());
///////////////// VALID REQUEST WITH THE SAME CLIENT_NAME ///////////////////////////
- HttpPost validRequest = new HttpPost(getPath());
- setRequestHeaders(validRequest);
+ HttpPost validRequest = new HttpPost(getTenantQualifiedURL(OAuthDCRMConstants.DCR_ENDPOINT_HOST_PART , tenant));
+ DCRUtils.setRequestHeaders(validRequest, username, password);
JSONArray redirectURIs = new JSONArray();
redirectURIs.add(OAuthDCRMConstants.REDIRECT_URI);
@@ -283,8 +291,9 @@ public void testRollbackOnInvalidRequest() throws IOException {
validRequest.setEntity(new StringEntity(validJSONBody.toJSONString()));
HttpResponse successResponse = client.execute(validRequest);
- assertEquals(successResponse.getStatusLine().getStatusCode(), 201, "Service Provider should have been created " +
- "with the same client name: " + DUMMY_DCR_APP + " attempted in the previous failed request.");
+ assertEquals(successResponse.getStatusLine().getStatusCode(), 201,
+ "Service Provider should have been created with the same client name: " + DUMMY_DCR_APP +
+ " attempted in the previous failed request.");
BufferedReader rd = new BufferedReader(new InputStreamReader(successResponse.getEntity().getContent()));
Object responseObj = JSONValue.parse(rd);
@@ -295,23 +304,70 @@ public void testRollbackOnInvalidRequest() throws IOException {
// Deleting created application.
testDeleteServiceProvider();
}
+ @Test(alwaysRun = true, groups = "wso2.is", priority = 9, description = "Create a service provider with " +
+ "additional OIDC properties")
+ public void testCreateServiceProviderRequestWithAdditionalParameters() throws Exception {
+
+ HttpPost request = new HttpPost(getTenantQualifiedURL(OAuthDCRMConstants.DCR_ENDPOINT_HOST_PART , tenant));
+ JSONObject registerRequestJSON = DCRUtils.getRegisterRequestJSON("request6.json");
- private void setRequestHeaders(HttpPost request) {
- request.addHeader(HttpHeaders.AUTHORIZATION, getAuthzHeader());
+ request.addHeader(HttpHeaders.AUTHORIZATION, DCRUtils.getAuthzHeader(username, password));
request.addHeader(HttpHeaders.CONTENT_TYPE, OAuthDCRMConstants.CONTENT_TYPE);
- }
+ StringEntity entity = new StringEntity(registerRequestJSON.toJSONString());
+ request.setEntity(entity);
+ ObjectMapper mapper = new ObjectMapper();
+
+ HttpResponse response = client.execute(request);
+ assertEquals(response.getStatusLine().getStatusCode(), 201, "Service Provider " +
+ "has not been created successfully");
+ JSONObject createResponsePayload = DCRUtils.getPayload(response);
+ client_id = ((JSONObject) createResponsePayload).get("client_id").toString();
+ assertNotNull(client_id, "client_id cannot be null");
- private String getPath() {
- if (tenant.equals("carbon.super")) {
- return OAuthDCRMConstants.DCR_ENDPOINT_HOST_PART + OAuthDCRMConstants.DCR_ENDPOINT_PATH_PART;
- } else {
- return OAuthDCRMConstants.DCR_ENDPOINT_HOST_PART + "/t/" + tenant + OAuthDCRMConstants
- .DCR_ENDPOINT_PATH_PART;
- }
- }
- private String getAuthzHeader() {
- return "Basic " + Base64.encodeBase64String((username + ":" + password).getBytes()).trim();
+ HttpGet getRequest = new HttpGet(getTenantQualifiedURL(OAuthDCRMConstants.DCR_ENDPOINT_HOST_PART , tenant)
+ + client_id);
+ getRequest.addHeader(HttpHeaders.AUTHORIZATION, DCRUtils.getAuthzHeader(username, password));
+ getRequest.addHeader(HttpHeaders.CONTENT_TYPE, OAuthDCRMConstants.CONTENT_TYPE);
+
+ HttpResponse getResponse = client.execute(getRequest);
+ assertEquals(getResponse.getStatusLine().getStatusCode(), 200, "Service provider request " +
+ "has not returned with successful response");
}
+ @Test(alwaysRun = true, groups = "wso2.is", priority = 10, description = "Create a service provider with " +
+ "additional OIDC properties")
+ public void testUpdateServiceProviderRequestWithAdditionalParameters() throws Exception {
+
+ HttpPut request = new HttpPut(getTenantQualifiedURL(OAuthDCRMConstants.DCR_ENDPOINT_HOST_PART , tenant)
+ + client_id);
+ request.addHeader(HttpHeaders.AUTHORIZATION, DCRUtils.getAuthzHeader(username, password));
+ request.addHeader(HttpHeaders.CONTENT_TYPE, OAuthDCRMConstants.CONTENT_TYPE);
+ JSONObject updateRequestPayload = DCRUtils.getRegisterRequestJSON("request7.json");
+
+ StringEntity entity = new StringEntity(updateRequestPayload.toJSONString());
+ request.setEntity(entity);
+ ObjectMapper mapper = new ObjectMapper();
+
+ HttpResponse response = client.execute(request);
+ assertEquals(response.getStatusLine().getStatusCode(), 200, "Service Provider " +
+ "has not been created successfully");
+ JSONObject updateResponsePayload = DCRUtils.getPayload(response);
+ client_id = ((JSONObject) updateResponsePayload).get("client_id").toString();
+ assertNotNull(client_id, "client_id cannot be null");
+
+ // Verify that updated attribute is correctly returned by retrieving data.
+ HttpGet getRequest = new HttpGet(getTenantQualifiedURL(OAuthDCRMConstants.DCR_ENDPOINT_HOST_PART , tenant)
+ + client_id);
+ getRequest.addHeader(HttpHeaders.AUTHORIZATION, DCRUtils.getAuthzHeader(username, password));
+ getRequest.addHeader(HttpHeaders.CONTENT_TYPE, OAuthDCRMConstants.CONTENT_TYPE);
+
+ HttpResponse getResponse = client.execute(getRequest);
+ assertEquals(getResponse.getStatusLine().getStatusCode(), 200, "Service provider request " +
+ "has not returned with successful response");
+ JSONObject getResponsePayload = DCRUtils.getPayload(getResponse);
+ assertEquals(getResponsePayload.get("token_endpoint_auth_method"), "tls_client_auth");
+
+ testDeleteServiceProvider();
+ }
}
diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/oauth2/dcrm/api/util/DCRUtils.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/oauth2/dcrm/api/util/DCRUtils.java
new file mode 100644
index 00000000000..4c0c88f3c27
--- /dev/null
+++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/oauth2/dcrm/api/util/DCRUtils.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com) All Rights Reserved.
+ *
+ * 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.identity.integration.test.oauth2.dcrm.api.util;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.http.HttpHeaders;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.util.EntityUtils;
+import org.json.simple.JSONObject;
+import org.json.simple.JSONValue;
+import org.json.simple.parser.JSONParser;
+import org.wso2.identity.integration.test.utils.OAuth2Constant;
+
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+/**
+ * Utils for preparing DCR payloads
+ */
+public class DCRUtils {
+
+ private static JSONParser parser = new JSONParser();
+ private static final String REGISTER_REQUESTS_LOCATION = "registration.requests.location";
+
+ /**
+ * Get register request JSON object.
+ *
+ * @param fileName File name.
+ * @return Register request JSON object.
+ * @throws Exception Exception.
+ */
+ public static JSONObject getRegisterRequestJSON(String fileName) throws Exception {
+
+ return (JSONObject) parser.parse(new FileReader(getFilePath(REGISTER_REQUESTS_LOCATION, fileName)));
+ }
+
+ /**
+ * Get file path.
+ *
+ * @param folderPath Folder path.
+ * @param fileName File name.
+ * @return File path.
+ * @throws Exception Exception.
+ */
+ public static String getFilePath(String folderPath, String fileName) throws Exception {
+
+ Path path = Paths.get(System.getProperty(folderPath) + fileName);
+ if (!Files.exists(path)) {
+ throw new FileNotFoundException("Failed to find file: " + path.toString());
+ }
+ return path.toString();
+ }
+
+ public static void setRequestHeaders(HttpPost request, String username, String password) {
+
+ request.addHeader(HttpHeaders.AUTHORIZATION, getAuthzHeader(username, password));
+ request.addHeader(HttpHeaders.CONTENT_TYPE, OAuthDCRMConstants.CONTENT_TYPE);
+ }
+
+ public static String getAuthzHeader(String username, String password) {
+
+ return OAuth2Constant.BASIC_HEADER + Base64.encodeBase64String((username + ":" + password).getBytes()).trim();
+ }
+
+ public static JSONObject getPayload(HttpResponse response) throws IOException {
+
+ BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
+ Object responseObj = JSONValue.parse(rd);
+ EntityUtils.consume(response.getEntity());
+ return (JSONObject) responseObj;
+ }
+}
diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/oauth2/dcrm/api/util/OAuthDCRMConstants.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/oauth2/dcrm/api/util/OAuthDCRMConstants.java
index 2ad8fcbb834..7a7ea8f4b4a 100644
--- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/oauth2/dcrm/api/util/OAuthDCRMConstants.java
+++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/oauth2/dcrm/api/util/OAuthDCRMConstants.java
@@ -18,7 +18,7 @@
package org.wso2.identity.integration.test.oauth2.dcrm.api.util;
public class OAuthDCRMConstants {
- public static final String DCR_ENDPOINT_HOST_PART = "https://localhost:9853";
+ public static final String DCR_ENDPOINT_HOST_PART = "https://localhost:9853/api/identity/oauth2/dcr/v1.1/register/";
public static final String DCR_ENDPOINT_PATH_PART = "/api/identity/oauth2/dcr/v1.1/register/";
public static final String CLIENT_NAME = "client_name";
public static final String GRANT_TYPES = "grant_types";
@@ -46,6 +46,19 @@ public class OAuthDCRMConstants {
public static final String GRANT_TYPE_AUTHORIZATION_CODE = "authorization_code";
public static final String GRANT_TYPE_PASSWORD = "password";
-
-
+ public static final String TOKEN_AUTH_METHOD = "token_endpoint_auth_method";
+ public static final String TOKEN_AUTH_SIGNATURE_ALGORITHM = "token_endpoint_auth_signing_alg";
+ public static final String SECTOR_IDENTIFIER_URI = "sector_identifier_uri";
+ public static final String ID_TOKEN_SIGNATURE_ALGORITHM = "id_token_signed_response_alg";
+ public static final String ID_TOKEN_ENCRYPTION_ALGORITHM = "id_token_encrypted_response_alg";
+ public static final String ID_TOKEN_ENCRYPTION_METHOD = "id_token_encrypted_response_enc";
+ public static final String REQUEST_OBJECT_SIGNATURE_ALGORITHM = "request_object_signing_alg";
+ public static final String TLS_SUBJECT_DN = "tls_client_auth_subject_dn";
+ public static final String IS_PUSH_AUTH = "require_pushed_authorization_requests";
+ public static final String IS_SIGNED_REQUEST_OBJECT = "require_signed_request_object";
+ public static final String IS_CERTIFICATE_BOUND_ACCESS_TOKEN = "tls_client_certificate_bound_access_tokens";
+ public static final String SUBJECT_TYPE = "subject_type";
+ public static final String REQUEST_OBJECT_ENCRYPTION_ALGORITHM = "request_object_encryption_alg";
+ public static final String REQUEST_OBJECT_ENCRYPTION_METHOD = "request_object_encryption_enc";
+ public static final String JWKS_URI = "jwks_uri";
}
diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/utils/OAuth2Constant.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/utils/OAuth2Constant.java
index 67434f4c365..6a79a049de7 100644
--- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/utils/OAuth2Constant.java
+++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/identity/integration/test/utils/OAuth2Constant.java
@@ -89,7 +89,7 @@ public final class OAuth2Constant {
public static final String GRANT_TYPE_NAME = "grant_type";
public static final String AUTHORIZATION_CODE_NAME = "code";
public static final String REDIRECT_URI_NAME = "redirect_uri";
- public static final String BASIC_HEADER = "Basic";
+ public static final String BASIC_HEADER = "Basic ";
public static final String INVALID_GRANT_ERROR = "invalid_grant";
public static final String SESSION_DATA_KEY_CONSENT = "sessionDataKeyConsent";
public static final String SESSION_DATA_KEY = "sessionDataKey";
diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/IS/oauth/dcr-fapi-validation-enabled.toml b/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/IS/oauth/dcr-fapi-validation-enabled.toml
new file mode 100644
index 00000000000..953307391fb
--- /dev/null
+++ b/modules/integration/tests-integration/tests-backend/src/test/resources/artifacts/IS/oauth/dcr-fapi-validation-enabled.toml
@@ -0,0 +1,36 @@
+[server]
+hostname = "localhost"
+node_ip = "127.0.0.1"
+base_path = "https://$ref{server.hostname}:${carbon.management.port}"
+
+[super_admin]
+username = "admin"
+password = "admin"
+create_admin_account = true
+
+[user_store]
+type = "database_unique_id"
+
+[database.identity_db]
+driver = "$env{IDENTITY_DATABASE_DRIVER}"
+url = "$env{IDENTITY_DATABASE_URL}"
+username = "$env{IDENTITY_DATABASE_USERNAME}"
+password = "$env{IDENTITY_DATABASE_PASSWORD}"
+
+[database.shared_db]
+driver = "$env{SHARED_DATABASE_DRIVER}"
+url = "$env{SHARED_DATABASE_URL}"
+username = "$env{SHARED_DATABASE_USERNAME}"
+password = "$env{SHARED_DATABASE_PASSWORD}"
+
+[keystore.primary]
+file_name = "wso2carbon.jks"
+password = "wso2carbon"
+
+[oauth]
+dcr.enable_sector_identifier_validation=true
+dcr.ssa_jkws="https://localhost:9853/oauth2/jwks"
+dcr.enable_fapi_enforcement=true
+oidc.fapi.enable_validation=true
+oidc.fapi.allowed_client_authentication_methods = ["private_key_jwt", "tls_client_auth"]
+oidc.fapi.allowed_signature_algorithms = ["PS256", "ES256"]
diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/registration-requests/request1.json b/modules/integration/tests-integration/tests-backend/src/test/resources/registration-requests/request1.json
new file mode 100644
index 00000000000..a6b87fab489
--- /dev/null
+++ b/modules/integration/tests-integration/tests-backend/src/test/resources/registration-requests/request1.json
@@ -0,0 +1,28 @@
+{
+ "redirect_uris": [
+ "https://abc/redirect1",
+ "https://abc/redirect2"
+ ],
+ "client_name": "TestErrorScenarios",
+
+ "grant_types": [
+ "client_credentials"
+ ],
+ "jwks_uri": "https://localhost/jwks",
+ "backchannel_logout_uri": "https://www.google.com",
+ "backchannel_logout_session_required": true,
+ "token_endpoint_auth_method": "client_secret",
+ "token_endpoint_auth_signing_alg" : "PS256",
+ "sector_identifier_uri" : "https://gist.githubusercontent.com/SachiniSiriwardene/87efb254413da5fed5610deb7e1b9261/raw/d817580c8d4810fa01d31312fff16c33a4816c1f/redirecturi.json",
+ "id_token_signed_response_alg" : "PS256",
+ "id_token_encrypted_response_alg" : "RSA-OAEP",
+ "id_token_encrypted_response_enc" : "A128GCM",
+ "request_object_signing_alg" : "ES256",
+ "tls_client_auth_subject_dn" : "dfrrfc",
+ "require_signed_request_object" : true,
+ "require_pushed_authorization_requests" : true,
+ "subject_type" : "pairwise",
+ "request_object_encryption_alg" : "RSA-OAEP",
+ "request_object_encryption_enc" : "A128GCM",
+ "tls_client_certificate_bound_access_tokens" : true
+}
diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/registration-requests/request2.json b/modules/integration/tests-integration/tests-backend/src/test/resources/registration-requests/request2.json
new file mode 100644
index 00000000000..40aad0d6333
--- /dev/null
+++ b/modules/integration/tests-integration/tests-backend/src/test/resources/registration-requests/request2.json
@@ -0,0 +1,28 @@
+{
+ "redirect_uris": [
+ "https://abc/redirect1",
+ "https://abc/redirect2"
+ ],
+ "client_name": "TestErrorScenarios",
+
+ "grant_types": [
+ "client_credentials"
+ ],
+ "jwks_uri": "https://localhost/jwks",
+ "backchannel_logout_uri": "https://www.google.com",
+ "backchannel_logout_session_required": true,
+ "token_endpoint_auth_method": "tls_client_auth",
+ "token_endpoint_auth_signing_alg" : "PS256",
+ "sector_identifier_uri" : "https://gist.githubusercontent.com/SachiniSiriwardene/87efb254413da5fed5610deb7e1b9261/raw/d817580c8d4810fa01d31312fff16c33a4816c1f/redirecturi.json",
+ "id_token_signed_response_alg" : "RS256",
+ "id_token_encrypted_response_alg" : "RSA-OAEP",
+ "id_token_encrypted_response_enc" : "A128GCM",
+ "request_object_signing_alg" : "ES256",
+ "tls_client_auth_subject_dn" : "dfrrfc",
+ "require_signed_request_object" : true,
+ "require_pushed_authorization_requests" : true,
+ "subject_type" : "pairwise",
+ "request_object_encryption_alg" : "RSA-OAEP",
+ "request_object_encryption_enc" : "A128GCM",
+ "tls_client_certificate_bound_access_tokens" : true
+}
diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/registration-requests/request3.json b/modules/integration/tests-integration/tests-backend/src/test/resources/registration-requests/request3.json
new file mode 100644
index 00000000000..7fa3861dc37
--- /dev/null
+++ b/modules/integration/tests-integration/tests-backend/src/test/resources/registration-requests/request3.json
@@ -0,0 +1,28 @@
+{
+ "redirect_uris": [
+ "https://abc/redirect1",
+ "https://abc/redirect2"
+ ],
+ "client_name": "TestErrorScenarios",
+
+ "grant_types": [
+ "client_credentials"
+ ],
+ "jwks_uri": "https://localhost/jwks",
+ "backchannel_logout_uri": "https://www.google.com",
+ "backchannel_logout_session_required": true,
+ "token_endpoint_auth_method": "tls_client_auth",
+ "token_endpoint_auth_signing_alg" : "PS256",
+ "sector_identifier_uri" : "https://gist.githubusercontent.com/SachiniSiriwardene/87efb254413da5fed5610deb7e1b9261/raw/d817580c8d4810fa01d31312fff16c33a4816c1f/redirecturi.json",
+ "id_token_signed_response_alg" : "PS256",
+ "id_token_encrypted_response_alg" : "RSA1_5",
+ "id_token_encrypted_response_enc" : "A128GCM",
+ "request_object_signing_alg" : "ES256",
+ "tls_client_auth_subject_dn" : "dfrrfc",
+ "require_signed_request_object" : true,
+ "require_pushed_authorization_requests" : true,
+ "subject_type" : "pairwise",
+ "request_object_encryption_alg" : "RSA-OAEP",
+ "request_object_encryption_enc" : "A128GCM",
+ "tls_client_certificate_bound_access_tokens" : true
+}
diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/registration-requests/request4.json b/modules/integration/tests-integration/tests-backend/src/test/resources/registration-requests/request4.json
new file mode 100644
index 00000000000..8e64738a269
--- /dev/null
+++ b/modules/integration/tests-integration/tests-backend/src/test/resources/registration-requests/request4.json
@@ -0,0 +1,27 @@
+{
+ "redirect_uris": [
+ "https://abc/redirect1",
+ "https://abcd/redirect2"
+ ],
+ "client_name": "TestErrorScenarios",
+
+ "grant_types": [
+ "client_credentials"
+ ],
+ "jwks_uri": "https://localhost/jwks",
+ "backchannel_logout_uri": "https://www.google.com",
+ "backchannel_logout_session_required": true,
+ "token_endpoint_auth_method": "tls_client_auth",
+ "token_endpoint_auth_signing_alg" : "PS256",
+ "id_token_signed_response_alg" : "PS256",
+ "id_token_encrypted_response_alg" : "RSA-OAEP",
+ "id_token_encrypted_response_enc" : "A128GCM",
+ "request_object_signing_alg" : "ES256",
+ "tls_client_auth_subject_dn" : "dfrrfc",
+ "require_signed_request_object" : true,
+ "require_pushed_authorization_requests" : true,
+ "subject_type" : "pairwise",
+ "request_object_encryption_alg" : "RSA-OAEP",
+ "request_object_encryption_enc" : "A128GCM",
+ "tls_client_certificate_bound_access_tokens" : true
+}
diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/registration-requests/request5.json b/modules/integration/tests-integration/tests-backend/src/test/resources/registration-requests/request5.json
new file mode 100644
index 00000000000..7f4e22b15f9
--- /dev/null
+++ b/modules/integration/tests-integration/tests-backend/src/test/resources/registration-requests/request5.json
@@ -0,0 +1,28 @@
+{
+ "redirect_uris": [
+ "https://abc/redirect1",
+ "https://abc/redirect"
+ ],
+ "client_name": "TestErrorScenarios",
+
+ "grant_types": [
+ "client_credentials"
+ ],
+ "jwks_uri": "https://localhost/jwks",
+ "backchannel_logout_uri": "https://www.google.com",
+ "backchannel_logout_session_required": true,
+ "token_endpoint_auth_method": "tls_client_auth",
+ "token_endpoint_auth_signing_alg" : "PS256",
+ "sector_identifier_uri" : "https://gist.githubusercontent.com/SachiniSiriwardene/87efb254413da5fed5610deb7e1b9261/raw/d817580c8d4810fa01d31312fff16c33a4816c1f/redirecturi.json",
+ "id_token_signed_response_alg" : "PS256",
+ "id_token_encrypted_response_alg" : "RSA-OAEP",
+ "id_token_encrypted_response_enc" : "A128GCM",
+ "request_object_signing_alg" : "ES256",
+ "tls_client_auth_subject_dn" : "dfrrfc",
+ "require_signed_request_object" : true,
+ "require_pushed_authorization_requests" : true,
+ "subject_type" : "pairwise",
+ "request_object_encryption_alg" : "RSA-OAEP",
+ "request_object_encryption_enc" : "A128GCM",
+ "tls_client_certificate_bound_access_tokens" : true
+}
diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/registration-requests/request6.json b/modules/integration/tests-integration/tests-backend/src/test/resources/registration-requests/request6.json
new file mode 100644
index 00000000000..01e10c5cf22
--- /dev/null
+++ b/modules/integration/tests-integration/tests-backend/src/test/resources/registration-requests/request6.json
@@ -0,0 +1,26 @@
+{
+ "redirect_uris": [
+ "https://abc/redirect1",
+ "https://abc/redirect2"
+ ],
+ "client_name": "TestAdditionalProperties",
+
+ "grant_types": [
+ "authorization_code",
+ "implicit"
+ ],
+ "jwks_uri": "https://localhost/jwks",
+ "token_endpoint_auth_method": "private_key_jwt",
+ "token_endpoint_auth_signing_alg" : "PS256",
+ "id_token_signed_response_alg" : "PS256",
+ "id_token_encrypted_response_alg" : "RSA-OAEP",
+ "id_token_encrypted_response_enc" : "A128GCM",
+ "request_object_signing_alg" : "ES256",
+ "tls_client_auth_subject_dn" : "dfrrfc",
+ "require_signed_request_object" : true,
+ "require_pushed_authorization_requests" : true,
+ "subject_type" : "pairwise",
+ "request_object_encryption_alg" : "RSA-OAEP",
+ "request_object_encryption_enc" : "A128GCM",
+ "tls_client_certificate_bound_access_tokens":true
+}
diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/registration-requests/request7.json b/modules/integration/tests-integration/tests-backend/src/test/resources/registration-requests/request7.json
new file mode 100644
index 00000000000..b4cbc66c273
--- /dev/null
+++ b/modules/integration/tests-integration/tests-backend/src/test/resources/registration-requests/request7.json
@@ -0,0 +1,26 @@
+{
+ "redirect_uris": [
+ "https://abc/redirect1"
+ ],
+ "client_name": "TestAdditionalProperties",
+
+ "grant_types": [
+ "authorization_code",
+ "implicit"
+ ],
+ "jwks_uri": "https://localhost/jwks",
+ "token_endpoint_auth_method": "tls_client_auth",
+ "token_endpoint_auth_signing_alg" : "PS256",
+ "sector_identifier_uri" : "https://gist.githubusercontent.com/SachiniSiriwardene/87efb254413da5fed5610deb7e1b9261/raw/d817580c8d4810fa01d31312fff16c33a4816c1f/redirecturi.json",
+ "id_token_signed_response_alg" : "PS256",
+ "id_token_encrypted_response_alg" : "RSA-OAEP",
+ "id_token_encrypted_response_enc" : "A128GCM",
+ "request_object_signing_alg" : "PS256",
+ "tls_client_auth_subject_dn" : "dfrrfc",
+ "require_signed_request_object" : true,
+ "require_pushed_authorization_requests" : true,
+ "subject_type" : "pairwise",
+ "request_object_encryption_alg" : "RSA-OAEP",
+ "request_object_encryption_enc" : "A128GCM",
+ "tls_client_certificate_bound_access_tokens":false
+}
diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/registration-requests/request8.json b/modules/integration/tests-integration/tests-backend/src/test/resources/registration-requests/request8.json
new file mode 100644
index 00000000000..2e6910665c1
--- /dev/null
+++ b/modules/integration/tests-integration/tests-backend/src/test/resources/registration-requests/request8.json
@@ -0,0 +1,28 @@
+{
+ "redirect_uris": [
+ "https://abc/redirect1"
+ ],
+ "client_name": "TestErrorScenarios",
+
+ "grant_types": [
+ "authorization_code",
+ "implicit"
+ ],
+ "jwks_uri": "https://localhost/jwks",
+ "software_statement": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ik1ESmxOakl4TjJFMU9HWmxPR1ZtTUdReE9URmxNekJtTm1GalpqUTBZMll3T0dZME4ySTBZekU0WXpaak5qUmhZbVJtTW1RME9EZGlORGhqTUdFd01BX1JTMjccdU2IiwidHlwIjoiSldUIn0.eyJpc3MiOiJPcGVuQmFua2luZyBMdGQiLCJpYXQiOjE2NDc0MDU5NDAsImp0aSI6IjM2YjVkZmUwMjA1YzQwNjAiLCJzb2Z0d2FyZV9lbnZpcm9ubWVudCI6InNhbmRib3giLCJzb2Z0d2FyZV9tb2RlIjoiVGVzdCIsInNvZnR3YXJlX2lkIjoib1E0S29hYXZwT3VvRTdydlFzWkVPViIsInNvZnR3YXJlX2NsaWVudF9pZCI6Im9RNEtvYWF2cE91b0U3cnZRc1pFT1YiLCJzb2Z0d2FyZV9jbGllbnRfbmFtZSI6IldTTzIgT3BlbiBCYW5raW5nIFRQUDIgKFNhbmRib3gpIiwic29mdHdhcmVfY2xpZW50X2Rlc2NyaXB0aW9uIjoiV1NPMiBPcGVuIEJhbmtpbmcgVFBQMiBmb3IgdGVzdGluZyIsInNvZnR3YXJlX3ZlcnNpb24iOjEuNSwic29mdHdhcmVfY2xpZW50X3VyaSI6Imh0dHBzOi8vd3d3Lmdvb2dsZS5jb20iLCJzb2Z0d2FyZV9yZWRpcmVjdF91cmlzIjpbImh0dHBzOi8vd3d3Lmdvb2dsZS5jb20vcmVkaXJlY3RzL3JlZGlyZWN0MSJdLCJzb2Z0d2FyZV9yb2xlcyI6WyJQSVNQIiwiQUlTUCIsIkNCUElJIl0sIm9yZ2FuaXNhdGlvbl9jb21wZXRlbnRfYXV0aG9yaXR5X2NsYWltcyI6eyJhdXRob3JpdHlfaWQiOiJPQkdCUiIsInJlZ2lzdHJhdGlvbl9pZCI6IlVua25vd24wMDE1ODAwMDAxSFFRclpBQVgiLCJzdGF0dXMiOiJBY3RpdmUiLCJhdXRob3Jpc2F0aW9ucyI6W3sibWVtYmVyX3N0YXRlIjoiR0IiLCJyb2xlcyI6WyJQSVNQIiwiQUlTUCIsIkNCUElJIl19LHsibWVtYmVyX3N0YXRlIjoiSUUiLCJyb2xlcyI6WyJQSVNQIiwiQ0JQSUkiLCJBSVNQIl19LHsibWVtYmVyX3N0YXRlIjoiTkwiLCJyb2xlcyI6WyJQSVNQIiwiQUlTUCIsIkNCUElJIl19XX0sInNvZnR3YXJlX2xvZ29fdXJpIjoiaHR0cHM6Ly93d3cuZ29vZ2xlLmNvbSIsIm9yZ19zdGF0dXMiOiJBY3RpdmUiLCJvcmdfaWQiOiIwMDE1ODAwMDAxSFFRclpBQVgiLCJvcmdfbmFtZSI6IldTTzIgKFVLKSBMSU1JVEVEIiwib3JnX2NvbnRhY3RzIjpbeyJuYW1lIjoiVGVjaG5pY2FsIiwiZW1haWwiOiJzYWNoaW5pc0B3c28yLmNvbSIsInBob25lIjoiKzk0Nzc0Mjc0Mzc0IiwidHlwZSI6IlRlY2huaWNhbCJ9LHsibmFtZSI6IkJ1c2luZXNzIiwiZW1haWwiOiJzYWNoaW5pc0B3c28yLmNvbSIsInBob25lIjoiKzk0Nzc0Mjc0Mzc0IiwidHlwZSI6IkJ1c2luZXNzIn1dLCJvcmdfandrc19lbmRwb2ludCI6Imh0dHBzOi8va2V5c3RvcmUub3BlbmJhbmtpbmd0ZXN0Lm9yZy51ay8wMDE1ODAwMDAxSFFRclpBQVgvMDAxNTgwMDAwMUhRUXJaQUFYLmp3a3MiLCJvcmdfandrc19yZXZva2VkX2VuZHBvaW50IjoiaHR0cHM6Ly9rZXlzdG9yZS5vcGVuYmFua2luZ3Rlc3Qub3JnLnVrLzAwMTU4MDAwMDFIUVFyWkFBWC9yZXZva2VkLzAwMTU4MDAwMDFIUVFyWkFBWC5qd2tzIiwic29mdHdhcmVfandrc19lbmRwb2ludCI6Imh0dHBzOi8va2V5c3RvcmUub3BlbmJhbmtpbmd0ZXN0Lm9yZy51ay8wMDE1ODAwMDAxSFFRclpBQVgvb1E0S29hYXZwT3VvRTdydlFzWkVPVi5qd2tzIiwic29mdHdhcmVfandrc19yZXZva2VkX2VuZHBvaW50IjoiaHR0cHM6Ly9rZXlzdG9yZS5vcGVuYmFua2luZ3Rlc3Qub3JnLnVrLzAwMTU4MDAwMDFIUVFyWkFBWC9yZXZva2VkL29RNEtvYWF2cE91b0U3cnZRc1pFT1YuandrcyIsInNvZnR3YXJlX3BvbGljeV91cmkiOiJodHRwczovL3d3dy5nb29nbGUuY29tIiwic29mdHdhcmVfdG9zX3VyaSI6Imh0dHBzOi8vd3d3Lmdvb2dsZS5jb20iLCJzb2Z0d2FyZV9vbl9iZWhhbGZfb2Zfb3JnIjoiV1NPMiBPcGVuIEJhbmtpbmcifQ.H_9zUiJnaGxdCW1hY16IpRVRdVwZTeoKG3t8NrQ5t_VAF4OPIhz1rhJgE117Z-MA6rVOhs3qXe-3-qswm9uEPR5El3qGfumCcmrKouh7xfE8NJo65Ox947cDgPVfY2RmdIJ5snZHZaw66Ty0iy0x57RSQCjMBkKzJGxG_uv6usS6TLCz_Z7sYl0aZ_SORlg2OWCMJ-LspPCfqzh09_eIuP2_2n9rW6-98kz7MebP4rPJn4wdUtHLc_noMydey6MCOZCMOl4wXbkbvZxMq2oRtoV_VYPkgs1lzGobE5OgAX4UKMk9jOKJkhD-k6AENG35Z1_U2K9kdhpXLwCJwzJbfg",
+ "token_endpoint_auth_method": "private_key_jwt",
+ "token_endpoint_auth_signing_alg" : "PS256",
+ "sector_identifier_uri" : "https://gist.githubusercontent.com/SachiniSiriwardene/87efb254413da5fed5610deb7e1b9261/raw/d817580c8d4810fa01d31312fff16c33a4816c1f/redirecturi.json",
+ "id_token_signed_response_alg" : "PS256",
+ "id_token_encrypted_response_alg" : "RSA-OAEP",
+ "id_token_encrypted_response_enc" : "A128GCM",
+ "request_object_signing_alg" : "ES256",
+ "tls_client_auth_subject_dn" : "dfrrfc",
+ "require_signed_request_object" : true,
+ "require_pushed_authorization_requests" : true,
+ "subject_type" : "pairwise",
+ "request_object_encryption_alg" : "RSA-OAEP",
+ "request_object_encryption_enc" : "A128GCM",
+ "tls_client_certificate_bound_access_tokens":true
+}
+
diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/testng.xml b/modules/integration/tests-integration/tests-backend/src/test/resources/testng.xml
index 8c23c636a04..85371937400 100644
--- a/modules/integration/tests-integration/tests-backend/src/test/resources/testng.xml
+++ b/modules/integration/tests-integration/tests-backend/src/test/resources/testng.xml
@@ -377,4 +377,9 @@
+
+
+
+
+