djangosaml2: [SameSite Cookie] Session not cleared on logout and unsolicited response Error

I’ve setup a djangosaml2 application where I successfully can login using ADFS. When I logout I get no error but as soon as I go to the login page again I’m automatically signed in to the same user without any chance to change user.

I receive no error when logging out, I get a LogoutResponse with the following status so it doesn’t look like anything has gone wrong:

<samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" /></samlp:Status>

Is there something I must configure in the settings for djangosaml2 or is there something that must be done on the ADFS side?

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 30 (20 by maintainers)

Most upvoted comments

Would you be able to submit a PR with your previous commit and put out a bug fix release on PyPi? Again submitting a public PR for this on my side might raise some intellectual property ownership concerns regarding my current contract so I’d prefer if you did it.

@Rjevski I think that it would a good moment to get your contribution in a material PR 😃 Pleasure to work with you.

I’d should have also a geenral refactor of uniauth here: https://github.com/UniversitaDellaCalabria/uniAuth

take a look if you’re interested in a SAML2 IdP, I think that a skilled analyst as you would be important to keep closer 👍

Doing tests with more attention I agree that even if we patched SLO the unsolicited response errors still persist, when entities belonghing to different domain names interacts each other.

This mean that @Rjevski is completely right and we should move a separate session handling with a SameSite=none cookie, related to the SAML session. I’ll do this in the branch samesite_slo_wa

Code coverage and better testing might help somewhere else, but in this case when talking about SameSite-related cookie issues, unit tests are unlikely to catch it unless you wanted to replicate the entire browser’s behavior in the unit test. In a standard test using the Django test client, the cookie would be sent just fine because SameSite is irrelevant and the test client has no concept of first-party/third-party requests anyway.

In addition, I realized what you purposed, split the session handling SAML2 and django. This is a good solution. Before going that way I’d prefer to build something durable for the future, I’m facing that djangosaml2 have unit test but not code coverage.

I opened an issue for this, that’s the solution to see how this bug can be raised and how to cover it with unit tests. Hope you agree.

At last but not least, tell me if you’re ready to purpose a PR for this bug, I could deal with code coverage in parallel

I’d like to suggest you reopen this, I am noticing the same issue with a different IdP and it’s definitely not got anything to do with the IdP immediately logging me back in (the logout works and I end up logged out of the IdP so no chance for it to automatically log me back in, and even force_authn doesn’t change anything).

The problem is that in the logout view, we seem to forget calling auth.logout(request) if SP-initiated logout is indeed supported (we do call it otherwise though). Instead we redirect to the IdP’s logout URL as we’re supposed to, however we still have a valid, logged-in Django session. At that point I am not sure if there is value in keeping the Django session logged in (so far it doesn’t look like it, and as such we should probably log-out the local session already), however all is not lost yet - we’ll have another opportunity to logout the local session.

After being redirected/POSTed to the IdP and it does its logout flow on its side, it redirects back to the SP’s logout endpoint (saml2_ls_post), which eventually calls the built-in Django logout function. However, due to SameSite restrictions on the session cookie (similar to this other issue), the Django logout doesn’t do anything because there is no session to actually log out - the session cookie was not submitted due to SameSite restrictions. At this point we’ve wasted our last opportunity to logout the local session.

Solutions:

  1. Look into why we don’t just logout the Django session to begin with before even redirecting/POSTing to the IdP’s logout endpoint, and if there are no reasons against it then just logout the session there.

  2. As mentioned in the other issue, a solution for the SameSite problem is needed anyway, a separate cookie only for SAML-related things that would have the proper SameSite settings and thus would successfully be sent even for IdP-initiated POSTs. In that case the separate session for that cookie should contain a reference to the real Django session so during logout we can retrieve that session indirectly (since we don’t have the cookie for that session in the request directly) and log it out.

  3. Only use redirect bindings which should not be affected by SameSite cookie restrictions if such a thing is possible (my IdP doesn’t seem to support anything but HTTP POST bindings for logout)