Align admin console for client for backchannel and frontchannel logout

closes #10138

Signed-off-by: mposolda <mposolda@gmail.com>

Co-authored-by: Erik Jan de Wit <edewit@redhat.com>
Signed-off-by: Marek Posolda <mposolda@gmail.com>
This commit is contained in:
mposolda 2024-10-17 19:30:52 +02:00 committed by Marek Posolda
parent 049121f41e
commit dbcb3151a9
4 changed files with 46 additions and 10 deletions

View file

@ -94,10 +94,12 @@ There will be also one item on the consent screen about this client itself.
[[_front-channel-logout]]
*Front channel logout*:: If *Front Channel Logout* is enabled, the application should be able to log out users through the front channel as per link:https://openid.net/specs/openid-connect-frontchannel-1_0.html[OpenID Connect Front-Channel Logout] specification. If enabled, you should also provide the `Front-Channel Logout URL`.
*Front-channel logout URL*:: URL that will be used by {project_name} to send logout requests to clients through the front-channel.
*Front-channel logout URL*:: URL that will be used by {project_name} to send logout requests to clients through the front-channel. If not provided, it defaults to the Home URL. This option is applicable just if `Front channel logout` option is ON.
*Front-channel logout session required*:: Specifies whether a sid (session ID) and iss (issuer) parameters are included in the Logout request when the Front-channel Logout URL is used.
[[_back-channel-logout-url]]
*Backchannel logout URL*:: URL that will cause the client to log itself out when a logout request is sent to this realm (via end_session_endpoint). If omitted, no logout requests are sent to the client.
*Backchannel logout URL*:: URL that will cause the client to log itself out when a logout request is sent to this realm (via end_session_endpoint). The logout is done by sending logout token as specified in the OIDC Backchannel logout specification. If omitted, the logout request might be sent to the specified `Admin URL` (if configured) in the format specific to {project_name} adapters. If even `Admin URL` is not configured, no logout request will be sent to the client. This option is applicable just if `Front channel logout` option is OFF.
*Backchannel logout session required*::
Specifies whether a session ID Claim is included in the Logout Token when the *Backchannel Logout URL* is used.

View file

@ -45,8 +45,11 @@ export default class CreateClientPage extends CommonPage {
'[for="kc-frontchannelLogout-switch"] > .pf-v5-c-switch__toggle';
#frontChannelLogoutSwitchInput = "#kc-frontchannelLogout-switch";
#frontChannelLogoutInput = "frontchannelLogoutUrl";
#frontChannelLogoutSessionRequiredSwitchInput =
"#attributes\\.frontchannel🍺logout🍺session🍺required";
#backChannelLogoutInput = "backchannelLogoutUrl";
#backChannelLogoutRequiredSwitchInput = "#backchannelLogoutSessionRequired";
#backChannelLogoutSessionRequiredSwitchInput =
"#backchannelLogoutSessionRequired";
#backChannelLogoutRevoqueSwitch =
'.pf-v5-c-form__group-control [for="backchannelLogoutRevokeOfflineSessions"] > .pf-v5-c-switch__toggle';
#backChannelLogoutRevoqueSwitchInput =
@ -268,17 +271,29 @@ export default class CreateClientPage extends CommonPage {
}
checkLogoutSettingsElements() {
cy.get(this.#backChannelLogoutRevoqueSwitch).scrollIntoView();
cy.get(this.#frontChannelLogoutSessionRequiredSwitchInput).scrollIntoView();
cy.get(this.#frontChannelLogoutSwitchInput).should("not.be.disabled");
cy.findByTestId(this.#frontChannelLogoutInput).should("not.be.disabled");
cy.get(this.#frontChannelLogoutSessionRequiredSwitchInput).should(
"not.be.disabled",
);
cy.findByTestId(this.#backChannelLogoutInput).should("not.exist");
cy.get(this.#backChannelLogoutSessionRequiredSwitchInput).should(
"not.exist",
);
cy.get(this.#backChannelLogoutRevoqueSwitchInput).should("not.exist");
cy.get(this.#frontChannelLogoutSwitch).click();
cy.findByTestId(this.#frontChannelLogoutInput).should("not.exist");
cy.get(this.#frontChannelLogoutSessionRequiredSwitchInput).should(
"not.exist",
);
cy.findByTestId(this.#backChannelLogoutInput).should("not.be.disabled");
cy.get(this.#backChannelLogoutRequiredSwitchInput).should(
cy.get(this.#backChannelLogoutSessionRequiredSwitchInput).should(
"not.be.disabled",
);
cy.get(this.#backChannelLogoutRevoqueSwitchInput).should("not.be.disabled");
cy.get(this.#frontChannelLogoutSwitch).click();
cy.findByTestId(this.#frontChannelLogoutInput).should("not.exist");
cy.get(this.#frontChannelLogoutSwitch).click();
cy.findByTestId(this.#frontChannelLogoutInput).should("not.be.disabled");

View file

@ -471,7 +471,7 @@ eventTypes.TOKEN_EXCHANGE.description=Token exchange
continue=Continue
editProvider=Edit provider
included.client.audience.label=Included Client Audience
backchannelLogoutUrlHelp=URL that will cause the client to log itself out when a logout request is sent to this realm (via end_session_endpoint). If omitted, no logout request will be sent to the client is this case.
backchannelLogoutUrlHelp=URL that will cause the client to log itself out when a logout request is sent to this realm (via end_session_endpoint). The logout is done by sending logout token as specified in the OIDC Backchannel logout specification. If omitted, the logout request might be sent to the specified 'Admin URL' (if configured) in the format specific to Keycloak/RH-SSO adapters. If even 'Admin URL' is not configured, no logout request will be sent to the client.
updateScopeSuccess=Authorization scope successfully updated
userInfoResponseEncryptionKeyManagementAlgorithmHelp=JWA Algorithm used for key management in encrypting User Info Endpoint responses. This option is needed if you want encrypted User Info Endpoint responses. If left empty, User Info Endpoint responses are not encrypted.
authnContextDeclRefsHelp=Ordered list of requested AuthnContext DeclRefs.
@ -1011,6 +1011,8 @@ useRealmRolesMappingHelp=If true, then LDAP role mappings will be mapped to real
forwardParameters=Forwarded query parameters
isAccessTokenJWTHelp=The Access Token received from the Identity Provider is a JWT and its claims will be accessible for mappers.
frontchannelLogoutUrl=Front-channel logout URL
frontchannelLogoutSessionRequired=Front-channel logout session required
frontchannelLogoutSessionRequiredHelp=Specifying whether a sid (session ID) and iss (issuer) parameters are included in the Logout request when the Front-channel Logout URL is used.
testConnectionHint.withoutEmailAction=Configure e-mail address
webAuthnUpdateError=Could not update webauthn policies due to {{error}}
paginationHelp=Whether the LDAP server supports pagination
@ -2490,6 +2492,7 @@ contentSecurityPolicy=Content-Security-Policy
client-uris-must-match.tooltip=If on, all Client URIs (Redirect URIs and others) are allowed just if they match some trusted host or domain.
off=Off
frontchannelLogoutHelp=When true, logout requires a browser redirect to client. When false, server performs a background invocation for logout.
frontchannelLogoutOIDCHelp=When true, logout requires a browser to send the request to the client to configured Front-channel logout URL as specified in the OIDC Front-channel logout specification. When false, server can perform a background invocation for logout as long as either the Backchannel-logout URL is configured or Admin URL is configured.
updateSuccess=Provider successfully updated
hide=Hide
isMandatoryInLdapHelp=If true, attribute is mandatory in LDAP. Hence if there is no value in Keycloak DB, the empty value will be set to be propagated to LDAP.

View file

@ -3,6 +3,7 @@ import { Controller, useFormContext } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { HelpItem, TextControl } from "@keycloak/keycloak-ui-shared";
import { DefaultSwitchControl } from "../../components/SwitchControl";
import { FixedButtonsGroup } from "../../components/form/FixedButtonGroup";
import { FormAccess } from "../../components/form/FormAccess";
import { useAccess } from "../../context/access/Access";
@ -29,6 +30,10 @@ export const LogoutPanel = ({
const protocol = watch("protocol");
const frontchannelLogout = watch("frontchannelLogout");
const frontchannelLogoutTooltip =
protocol === "openid-connect"
? "frontchannelLogoutOIDCHelp"
: "frontchannelLogoutHelp";
return (
<FormAccess
@ -40,7 +45,7 @@ export const LogoutPanel = ({
label={t("frontchannelLogout")}
labelIcon={
<HelpItem
helpText={t("frontchannelLogoutHelp")}
helpText={t(frontchannelLogoutTooltip)}
fieldLabelId="frontchannelLogout"
/>
}
@ -78,7 +83,18 @@ export const LogoutPanel = ({
}}
/>
)}
{protocol === "openid-connect" && (
{protocol === "openid-connect" && frontchannelLogout && (
<DefaultSwitchControl
name={convertAttributeNameToForm<FormFields>(
"attributes.frontchannel.logout.session.required",
)}
defaultValue="true"
label={t("frontchannelLogoutSessionRequired")}
labelIcon={t("frontchannelLogoutSessionRequiredHelp")}
stringify
/>
)}
{protocol === "openid-connect" && !frontchannelLogout && (
<>
<TextControl
data-testid="backchannelLogoutUrl"