crewjam / saml

SAML library for go
BSD 2-Clause "Simplified" License
969 stars 435 forks source link

Advice on validating InResponseTo in a distributed system #488

Open OscarVanL opened 1 year ago

OscarVanL commented 1 year ago

Hi,

I have a common Kuberentes architecture where I have several pods (instances) of each server. The pod that a HTTP request is sent to by the load balancer is nondeterministic, meaning if any service requires state, it must live in a database, or redis, or similar.

In practice, this causes the following error when SAML sign-ins are performed:

`InResponseTo` does not match any of the possible request IDs (expected [])

this is because (based on your explanation here) the DefaultRequestTracker's CookieRequestTracker is stateful, there is a locally stored list of tracked request indexes, but the pod that started the auth flow is not necessarily the same one that will handle the SAML response.

My usage pattern is not IDP-initiated, so my requests always include the InResponseTo field. Therefore, I will need to lookup the list of possibleRequestIDs from a shared resource every time, and also make the RequestTracker store the signed cookie in a shared resource.

Do you have any advice on how to do this? I expect I will need to make my own RequestTracker interface implementation that performs the necessary redis/DB operations along with all the existing logic.

OscarVanL commented 1 year ago

Actually, reading the library code further makes me think that the InResponseTo field contains an ID that maps to a claim inside the JWT generated by signedTrackedRequest and embedded in the cookies as saml_<request_index>.

This (as far as I understand) would make the SAML request's state self-contained, so the problem I describe above is not infact a problem.

I assume the problem in the error log I provided above is just that the saml_<request_index> cookie has gone missing somewhere?

Am I right in thinking the whole redirect state is self-contained? If so, that's a neat solution!