elastic / kibana

Your window into the Elastic Stack
https://www.elastic.co/products/kibana
Other
19.6k stars 8.22k forks source link

Support concurrent SP-initiated SAML login attempts #199188

Open azasypkin opened 4 hours ago

azasypkin commented 4 hours ago

Summary

[!NOTE] This issue specifically focuses on SAML, as it’s much more widely used in our offering compared to OpenID Connect (OIDC), but we may eventually want to support concurrent login attempts for OIDC as well (this will likely require changes in ES as well).

When a user initiates a SAML handshake from Kibana, we call the SAML prepare authentication API under the hood and store the returned unique identifier for the SAML request in the unauthenticated intermediate session:

Image

Once the user finishes the SAML handshake in the Identity Provider (IdP) and returns to Kibana with the SAML response, we forward it to the SAML authenticate API along with the SAML request ID extracted from the cookie:

Image

If the login succeeds, we invalidate the intermediate session with the SAML request ID and create a new one linked to the authenticated user identity.

The issue with this approach is that when a user initiates multiple login attempts — for example, when a user without an active session opens or refreshes multiple Kibana tabs at the same time — all these tabs initiate a new SAML handshake and compete for the single intermediate session and cookie. As a result, the last tab that initiated the SAML handshake “wins”, since only its request ID is persisted in the intermediate session. All other tabs will end up with "Unexpected authentication error" and will require user to manually refresh tab to pick up the existing Kibana session.

One way to solve this would be to maintain multiple SAML request IDs within the same intermediate session, which we can then send to the SAML authenticate API along with whatever SAML response the user provides. The API accepts multiple SAML request IDs. Whenever we successfully authenticate a user, we’d transfer the list of request IDs from the intermediate unauthenticated session to the authenticated one, allowing the user to override the session from another tab if they choose to.

We should also limit the number of SAML request IDs we store in a single intermediate session, say up to 50 (it’s pretty common to have tens of tabs open at the same time these days). Any new ID will then displace the oldest one.

[!WARNING] It’s not clear if we can support IdP-initiated login attempts for a user who already has an intermediate session from the SP-initiated login attempt, since we’d be providing the SAML response without the associated request ID, along with the list of SAML request IDs from the intermediate session. We’ll need to check with the ES team for the options or try to recognize IdP initiated login and don't send any SAML request IDs.

Related to: https://github.com/elastic/kibana/issues/112549

elasticmachine commented 4 hours ago

Pinging @elastic/kibana-security (Team:Security)