Skip to main content

Implement Identity Provider (IdP) initiated SSO

IdP-initiated SSO allows users to log into your application directly from their identity provider's portal. While convenient, it poses security risks such as stolen SAML assertions.

In IdP initiated SSO:

  1. The user logs into their identity provider portal and selects your application.
  2. The identity provider sends the user's details as assertions to your application.
  3. Your application validates the assertions, retrieves the user information, and if everything checks out, logs the user in.

IdP initiated SSO
workflow

IdP initiated SSO workflow

Since the login is initiated from the identity provider's portal, this flow is called IdP-initiated SSO.

Security Risks

Stolen SAML Assertions: Attackers can steal these assertions and use them to gain unauthorized access. If an attacker manages to steal these assertions, they can:

  • Inject them into another service provider, gaining access to that user's account
  • Inject them back into your application with altered assertions, potentially elevating their privileges

With a stolen SAML assertion, an attacker can gain access to your application as the compromised user, bypassing the usual authentication process. This compromised behavior is much harder with Service Provider (SP) initiated SSO flow.

How Attackers Steal SAML Assertions

Attackers can steal SAML assertions through various methods:

  • Man-In-The-Middle (MITM) Attacks: Intercepting and replacing the SAML response during transmission.
  • Open Redirect Attacks: Exploiting improper endpoint validation to redirect the SAML response to a malicious server.
  • Leaky Logs and Headers: Sensitive information, including SAML assertions, can be leaked through logs or headers.
  • Browser-Based Attacks: Exploiting browser vulnerabilities to steal SAML assertions

The Challenge for Service Providers

The chief problem with stolen assertions is that everything appears legitimate to the service provider. The message and assertion are valid, issued by the expected identity provider, and signed with the expected key. However, the service provider cannot verify whether the assertions are stolen or not. This makes it difficult to detect and prevent unauthorized access through stolen SAML assertions.

Mitigating Security Risks: Convert IdP-initiated to SP-initiated SSO

Despite the security risks, IdP initiated SSO offers significant convenience to end users, allowing them to easily log into various applications used within their organization. As such, it's important for your application to support it. To support it securely, convert the incoming IdP-initiated request to an SP-initiated SSO flow. Refer the below diagram for the recommended workflow from Scalekit.

Scalekit's recommended workflow for IdP initiated
SSO

Scalekit's recommended workflow for IdP initiated SSO

  1. When Scalekit receives an IdP-initiated SSO request from a customer, it sends a request to your configured default redirect_uri (located in Scalekit Dashboard > API Config > Redirect URIs) with idp_initiated_login included as a request parameter.
https://b2b-app.com/default-redirect-uri
?idp_initiated_login=<encoded_jwt_token>
  1. The idp_initiated_login request parameter is a signed JWT token containing all necessary details to identify the organization, SSO connection, and user information, enabling you to initiate a new authorization request.
{
"organization_id": "org_225336910XXXX588",
"connection_id": "conn_22533XXXXX575236",
"login_hint": "name@example.com",
"exp": 1723042087,
"nbf": 1723041787,
"iat": 1723041787,
"iss": "https://b2b-app.com"
}
  1. You can use any of these three parameters to initiate a new SSO request. Since the user is already logged into their Identity Provider, they are not prompted to authenticate again, providing a seamless experience while addressing potential security vulnerabilities associated with IdP-initiated SSO.
// 1. Default redirect URL is callback with JWT
const { code, error_description, idp_initiated_login } = req.query;

if (error_description) {
return res.status(400).json({ message: error_description });
}


// 2. Decode the JWT
if (idp_initiated_login) {

const {
connection_id,
organization_id,
login_hint,
relay_state
} = await scalekit.getIdpInitiatedLoginClaims(idp_initiated_login);

let options = {};
// Either ONE of the following properties
options["connectionId"] = connection_id
options["organizationId"] = organization_id
options["loginHint"] = login_hint

// 3. Generate Authorization URL
const url = scalekit.getAuthorizationUrl(
<redirect_uri>,
options
)
return res.redirect(url);
}

In case of error, the redirect URI will receive a callback containing the error information as query parameters.

https://b2b-app.com/callback?error=<error_category>&error_description=<details>

Advantages

The advantages of using this approach are:

  • Enhanced Security: Overcomes the security risks of handling IdP-initiated SSO
  • Seamless Experience: The additional redirect is almost instantaneous, providing a smooth user experience

By following these steps, you can support IdP-initiated SSO while maintaining a high level of security for your users


Is this page helpful? Yes No