|
| 1 | +import Availability from '@components/Availability'; |
| 2 | + |
| 3 | +<Availability cloud="comingSoon" oss={false} /> |
| 4 | + |
| 5 | +# IdP-initiated SSO (SAML only) |
| 6 | + |
| 7 | +IdP-initiated SSO is a single sign-on process where the Identity Provider (IdP) primarily controls the authentication flow. This process begins when a user logs into the IdP's platform, such as a company portal or a centralized identity dashboard. Once authenticated, the IdP generates an SAML assertion and directs the user to the Service Provider (SP) to access the application or service. |
| 8 | + |
| 9 | + |
| 10 | + |
| 11 | + |
| 12 | + |
| 13 | +## Risks and considerations |
| 14 | + |
| 15 | +IdP-initiated SSO can introduce several security vulnerabilities that organizations should be aware of. Since the authentication process is initiated by the IdP without a direct request from the user, it can be susceptible to various attacks, including [Cross-Site Request Forgery](https://blog.logto.io/csrf) (CSRF). |
| 16 | + |
| 17 | +This lack of user-initiated authentication can lead to unauthorized access if proper safeguards are not in place. Additionally, the reliance on a single point of authentication increases the risk of a security breach, as compromising the IdP could expose all connected applications. |
| 18 | + |
| 19 | +Therefore, it is highly recommended to use SP-initiated SSO, which provides a more secure and controlled authentication flow, ensuring that users explicitly request access to services. |
| 20 | + |
| 21 | +## Connect IdP-initiated SSO with Logto OIDC applications |
| 22 | + |
| 23 | +Logto as an OpenID Connect (OIDC) provider does not support IdP-initiated SSO. However, you can configure Logto as a SP to support IdP-initiated SSO with your enterprise IdP using SAML. This setup allows you to leverage Logto's authentication capabilities while maintaining the IdP's control over the authentication flow. |
| 24 | + |
| 25 | +By default, this feature is not enabled in Logto. If you need IdP-initiated SSO enabled for your tenant, please [contact our support team](https://logto.io/contact?src=docs.sso). |
| 26 | + |
| 27 | +### Prerequisites |
| 28 | + |
| 29 | +Before configuring IdP-initiated SSO, you need to create a SAML connector first. Navigate to the `Enterprise SSO` section in the Logto console and follow the step-by-step [guide](https://docs.logto.io/docs/recipes/single-sign-on/configure-sso/) to set up a [SAML](https://docs.logto.io/docs/recipes/single-sign-on/configure-sso/saml/) connector with your IdP. |
| 30 | + |
| 31 | +Once the SAML connector is set up, you can enable the SSO sign-in method in the `Sign-in experience` section, and test the SP-initiated SSO flow to ensure that the configuration is correct. Make sure the SP-initiated SSO is working as expected before proceeding with IdP-initiated SSO. |
| 32 | + |
| 33 | +### Enable IdP-initiated SSO |
| 34 | + |
| 35 | +:::note |
| 36 | +By default, this feature is not enabled in Logto. If you need IdP-initiated SSO enabled for your tenant, please [contact our support team](https://logto.io/contact?src=docs.sso). |
| 37 | +::: |
| 38 | + |
| 39 | +Once the IdP-initiated SSO feature is enabled for your tenant, you should see an extra tab in your SAML connector's settings page, called `IdP-initiated SSO`. Enable the `IdP-initiated SSO` toggle to activate the feature for the connector. |
| 40 | + |
| 41 | +### Select the SP application |
| 42 | + |
| 43 | +Unlike SP-initiated SSO, where the authentication flow starts from the SP, IdP-initiated SSO requires a client side SP application to redirect users after the authentication process. You can select the SP application from the list of registered applications in the `Default application` dropdown. |
| 44 | + |
| 45 | +Only `Traditional Web App` and `Single Page App` applications are supported for IdP-initiated SSO. Make sure to select the appropriate application type based on your use case. |
| 46 | + |
| 47 | +:::note |
| 48 | +On you IdP's side, leave the `RelayState` parameter to **EMPTY** for the IdP-initiated SSO flow to work correctly. Logto will handle the redirection based on the default SP application selected. |
| 49 | +::: |
| 50 | + |
| 51 | +## Configure IdP-initiated authentication flow |
| 52 | + |
| 53 | +In order to connect IdP-initiated SAML SSO with OIDC, Logto provides two configuration options to handle the authentication request. |
| 54 | + |
| 55 | +### Option A: Redirect to the default SP application (Recommended) |
| 56 | + |
| 57 | +When the IdP initiates the SSO flow, and sends the SAML assertion to Logto, an IdP-initiated SSO assertion session will be created. Logto will redirect the user to the default SP application to initiate a standard OIDC authentication request at the client side. |
| 58 | + |
| 59 | +```mermaid |
| 60 | +sequenceDiagram |
| 61 | + actor User |
| 62 | + participant IdP as IdP |
| 63 | + participant Logto as Logto |
| 64 | + participant Experience as sign-in experience |
| 65 | + participant SP as Client |
| 66 | +
|
| 67 | + User->>IdP: Log in and select SP application |
| 68 | + IdP->>Logto: Redirect to Logto with SAML assertion |
| 69 | + Logto-->>Logto: Preserve IdP-initiated SSO assertion session |
| 70 | + Logto->>SP: Redirect to default SP application |
| 71 | + SP->>Logto: OIDC authentication request |
| 72 | + Logto->>Experience: Redirect user to sign-in experience |
| 73 | + Experience-->>Logto: Validate IdP-initiated SSO assertion session (silent authentication) |
| 74 | + Logto->>SP: Authenticate and redirect to SP application with authorization code |
| 75 | + SP->>Logto: OIDC token request |
| 76 | + Logto->>SP: token response |
| 77 | + SP->>User: Authenticate user |
| 78 | +``` |
| 79 | + |
| 80 | +To setup this option, select the `Redirect to client for SP-initiated authentication` card in the `IdP-initiated SSO` tab of the SAML connector settings. |
| 81 | + |
| 82 | + |
| 83 | + |
| 84 | +1. Provide a `Client redirect URL` to redirect the user to the default SP application after the IdP-initiated SSO flow. Logto will redirect the user to this URL with the `?ssoConnectorId={connectorId}` query parameter appended to the URL. The client application should handle the redirection and initiate the OIDC authentication request. (We recommend using a dedicated route or page in your client application to handle the IdP-initiated SSO authentication request.) |
| 85 | + |
| 86 | +2. Handle the OIDC authentication request at the client side using the `ssoConnectorId` query parameter to identify the SAML connector that initiated the IdP-initiated SSO authentication flow. |
| 87 | + |
| 88 | +3. Pass the [direct sign-in](https://docs.logto.io/docs/references/openid-connect/authentication-parameters/#direct-sign-in) authentication parameter in the sign-in request to Logto to complete the SSO authentication flow. |
| 89 | + |
| 90 | +```typescript |
| 91 | +// React example |
| 92 | +import { Prompt, useLogto } from '@logto/react'; |
| 93 | +import { useEffect } from 'react'; |
| 94 | +import { useNavigate, useSearchParams } from 'react-router-dom'; |
| 95 | + |
| 96 | +const SsoDirectSignIn = () => { |
| 97 | + const { signIn } = useLogto(); |
| 98 | + const [searchParams] = useSearchParams(); |
| 99 | + |
| 100 | + useEffect(() => { |
| 101 | + const ssoConnectorId = searchParams.get('ssoConnectorId'); |
| 102 | + if (ssoConnectorId) { |
| 103 | + void signIn({ |
| 104 | + redirectUri, |
| 105 | + prompt: Prompt.Login, |
| 106 | + directSignIn: { |
| 107 | + method: 'sso', |
| 108 | + target: ssoConnectorId, |
| 109 | + }, |
| 110 | + }); |
| 111 | + } |
| 112 | + }, [searchParams, signIn]); |
| 113 | +}; |
| 114 | +``` |
| 115 | + |
| 116 | +- `redirectUri`: The `redirect_uri` to redirect the user after the OIDC authentication flow is completed. |
| 117 | +- `prompt=login`: Forces the user to log in using the IdP-initiated SSO identity. |
| 118 | +- `directSignIn=sso:{connectorId}`: Specifies the direct sign-in method as `sso` and the target SAML connector ID. This parameter will trigger the SSO authentication flow directly without showing the login page. User will be automatically authenticated using the preserved IdP-initiated SSO assertion session if the connector ID matches and the session is valid. |
| 119 | + |
| 120 | +This method ensures that the authentication flow is secure and follows the standard OIDC protocol, while maintaining the IdP's control over the authentication process. Client app can take advantage of the IdP-initiated SSO assertion session to authenticate the user without additional login steps, while keeping the authentication flow secure and controlled. The client app can still validate the `state` and `PKCE` parameters to ensure the authentication request is secure. |
| 121 | + |
| 122 | +:::note |
| 123 | +This method is available for both `Traditional Web App` and `Single Page App` applications. And it is recommended for all the use cases. |
| 124 | +::: |
| 125 | + |
| 126 | +### Option B: Directly authenticate the user with IdP-initiated SSO |
| 127 | + |
| 128 | +For certain circumstances, SP may not be able to handle the IdP-initiated SSO callback and initiate the OIDC authentication request. In this case, Logto provides an alternative option to directly authenticate the user with the IdP-initiated SSO assertion session. |
| 129 | + |
| 130 | +This option is considered less secure and not recommended. The authentication flow bypasses the standard OIDC protocol. As the authentication request is initiated by the IdP, the client app may not be able to validate the authentication request securely. E.g. the client app can not validate the `state` and `PKCE` parameters to ensure the authentication request is secure. |
| 131 | + |
| 132 | +:::warning |
| 133 | +This method is not available for `Single Page App` applications, as it requires the client app to handle the authentication request securely using the `PKCE` parameter. If you need to implement IdP-initiated SSO for a SPA application, please use the above option instead. |
| 134 | +::: |
| 135 | + |
| 136 | +```mermaid |
| 137 | + sequenceDiagram |
| 138 | +
|
| 139 | + actor User |
| 140 | + participant IdP as IdP |
| 141 | + participant Logto as Logto |
| 142 | + participant Experience as sign-in experience |
| 143 | + participant SP as Client |
| 144 | +
|
| 145 | + User->>IdP: Log in and select SP application |
| 146 | + IdP->>Logto: Redirect to Logto with SAML assertion |
| 147 | + Logto-->>Logto: Preserve IdP-initiated SSO assertion session |
| 148 | + Logto-->>Logto: Initiate OIDC authentication request |
| 149 | + Logto->>Experience: Redirect user to sign-in experience |
| 150 | + Experience-->>Logto: Validate IdP-initiated SSO assertion session (silent authentication) |
| 151 | + Logto->>SP: Authenticate and redirect to SP application with authorization code (No state or PKCE validation) |
| 152 | + SP->>Logto: OIDC token request |
| 153 | + Logto->>SP: token response |
| 154 | + SP->>User: Authenticate user |
| 155 | +``` |
| 156 | + |
| 157 | +To configure this option, select the `Directly sign-in using IdP-initiated SSO` option in the `IdP-initiated SSO` tab of the SAML connector settings. |
| 158 | + |
| 159 | + |
| 160 | + |
| 161 | +1. Select the `Post sign-in redirect URI` to redirect the user back to the client application after successful authentication. This URL will be used as the `redirect_uri` in the OIDC authentication request. The URI must be one of the allowed redirect URIs registered in the client application. |
| 162 | + |
| 163 | + :::note |
| 164 | + It is highly recommended to use a dedicated `redirect URI` for IdP-initiated SSO. Given that the authentication request is unsolicited, the client application should manage the response independently, separate from the standard SP-initiated authentication flow. |
| 165 | + ::: |
| 166 | + |
| 167 | +2. Customize the authorization request parameters if needed using the `Additional authentication parameters` json editor (following the type `Map<string,string>`). |
| 168 | + |
| 169 | + E.g. By default Logto only requests the `openid` and `profile` scopes. You can add additional scopes or parameters to the authentication request. |
| 170 | + |
| 171 | + ```json |
| 172 | + { |
| 173 | + "scope": "email offline_access" |
| 174 | + } |
| 175 | + ``` |
| 176 | + |
| 177 | + - add additional `email` scope to request the user's email address. |
| 178 | + - add `offline_access` scope to request the refresh token. |
| 179 | + |
| 180 | + We also recommend you to provide a custom `state` parameter to validate the authentication response securely. |
| 181 | + |
| 182 | + ```json |
| 183 | + { |
| 184 | + "state": "custom-state-value" |
| 185 | + } |
| 186 | + ``` |
| 187 | + |
| 188 | + The client app should validate the `state` parameter in the authorization code response to ensure the authentication request is valid. |
0 commit comments