From 2efd79f98206c43eaef8ef6373bddaaba5dc066a Mon Sep 17 00:00:00 2001 From: Takashi Norimatsu Date: Sat, 27 May 2023 19:36:08 +0900 Subject: [PATCH] FAPI 2.0 security profile - supporting RFC 9207 OAuth 2.0 Authorization Server Issuer Identification Closes #20584 --- .../adapters/OAuthRequestAuthenticator.java | 3 +- .../org/keycloak/adapters/ServerRequest.java | 3 +- .../java/org/keycloak/OAuth2Constants.java | 3 + .../OIDCConfigurationRepresentation.java | 12 ++ .../topics/keycloak/changes-23_0_0.adoc | 13 ++ .../upgrading/topics/keycloak/changes.adoc | 4 + .../public/locales/en/clients-help.json | 1 + .../admin-ui/public/locales/en/clients.json | 1 + .../OpenIdConnectCompatibilityModes.tsx | 29 ++++ js/libs/keycloak-js/src/keycloak.js | 6 +- .../protocol/oidc/OIDCConfigAttributes.java | 1 + .../oidc/OIDCAdvancedConfigWrapper.java | 10 ++ .../protocol/oidc/OIDCLoginProtocol.java | 6 + .../protocol/oidc/OIDCWellKnownProvider.java | 2 + .../oidc/endpoints/AuthorizationEndpoint.java | 6 + .../hello-world-authz-realm.json | 5 +- .../servlet-authz/servlet-authz-realm.json | 5 +- .../servlet-policy-enforcer-authz-realm.json | 3 + .../keycloak/testsuite/util/OAuthClient.java | 6 + .../BrokerLinkAndTokenExchangeTest.java | 9 ++ .../ClientInitiatedAccountLinkTest.java | 7 + .../oauth/AuthorizationCodeTest.java | 4 + .../testsuite/oauth/OAuthRedirectUriTest.java | 1 + .../oidc/OIDCBackwardsCompatibilityTest.java | 67 ++++++++++ .../resources/adapter-test/demorealm.json | 124 ++++++++++++++---- .../offline-client/offlinerealm.json | 15 ++- .../resources/adapter-test/tenant1-realm.json | 5 +- .../resources/adapter-test/tenant2-realm.json | 5 +- 28 files changed, 318 insertions(+), 38 deletions(-) create mode 100644 docs/documentation/upgrading/topics/keycloak/changes-23_0_0.adoc diff --git a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java index 1ad69adb7ce..68acc1118fb 100755 --- a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java +++ b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/OAuthRequestAuthenticator.java @@ -384,7 +384,8 @@ public class OAuthRequestAuthenticator { KeycloakUriBuilder builder = KeycloakUriBuilder.fromUri(facade.getRequest().getURI()) .replaceQueryParam(OAuth2Constants.CODE, null) .replaceQueryParam(OAuth2Constants.STATE, null) - .replaceQueryParam(OAuth2Constants.SESSION_STATE, null); + .replaceQueryParam(OAuth2Constants.SESSION_STATE, null) + .replaceQueryParam(OAuth2Constants.ISSUER, null); return builder.buildAsString(); } diff --git a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/ServerRequest.java b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/ServerRequest.java index dcf0d8f58c9..24f7aa73f90 100755 --- a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/ServerRequest.java +++ b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/ServerRequest.java @@ -290,7 +290,8 @@ public class ServerRequest { protected static String stripOauthParametersFromRedirect(String uri) { KeycloakUriBuilder builder = KeycloakUriBuilder.fromUri(uri) .replaceQueryParam(OAuth2Constants.CODE, null) - .replaceQueryParam(OAuth2Constants.STATE, null); + .replaceQueryParam(OAuth2Constants.STATE, null) + .replaceQueryParam(OAuth2Constants.ISSUER, null); return builder.buildAsString(); } diff --git a/core/src/main/java/org/keycloak/OAuth2Constants.java b/core/src/main/java/org/keycloak/OAuth2Constants.java index 5110b5ad8d0..93c4a53703e 100755 --- a/core/src/main/java/org/keycloak/OAuth2Constants.java +++ b/core/src/main/java/org/keycloak/OAuth2Constants.java @@ -145,6 +145,9 @@ public interface OAuth2Constants { // https://openid.net/specs/openid-financial-api-jarm-ID1.html String RESPONSE = "response"; + + // https://www.rfc-editor.org/rfc/rfc9207.html + String ISSUER = "iss"; } diff --git a/core/src/main/java/org/keycloak/protocol/oidc/representations/OIDCConfigurationRepresentation.java b/core/src/main/java/org/keycloak/protocol/oidc/representations/OIDCConfigurationRepresentation.java index 21be6358472..25855571c5a 100755 --- a/core/src/main/java/org/keycloak/protocol/oidc/representations/OIDCConfigurationRepresentation.java +++ b/core/src/main/java/org/keycloak/protocol/oidc/representations/OIDCConfigurationRepresentation.java @@ -193,6 +193,9 @@ public class OIDCConfigurationRepresentation { @JsonProperty("mtls_endpoint_aliases") private MTLSEndpointAliases mtlsEndpointAliases; + @JsonProperty("authorization_response_iss_parameter_supported") + private Boolean authorizationResponseIssParameterSupported; + protected Map otherClaims = new HashMap(); public String getIssuer() { @@ -624,4 +627,13 @@ public class OIDCConfigurationRepresentation { public Boolean getFrontChannelLogoutSupported() { return frontChannelLogoutSupported; } + + public Boolean getAuthorizationResponseIssParameterSupported() { + return authorizationResponseIssParameterSupported; + } + + public void setAuthorizationResponseIssParameterSupported(Boolean authorizationResponseIssParameterSupported) { + this.authorizationResponseIssParameterSupported = authorizationResponseIssParameterSupported; + } + } diff --git a/docs/documentation/upgrading/topics/keycloak/changes-23_0_0.adoc b/docs/documentation/upgrading/topics/keycloak/changes-23_0_0.adoc new file mode 100644 index 00000000000..5d589d8b231 --- /dev/null +++ b/docs/documentation/upgrading/topics/keycloak/changes-23_0_0.adoc @@ -0,0 +1,13 @@ += Added iss parameter to OAuth 2.0/OpenID Connect Authentication Response + +RFC 9207 OAuth 2.0 Authorization Server Issuer Identification specification adds the parameter `iss` in the OAuth 2.0/OpenID Connect Authentication Response for realizing secure authorization responses. + +In past releases, we did not have this parameter, but now {project_name} adds this parameter by default, as required by the specification. + +However, some OpenID Connect / OAuth2 adapters, and especially older {project_name} adapters, may have issues with this new parameter. + +For example, the parameter will be always present in the browser URL after successful authentication to the client application. +In these cases, it may be useful to disable adding the `iss` parameter to the authentication response. This can be done +for the particular client in the {project_name} Admin console, in client details in the section with `OpenID Connect Compatibility Modes`, +described in <<_compatibility_with_older_adapters>>. Dedicated `Exclude Issuer From Authentication Response` switch exists, +which can be turned on to prevent adding the `iss` parameter to the authentication response. diff --git a/docs/documentation/upgrading/topics/keycloak/changes.adoc b/docs/documentation/upgrading/topics/keycloak/changes.adoc index 229c7bf9039..639b3bbbfc1 100644 --- a/docs/documentation/upgrading/topics/keycloak/changes.adoc +++ b/docs/documentation/upgrading/topics/keycloak/changes.adoc @@ -1,5 +1,9 @@ == Migration Changes +=== Migrating to 23.0.0 + +include::changes-23_0_0.adoc[leveloffset=3] + === Migrating to 22.0.0 include::changes-22_0_0.adoc[leveloffset=3] diff --git a/js/apps/admin-ui/public/locales/en/clients-help.json b/js/apps/admin-ui/public/locales/en/clients-help.json index 94dda03c058..586323dac27 100644 --- a/js/apps/admin-ui/public/locales/en/clients-help.json +++ b/js/apps/admin-ui/public/locales/en/clients-help.json @@ -96,6 +96,7 @@ "authorizationEncryptedResponseEnc": "JWA Algorithm used for content encryption in encrypting the authorization response when the response mode is jwt. This option is needed if you want encrypted authorization response. If left empty, the authorization response is just signed, but not encrypted.", "openIdConnectCompatibilityModes": "This section is used to configure settings for backward compatibility with older OpenID Connect / OAuth 2 adaptors. It's useful especially if your client uses older version of Keycloak / RH-SSO adapter.", "excludeSessionStateFromAuthenticationResponse": "If this is on, the parameter 'session_state' will not be included in OpenID Connect Authentication Response. It is useful if your client uses older OIDC / OAuth2 adapter, which does not support 'session_state' parameter.", + "excludeIssuerFromAuthenticationResponse": "If this is on, the parameter 'iss' will not be included in OpenID Connect Authentication Response. It is useful if your client uses older OIDC / OAuth2 adapter, which does not support 'session_state' parameter.", "useRefreshTokens": "If this is on, a refresh_token will be created and added to the token response. If this is off then no refresh_token will be generated.", "useRefreshTokenForClientCredentialsGrant": "If this is on, a refresh_token will be created and added to the token response if the client_credentials grant is used. The OAuth 2.0 RFC6749 Section 4.4.3 states that a refresh_token should not be generated when client_credentials grant is used. If this is off then no refresh_token will be generated and the associated user session will be removed.", "useLowerCaseBearerType": "If this is on, token responses will be set the with the type \"bearer\" in lower-case. By default, the server sets the type as \"Bearer\" as defined by RFC6750.", diff --git a/js/apps/admin-ui/public/locales/en/clients.json b/js/apps/admin-ui/public/locales/en/clients.json index a24c411c640..e43def70a69 100644 --- a/js/apps/admin-ui/public/locales/en/clients.json +++ b/js/apps/admin-ui/public/locales/en/clients.json @@ -492,6 +492,7 @@ "authorizationEncryptedResponseEnc": "Authorization response encryption content encryption algorithm", "openIdConnectCompatibilityModes": "Open ID Connect Compatibility Modes", "excludeSessionStateFromAuthenticationResponse": "Exclude Session State From Authentication Response", + "excludeIssuerFromAuthenticationResponse": "Exclude Issuer From Authentication Response", "useRefreshTokens": "Use refresh tokens", "useRefreshTokenForClientCredentialsGrant": "Use refresh tokens for client credentials grant", "useLowerCaseBearerType": "Use lower-case bearer type in token responses", diff --git a/js/apps/admin-ui/src/clients/advanced/OpenIdConnectCompatibilityModes.tsx b/js/apps/admin-ui/src/clients/advanced/OpenIdConnectCompatibilityModes.tsx index 4ecc97d715d..859d9a17d52 100644 --- a/js/apps/admin-ui/src/clients/advanced/OpenIdConnectCompatibilityModes.tsx +++ b/js/apps/admin-ui/src/clients/advanced/OpenIdConnectCompatibilityModes.tsx @@ -57,6 +57,35 @@ export const OpenIdConnectCompatibilityModes = ({ )} /> + + } + > + ( + "attributes.exclude.issuer.from.auth.response", + )} + defaultValue="" + control={control} + render={({ field }) => ( + field.onChange(value.toString())} + aria-label={t("excludeIssuerFromAuthenticationResponse")} + /> + )} + /> + attributes = Optional.ofNullable(servlet.getAttributes()).orElse(new HashMap<>()); + attributes.put(OIDCConfigAttributes.EXCLUDE_ISSUER_FROM_AUTH_RESPONSE, Boolean.TRUE.toString()); + servlet.setAttributes(attributes); + realm.setClients(new LinkedList<>()); realm.getClients().add(servlet); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/ClientInitiatedAccountLinkTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/ClientInitiatedAccountLinkTest.java index e3d9dc5d3d0..4aafdb22c0d 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/ClientInitiatedAccountLinkTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/ClientInitiatedAccountLinkTest.java @@ -33,6 +33,7 @@ import org.keycloak.common.util.Base64Url; import org.keycloak.models.Constants; import org.keycloak.models.IdentityProviderMapperModel; import org.keycloak.models.IdentityProviderMapperSyncMode; +import org.keycloak.protocol.oidc.OIDCConfigAttributes; import org.keycloak.protocol.oidc.OIDCLoginProtocol; import org.keycloak.representations.AccessTokenResponse; import org.keycloak.representations.idm.ClientRepresentation; @@ -61,6 +62,7 @@ import org.keycloak.util.JsonSerialization; import jakarta.ws.rs.client.Client; import jakarta.ws.rs.core.UriBuilder; import java.net.URL; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -138,6 +140,11 @@ public class ClientInitiatedAccountLinkTest extends AbstractServletsAdapterTest servlet.getRedirectUris().add(uri + "/*"); servlet.setSecret("password"); servlet.setFullScopeAllowed(true); + + Map attributes = Optional.ofNullable(servlet.getAttributes()).orElse(new HashMap<>()); + attributes.put(OIDCConfigAttributes.EXCLUDE_ISSUER_FROM_AUTH_RESPONSE, Boolean.TRUE.toString()); + servlet.setAttributes(attributes); + realm.setClients(new LinkedList<>()); realm.getClients().add(servlet); testRealms.add(realm); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java index f9f835091f2..617fb8eae57 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java @@ -86,6 +86,7 @@ public class AuthorizationCodeTest extends AbstractKeycloakTest { Assert.assertNotNull(response.getCode()); assertEquals("OpenIdConnect.AuthenticationProperties=2302984sdlk", response.getState()); Assert.assertNull(response.getError()); + assertEquals(oauth.AUTH_SERVER_ROOT + "/realms/test", response.getIssuer()); String codeId = events.expectLogin().assertEvent().getDetails().get(Details.CODE_ID); } @@ -160,6 +161,7 @@ public class AuthorizationCodeTest extends AbstractKeycloakTest { Assert.assertNotNull(response.getCode()); Assert.assertNull(response.getState()); Assert.assertNull(response.getError()); + assertEquals(oauth.AUTH_SERVER_ROOT + "/realms/test", response.getIssuer()); String codeId = events.expectLogin().assertEvent().getDetails().get(Details.CODE_ID); } @@ -173,6 +175,7 @@ public class AuthorizationCodeTest extends AbstractKeycloakTest { OAuthClient.AuthorizationEndpointResponse errorResponse = new OAuthClient.AuthorizationEndpointResponse(oauth); assertTrue(errorResponse.isRedirected()); Assert.assertEquals(errorResponse.getError(), OAuthErrorException.UNSUPPORTED_RESPONSE_TYPE); + Assert.assertEquals(oauth.AUTH_SERVER_ROOT + "/realms/test", errorResponse.getIssuer()); events.expectLogin().error(Errors.INVALID_REQUEST).user((String) null).session((String) null).clearDetails().detail(Details.RESPONSE_TYPE, "tokenn").assertEvent(); } @@ -284,6 +287,7 @@ public class AuthorizationCodeTest extends AbstractKeycloakTest { Assert.assertNotNull(response.getCode()); Assert.assertNotNull(response.getState()); + Assert.assertEquals(oauth.AUTH_SERVER_ROOT + "/realms/test", response.getIssuer()); currentUri = new URI(driver.getCurrentUrl()); Assert.assertNotNull(currentUri.getRawQuery()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuthRedirectUriTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuthRedirectUriTest.java index f857b7f0eed..cbfdb80a4bb 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuthRedirectUriTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuthRedirectUriTest.java @@ -501,6 +501,7 @@ public class OAuthRedirectUriTest extends AbstractKeycloakTest { .replaceQueryParam(OAuth2Constants.CODE, null) .replaceQueryParam(OAuth2Constants.STATE, null) .replaceQueryParam(OAuth2Constants.SESSION_STATE, null) + .replaceQueryParam(OAuth2Constants.ISSUER, null) .build().toString(); if (browserUrlAfterRedirectFromKeycloak.endsWith("/")) browserUrlAfterRedirectFromKeycloak = browserUrlAfterRedirectFromKeycloak.substring(0, browserUrlAfterRedirectFromKeycloak.length() - 1); if (Constants.INSTALLED_APP_URN.equals(redirectUri)) { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCBackwardsCompatibilityTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCBackwardsCompatibilityTest.java index 6232c4cfc00..a93a7154214 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCBackwardsCompatibilityTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCBackwardsCompatibilityTest.java @@ -17,12 +17,18 @@ package org.keycloak.testsuite.oidc; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; + import org.jboss.arquillian.graphene.page.Page; import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.keycloak.OAuthErrorException; import org.keycloak.admin.client.resource.ClientResource; import org.keycloak.events.Details; +import org.keycloak.events.Errors; import org.keycloak.protocol.oidc.OIDCAdvancedConfigWrapper; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.EventRepresentation; @@ -38,6 +44,8 @@ import org.keycloak.testsuite.pages.OAuthGrantPage; import org.keycloak.testsuite.util.ClientManager; import org.keycloak.testsuite.util.OAuthClient; +import jakarta.ws.rs.core.UriBuilder; + /** * @author Marek Posolda @@ -106,5 +114,64 @@ public class OIDCBackwardsCompatibilityTest extends AbstractTestRealmKeycloakTes client.update(clientRep); } + @Test + public void testExcludeIssuerParameter() { + // Open login form and login successfully. Assert iss parameter is present + OAuthClient.AuthorizationEndpointResponse authzResponse = oauth.doLogin("test-user@localhost", "password"); + events.expectLogin().assertEvent(); + Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); + Assert.assertEquals(oauth.AUTH_SERVER_ROOT + "/realms/test", authzResponse.getIssuer()); + // Switch "exclude iss" to on + ClientResource client = ApiUtil.findClientByClientId(adminClient.realm("test"), "test-app"); + ClientRepresentation clientRep = client.toRepresentation(); + OIDCAdvancedConfigWrapper config = OIDCAdvancedConfigWrapper.fromClientRepresentation(clientRep); + config.setExcludeIssuerFromAuthResponse(true); + client.update(clientRep); + + // Open login again and assert iss parameter is not present + driver.navigate().to(oauth.getLoginFormUrl()); + org.keycloak.testsuite.Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); + events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent(); + + authzResponse = new OAuthClient.AuthorizationEndpointResponse(oauth); + Assert.assertNull(authzResponse.getIssuer()); + + // Revert + config.setExcludeIssuerFromAuthResponse(false); + client.update(clientRep); + } + + @Test + public void testExcludeIssuerParameterOnError() throws IOException { + // Open login form and login fails. Assert iss parameter is present + oauth.responseType("tokenn"); + UriBuilder b = UriBuilder.fromUri(oauth.getLoginFormUrl()); + driver.navigate().to(b.build().toURL()); + + OAuthClient.AuthorizationEndpointResponse errorResponse = new OAuthClient.AuthorizationEndpointResponse(oauth); + assertTrue(errorResponse.isRedirected()); + Assert.assertEquals(errorResponse.getError(), OAuthErrorException.UNSUPPORTED_RESPONSE_TYPE); + Assert.assertEquals(oauth.AUTH_SERVER_ROOT + "/realms/test", errorResponse.getIssuer()); + + events.expectLogin().error(Errors.INVALID_REQUEST).user((String) null).session((String) null).clearDetails().detail(Details.RESPONSE_TYPE, "tokenn").assertEvent(); + + // Switch "exclude iss" to on + ClientResource client = ApiUtil.findClientByClientId(adminClient.realm("test"), "test-app"); + ClientRepresentation clientRep = client.toRepresentation(); + OIDCAdvancedConfigWrapper config = OIDCAdvancedConfigWrapper.fromClientRepresentation(clientRep); + config.setExcludeIssuerFromAuthResponse(true); + client.update(clientRep); + + // Open login again and assert iss parameter is not present + driver.navigate().to(b.build().toURL()); + + errorResponse = new OAuthClient.AuthorizationEndpointResponse(oauth); + assertTrue(errorResponse.isRedirected()); + Assert.assertEquals(errorResponse.getError(), OAuthErrorException.UNSUPPORTED_RESPONSE_TYPE); + Assert.assertNull(errorResponse.getIssuer()); + + events.expectLogin().error(Errors.INVALID_REQUEST).user((String) null).session((String) null).clearDetails().detail(Details.RESPONSE_TYPE, "tokenn").assertEvent(); + + } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/demorealm.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/demorealm.json index edec83f46c4..9d5c678e6a3 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/demorealm.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/demorealm.json @@ -131,14 +131,20 @@ "enabled": true, "adminUrl": "/customer-db", "baseUrl": "/customer-db", - "bearerOnly": true + "bearerOnly": true, + "attributes" : { + "exclude.issuer.from.auth.response": "true" + } }, { "clientId": "customer-db-audience-required", "enabled": true, "adminUrl": "/customer-db-audience-required", "baseUrl": "/customer-db-audience-required", - "bearerOnly": true + "bearerOnly": true, + "attributes" : { + "exclude.issuer.from.auth.response": "true" + } }, { "clientId": "customer-portal", @@ -149,7 +155,10 @@ "/customer-portal/*" ], "secret": "password", - "directAccessGrantsEnabled": true + "directAccessGrantsEnabled": true, + "attributes" : { + "exclude.issuer.from.auth.response": "true" + } }, { "clientId": "serialization-servlet", @@ -160,7 +169,10 @@ "/serialization-servlet/*" ], "secret": "password", - "directAccessGrantsEnabled": true + "directAccessGrantsEnabled": true, + "attributes" : { + "exclude.issuer.from.auth.response": "true" + } }, { "clientId": "customer-portal-subsystem", @@ -170,7 +182,10 @@ "redirectUris": [ "/customer-portal-subsystem/*" ], - "secret": "password" + "secret": "password", + "attributes" : { + "exclude.issuer.from.auth.response": "true" + } }, { "clientId": "customer-cookie-portal", @@ -179,7 +194,10 @@ "redirectUris": [ "/customer-cookie-portal/*" ], - "secret": "password" + "secret": "password", + "attributes" : { + "exclude.issuer.from.auth.response": "true" + } }, { "clientId": "customer-cookie-portal-root", @@ -188,7 +206,10 @@ "redirectUris": [ "http://localhost:8080/*" ], - "secret": "password" + "secret": "password", + "attributes" : { + "exclude.issuer.from.auth.response": "true" + } }, { "clientId": "customer-portal-js", @@ -198,7 +219,10 @@ "baseUrl": "/customer-portal-js", "redirectUris": [ "/customer-portal-js/*" - ] + ], + "attributes" : { + "exclude.issuer.from.auth.response": "true" + } }, { "clientId": "customer-portal-cli", @@ -207,13 +231,19 @@ "redirectUris": [ "urn:ietf:wg:oauth:2.0:oob", "http://localhost" - ] + ], + "attributes" : { + "exclude.issuer.from.auth.response": "true" + } }, { "clientId": "customer-portal-public", "enabled": true, "publicClient": true, - "directAccessGrantsEnabled": true + "directAccessGrantsEnabled": true, + "attributes" : { + "exclude.issuer.from.auth.response": "true" + } }, { "clientId": "product-portal", @@ -223,7 +253,10 @@ "redirectUris": [ "/product-portal/*" ], - "secret": "password" + "secret": "password", + "attributes" : { + "exclude.issuer.from.auth.response": "true" + } }, { "clientId": "product-portal-subsystem", @@ -233,7 +266,10 @@ "redirectUris": [ "/product-portal-subsystem/*" ], - "secret": "password" + "secret": "password", + "attributes" : { + "exclude.issuer.from.auth.response": "true" + } }, { "clientId": "product-portal-autodetect-bearer-only", @@ -243,7 +279,10 @@ "redirectUris": [ "/product-portal-autodetect-bearer-only/*" ], - "secret": "password" + "secret": "password", + "attributes" : { + "exclude.issuer.from.auth.response": "true" + } }, { "clientId": "secure-portal", @@ -255,7 +294,8 @@ "/secure-portal/*" ], "attributes" : { - "jwt.credential.certificate" : "MIICqTCCAZECBgFT0Ngs/DANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1zZWN1cmUtcG9ydGFsMB4XDTE2MDQwMTA4MDA0MVoXDTI2MDQwMTA4MDIyMVowGDEWMBQGA1UEAwwNc2VjdXJlLXBvcnRhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJa4GixpmzP511AmI0eLPLORyJwXS8908MUvdG3hmh8jMOIhe28XjIFeZSY09vFxh22F2SUMjxU/B2Hw4PDJUkebuNR7rXhOIYCJAo6eEZzjSBY/wngFtfm74zJ/eLCobBtDvIld7jobdHTfE1Oz9+GzvtG0k7cm7ubrLT0J4I1UsFZj3b//3wa+O0vNaTwHC1Jz/m59VbtXqyO4xEzIdl416cnGCmEmk5qd5h1de2UoLi/CTad8HftIJhzN1qhlySzW/9Ha70aYlDH2hiibDsXDTrNaMdaaLik7I8Rv/nIbggysG863PKZo8wknDe62QctH5VYSSktiy4gjSJkGh7ECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAZnnx+AHQ8txugGcFK8gWjildDgk+v31fBHBDvmLQaSzsUaIOJaK4wnlwUI+VfR46HmBXhjlDCobFLUptd+kz0G7xapcIn3b5jLrySUUD7L+LAp1vNOQU4mKhTGS3IEvNB73D3GH9rQ+M3KEcoN3f99fNKqKsUdxbmZqGf4VOQ57PUfLBw4PJJGlROPosBc7ivPRyeYnKekhoCTynq30BAD1FA1BA8ppcY4ZVGADPTAgMJxpglpFY9LiqCwdLAGW1ttnsyIJ7DpT+kybhhk7c+MU7gyQdv8xPnMR0bSCB9hndowgBn5oZ393aMscwMNCzwJ0aWBs1sUyn3X0RIsu9Jg==" + "jwt.credential.certificate" : "MIICqTCCAZECBgFT0Ngs/DANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1zZWN1cmUtcG9ydGFsMB4XDTE2MDQwMTA4MDA0MVoXDTI2MDQwMTA4MDIyMVowGDEWMBQGA1UEAwwNc2VjdXJlLXBvcnRhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJa4GixpmzP511AmI0eLPLORyJwXS8908MUvdG3hmh8jMOIhe28XjIFeZSY09vFxh22F2SUMjxU/B2Hw4PDJUkebuNR7rXhOIYCJAo6eEZzjSBY/wngFtfm74zJ/eLCobBtDvIld7jobdHTfE1Oz9+GzvtG0k7cm7ubrLT0J4I1UsFZj3b//3wa+O0vNaTwHC1Jz/m59VbtXqyO4xEzIdl416cnGCmEmk5qd5h1de2UoLi/CTad8HftIJhzN1qhlySzW/9Ha70aYlDH2hiibDsXDTrNaMdaaLik7I8Rv/nIbggysG863PKZo8wknDe62QctH5VYSSktiy4gjSJkGh7ECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAZnnx+AHQ8txugGcFK8gWjildDgk+v31fBHBDvmLQaSzsUaIOJaK4wnlwUI+VfR46HmBXhjlDCobFLUptd+kz0G7xapcIn3b5jLrySUUD7L+LAp1vNOQU4mKhTGS3IEvNB73D3GH9rQ+M3KEcoN3f99fNKqKsUdxbmZqGf4VOQ57PUfLBw4PJJGlROPosBc7ivPRyeYnKekhoCTynq30BAD1FA1BA8ppcY4ZVGADPTAgMJxpglpFY9LiqCwdLAGW1ttnsyIJ7DpT+kybhhk7c+MU7gyQdv8xPnMR0bSCB9hndowgBn5oZ393aMscwMNCzwJ0aWBs1sUyn3X0RIsu9Jg==", + "exclude.issuer.from.auth.response": "true" } }, { @@ -268,7 +308,8 @@ "/rewritten/*" ], "attributes" : { - "jwt.credential.certificate" : "MIICqTCCAZECBgFT0Ngs/DANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1zZWN1cmUtcG9ydGFsMB4XDTE2MDQwMTA4MDA0MVoXDTI2MDQwMTA4MDIyMVowGDEWMBQGA1UEAwwNc2VjdXJlLXBvcnRhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJa4GixpmzP511AmI0eLPLORyJwXS8908MUvdG3hmh8jMOIhe28XjIFeZSY09vFxh22F2SUMjxU/B2Hw4PDJUkebuNR7rXhOIYCJAo6eEZzjSBY/wngFtfm74zJ/eLCobBtDvIld7jobdHTfE1Oz9+GzvtG0k7cm7ubrLT0J4I1UsFZj3b//3wa+O0vNaTwHC1Jz/m59VbtXqyO4xEzIdl416cnGCmEmk5qd5h1de2UoLi/CTad8HftIJhzN1qhlySzW/9Ha70aYlDH2hiibDsXDTrNaMdaaLik7I8Rv/nIbggysG863PKZo8wknDe62QctH5VYSSktiy4gjSJkGh7ECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAZnnx+AHQ8txugGcFK8gWjildDgk+v31fBHBDvmLQaSzsUaIOJaK4wnlwUI+VfR46HmBXhjlDCobFLUptd+kz0G7xapcIn3b5jLrySUUD7L+LAp1vNOQU4mKhTGS3IEvNB73D3GH9rQ+M3KEcoN3f99fNKqKsUdxbmZqGf4VOQ57PUfLBw4PJJGlROPosBc7ivPRyeYnKekhoCTynq30BAD1FA1BA8ppcY4ZVGADPTAgMJxpglpFY9LiqCwdLAGW1ttnsyIJ7DpT+kybhhk7c+MU7gyQdv8xPnMR0bSCB9hndowgBn5oZ393aMscwMNCzwJ0aWBs1sUyn3X0RIsu9Jg==" + "jwt.credential.certificate" : "MIICqTCCAZECBgFT0Ngs/DANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1zZWN1cmUtcG9ydGFsMB4XDTE2MDQwMTA4MDA0MVoXDTI2MDQwMTA4MDIyMVowGDEWMBQGA1UEAwwNc2VjdXJlLXBvcnRhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJa4GixpmzP511AmI0eLPLORyJwXS8908MUvdG3hmh8jMOIhe28XjIFeZSY09vFxh22F2SUMjxU/B2Hw4PDJUkebuNR7rXhOIYCJAo6eEZzjSBY/wngFtfm74zJ/eLCobBtDvIld7jobdHTfE1Oz9+GzvtG0k7cm7ubrLT0J4I1UsFZj3b//3wa+O0vNaTwHC1Jz/m59VbtXqyO4xEzIdl416cnGCmEmk5qd5h1de2UoLi/CTad8HftIJhzN1qhlySzW/9Ha70aYlDH2hiibDsXDTrNaMdaaLik7I8Rv/nIbggysG863PKZo8wknDe62QctH5VYSSktiy4gjSJkGh7ECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAZnnx+AHQ8txugGcFK8gWjildDgk+v31fBHBDvmLQaSzsUaIOJaK4wnlwUI+VfR46HmBXhjlDCobFLUptd+kz0G7xapcIn3b5jLrySUUD7L+LAp1vNOQU4mKhTGS3IEvNB73D3GH9rQ+M3KEcoN3f99fNKqKsUdxbmZqGf4VOQ57PUfLBw4PJJGlROPosBc7ivPRyeYnKekhoCTynq30BAD1FA1BA8ppcY4ZVGADPTAgMJxpglpFY9LiqCwdLAGW1ttnsyIJ7DpT+kybhhk7c+MU7gyQdv8xPnMR0bSCB9hndowgBn5oZ393aMscwMNCzwJ0aWBs1sUyn3X0RIsu9Jg==", + "exclude.issuer.from.auth.response": "true" } }, { @@ -281,7 +322,8 @@ "/secure-portal-with-custom-session-config/*" ], "attributes" : { - "jwt.credential.certificate" : "MIICqTCCAZECBgFT0Ngs/DANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1zZWN1cmUtcG9ydGFsMB4XDTE2MDQwMTA4MDA0MVoXDTI2MDQwMTA4MDIyMVowGDEWMBQGA1UEAwwNc2VjdXJlLXBvcnRhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJa4GixpmzP511AmI0eLPLORyJwXS8908MUvdG3hmh8jMOIhe28XjIFeZSY09vFxh22F2SUMjxU/B2Hw4PDJUkebuNR7rXhOIYCJAo6eEZzjSBY/wngFtfm74zJ/eLCobBtDvIld7jobdHTfE1Oz9+GzvtG0k7cm7ubrLT0J4I1UsFZj3b//3wa+O0vNaTwHC1Jz/m59VbtXqyO4xEzIdl416cnGCmEmk5qd5h1de2UoLi/CTad8HftIJhzN1qhlySzW/9Ha70aYlDH2hiibDsXDTrNaMdaaLik7I8Rv/nIbggysG863PKZo8wknDe62QctH5VYSSktiy4gjSJkGh7ECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAZnnx+AHQ8txugGcFK8gWjildDgk+v31fBHBDvmLQaSzsUaIOJaK4wnlwUI+VfR46HmBXhjlDCobFLUptd+kz0G7xapcIn3b5jLrySUUD7L+LAp1vNOQU4mKhTGS3IEvNB73D3GH9rQ+M3KEcoN3f99fNKqKsUdxbmZqGf4VOQ57PUfLBw4PJJGlROPosBc7ivPRyeYnKekhoCTynq30BAD1FA1BA8ppcY4ZVGADPTAgMJxpglpFY9LiqCwdLAGW1ttnsyIJ7DpT+kybhhk7c+MU7gyQdv8xPnMR0bSCB9hndowgBn5oZ393aMscwMNCzwJ0aWBs1sUyn3X0RIsu9Jg==" + "jwt.credential.certificate" : "MIICqTCCAZECBgFT0Ngs/DANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1zZWN1cmUtcG9ydGFsMB4XDTE2MDQwMTA4MDA0MVoXDTI2MDQwMTA4MDIyMVowGDEWMBQGA1UEAwwNc2VjdXJlLXBvcnRhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJa4GixpmzP511AmI0eLPLORyJwXS8908MUvdG3hmh8jMOIhe28XjIFeZSY09vFxh22F2SUMjxU/B2Hw4PDJUkebuNR7rXhOIYCJAo6eEZzjSBY/wngFtfm74zJ/eLCobBtDvIld7jobdHTfE1Oz9+GzvtG0k7cm7ubrLT0J4I1UsFZj3b//3wa+O0vNaTwHC1Jz/m59VbtXqyO4xEzIdl416cnGCmEmk5qd5h1de2UoLi/CTad8HftIJhzN1qhlySzW/9Ha70aYlDH2hiibDsXDTrNaMdaaLik7I8Rv/nIbggysG863PKZo8wknDe62QctH5VYSSktiy4gjSJkGh7ECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAZnnx+AHQ8txugGcFK8gWjildDgk+v31fBHBDvmLQaSzsUaIOJaK4wnlwUI+VfR46HmBXhjlDCobFLUptd+kz0G7xapcIn3b5jLrySUUD7L+LAp1vNOQU4mKhTGS3IEvNB73D3GH9rQ+M3KEcoN3f99fNKqKsUdxbmZqGf4VOQ57PUfLBw4PJJGlROPosBc7ivPRyeYnKekhoCTynq30BAD1FA1BA8ppcY4ZVGADPTAgMJxpglpFY9LiqCwdLAGW1ttnsyIJ7DpT+kybhhk7c+MU7gyQdv8xPnMR0bSCB9hndowgBn5oZ393aMscwMNCzwJ0aWBs1sUyn3X0RIsu9Jg==", + "exclude.issuer.from.auth.response": "true" } }, { @@ -292,7 +334,10 @@ "redirectUris": [ "/session-portal/*" ], - "secret": "password" + "secret": "password", + "attributes" : { + "exclude.issuer.from.auth.response": "true" + } }, { "clientId": "session-portal-distributable", @@ -302,7 +347,10 @@ "redirectUris": [ "http://localhost:8580/session-portal-distributable/*" ], - "secret": "password" + "secret": "password", + "attributes" : { + "exclude.issuer.from.auth.response": "true" + } }, { "clientId": "input-portal", @@ -312,7 +360,10 @@ "redirectUris": [ "/input-portal/*" ], - "secret": "password" + "secret": "password", + "attributes" : { + "exclude.issuer.from.auth.response": "true" + } }, { "clientId": "input-portal-no-access-token", @@ -322,7 +373,10 @@ "redirectUris": [ "/input-portal-no-access-token/*" ], - "secret": "password" + "secret": "password", + "attributes" : { + "exclude.issuer.from.auth.response": "true" + } }, { "clientId": "token-min-ttl", @@ -332,7 +386,10 @@ "redirectUris": [ "/token-min-ttl/*" ], - "secret": "password" + "secret": "password", + "attributes" : { + "exclude.issuer.from.auth.response": "true" + } }, { "clientId": "token-refresh", @@ -342,7 +399,10 @@ "redirectUris": [ "/token-refresh/*" ], - "secret": "password" + "secret": "password", + "attributes" : { + "exclude.issuer.from.auth.response": "true" + } }, { "clientId": "third-party", @@ -351,7 +411,10 @@ "/oauth-client/*", "/oauth-client-cdi/*" ], - "secret": "password" + "secret": "password", + "attributes" : { + "exclude.issuer.from.auth.response": "true" + } }, { "clientId": "basic-auth-service", @@ -360,7 +423,10 @@ "enabled": true, "adminUrl": "/basic-auth", "baseUrl": "/basic-auth", - "secret": "password" + "secret": "password", + "attributes" : { + "exclude.issuer.from.auth.response": "true" + } }, { "clientId": "client-secret-jwt-secure-portal", @@ -371,7 +437,10 @@ "redirectUris": [ "/client-secret-jwt-secure-portal/*" ], - "secret": "234234-234234-234234" + "secret": "234234-234234-234234", + "attributes" : { + "exclude.issuer.from.auth.response": "true" + } }, { "clientId": "client-secret-jwt-secure-portal-valid-alg", @@ -382,7 +451,10 @@ "redirectUris": [ "/client-secret-jwt-secure-portal-valid-alg/*" ], - "secret": "234234-234234-234234" + "secret": "234234-234234-234234", + "attributes" : { + "exclude.issuer.from.auth.response": "true" + } } ] } diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/offline-client/offlinerealm.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/offline-client/offlinerealm.json index 4cdd37d1704..b7daf0fdfff 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/offline-client/offlinerealm.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/offline-client/offlinerealm.json @@ -113,7 +113,10 @@ "http://localhost:8180/auth/realms/master/app/*" ], "adminUrl": "http://localhost:8180/auth/realms/master/app/logout", - "secret": "password" + "secret": "password", + "attributes" : { + "exclude.issuer.from.auth.response": "true" + } }, { "clientId" : "third-party", @@ -123,7 +126,10 @@ "redirectUris": [ "http://localhost:8180/app/*" ], - "secret": "password" + "secret": "password", + "attributes" : { + "exclude.issuer.from.auth.response": "true" + } }, { "clientId": "offline-client", @@ -134,7 +140,10 @@ "redirectUris": [ "/offline-client/*" ], - "secret": "secret1" + "secret": "secret1", + "attributes" : { + "exclude.issuer.from.auth.response": "true" + } } ], diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/tenant1-realm.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/tenant1-realm.json index 17a6d10cb44..b57ad5a80a9 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/tenant1-realm.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/tenant1-realm.json @@ -66,7 +66,10 @@ "redirectUris": [ "/multi-tenant/tenant1/*" ], - "secret": "password" + "secret": "password", + "attributes" : { + "exclude.issuer.from.auth.response": "true" + } } ] } diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/tenant2-realm.json b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/tenant2-realm.json index 522af1ad038..14981d901f7 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/tenant2-realm.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/adapter-test/tenant2-realm.json @@ -64,7 +64,10 @@ "redirectUris": [ "/multi-tenant/tenant2/*" ], - "secret": "password" + "secret": "password", + "attributes" : { + "exclude.issuer.from.auth.response": "true" + } } ] }