diff --git a/packages/core/src/routes/authn.ts b/packages/core/src/routes/authn.ts index edbb5763a..d039ad5cc 100644 --- a/packages/core/src/routes/authn.ts +++ b/packages/core/src/routes/authn.ts @@ -1,6 +1,6 @@ import type { ConnectorSession } from '@logto/connector-kit'; import { ConnectorError, ConnectorErrorCodes, ConnectorType } from '@logto/connector-kit'; -import { jsonObjectGuard } from '@logto/schemas'; +import { jsonObjectGuard, SsoAuthenticationQueryKey } from '@logto/schemas'; import { z } from 'zod'; import RequestError from '#src/errors/RequestError/index.js'; @@ -211,7 +211,7 @@ export default function authnRoutes( const idpInitiatedAuthConfig = await queries.ssoConnectors.getIdpInitiatedAuthConfigByConnectorId(connectorId); - // No IdP initiated auth config found + // IdP initiated SSO flow is not enabled for the current connector. assertThat( idpInitiatedAuthConfig, new RequestError({ @@ -235,7 +235,28 @@ export default function authnRoutes( overwrite: true, }); - // TODO: redirect to SSO direct sign-in flow + const { autoSendAuthorizationRequest, clientIdpInitiatedAuthCallbackUri } = + idpInitiatedAuthConfig; + + // Redirect to the client side callback URI if the autoSendAuthorizationRequest is disabled. + // Client side will generate and verify the state to prevent CSRF attack. + if (!autoSendAuthorizationRequest) { + assertThat( + clientIdpInitiatedAuthCallbackUri, + new RequestError( + 'single_sign_on.idp_initiated_authentication_client_callback_uri_not_found' + ) + ); + + const url = new URL(clientIdpInitiatedAuthCallbackUri); + url.searchParams.append(SsoAuthenticationQueryKey.SsoConnectorId, connectorId); + + ctx.redirect(url.toString()); + + return; + } + + // Generate the OIDC authorization request URL for the IdP initiated SSO flow. const signInUrl = await ssoConnectorsLibrary.getIdpInitiatedSamlSsoSignInUrl( envSet.oidc.issuer, idpInitiatedAuthConfig diff --git a/packages/phrases/src/locales/en/errors/single-sign-on.ts b/packages/phrases/src/locales/en/errors/single-sign-on.ts index d0bd363a8..baf3f4103 100644 --- a/packages/phrases/src/locales/en/errors/single-sign-on.ts +++ b/packages/phrases/src/locales/en/errors/single-sign-on.ts @@ -9,6 +9,8 @@ const single_sign_on = { 'Invalid application type. Only {{type}} applications are allowed.', idp_initiated_authentication_redirect_uri_not_registered: 'The redirect_uri is not registered. Please check the application settings.', + idp_initiated_authentication_client_callback_uri_not_found: + 'The client IdP-initiated authentication callback URI is not found. Please check the connector settings.', }; export default Object.freeze(single_sign_on); diff --git a/packages/schemas/src/types/sso-connector.ts b/packages/schemas/src/types/sso-connector.ts index e3a9bb073..443ba1d44 100644 --- a/packages/schemas/src/types/sso-connector.ts +++ b/packages/schemas/src/types/sso-connector.ts @@ -88,3 +88,7 @@ export const ssoConnectorWithProviderConfigGuard = SsoConnectors.guard ); export type SsoConnectorWithProviderConfig = z.infer; + +export enum SsoAuthenticationQueryKey { + SsoConnectorId = 'ssoConnectorId', +}