We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
2 parents fb5554c + 4fe6cc3 commit 1c5ec54Copy full SHA for 1c5ec54
4 files changed
djangosaml2/middleware.py
@@ -26,6 +26,8 @@ def process_response(self, request, response):
26
session every time, save the changes and set a session cookie or delete
27
the session cookie if the session has been emptied.
28
"""
29
+ SAMESITE = getattr(settings, "SAML_SESSION_COOKIE_SAMESITE", SAMESITE_NONE)
30
+
31
try:
32
accessed = request.saml_session.accessed
33
modified = request.saml_session.modified
@@ -39,7 +41,7 @@ def process_response(self, request, response):
39
41
self.cookie_name,
40
42
path=settings.SESSION_COOKIE_PATH,
43
domain=settings.SESSION_COOKIE_DOMAIN,
- samesite=SAMESITE_NONE,
44
+ samesite=SAMESITE,
45
)
46
patch_vary_headers(response, ("Cookie",))
47
else:
@@ -74,6 +76,6 @@ def process_response(self, request, response):
74
76
75
77
secure=settings.SESSION_COOKIE_SECURE or None,
78
httponly=settings.SESSION_COOKIE_HTTPONLY or None,
79
80
81
return response
djangosaml2/tests/__init__.py
@@ -1030,3 +1030,31 @@ def test_middleware_cookie_with_expiry(self):
1030
self.assertIsNotNone(cookie["expires"])
1031
self.assertNotEqual(cookie["expires"], "")
1032
self.assertNotEqual(cookie["max-age"], "")
1033
1034
+ def test_middleware_cookie_samesite(self):
1035
+ with override_settings(SAML_SESSION_COOKIE_SAMESITE="Lax"):
1036
+ session = self.get_session()
1037
+ session.save()
1038
+ self.set_session_cookies(session)
1039
1040
+ config_loader_path = "djangosaml2.tests.test_config_loader_with_real_conf"
1041
+ request = RequestFactory().get("/login/")
1042
+ request.user = AnonymousUser()
1043
+ request.session = session
1044
+ middleware = SamlSessionMiddleware(dummy_get_response)
1045
+ middleware.process_request(request)
1046
1047
+ saml_session_name = getattr(
1048
+ settings, "SAML_SESSION_COOKIE_NAME", "saml_session"
1049
+ )
1050
+ getattr(request, saml_session_name).save()
1051
1052
+ response = views.LoginView.as_view(config_loader_path=config_loader_path)(
1053
+ request
1054
1055
1056
+ response = middleware.process_response(request, response)
1057
1058
+ cookie = response.cookies[saml_session_name]
1059
1060
+ self.assertEqual(cookie["samesite"], "Lax")
docs/source/contents/setup.rst
@@ -62,14 +62,18 @@ You can even configure the SAML cookie name as follows::
62
63
SAML_SESSION_COOKIE_NAME = 'saml_session'
64
65
+By default, djangosaml2 will set "SameSite=None" for the SAML session cookie. This value can be configured as follows::
66
67
+ SAML_SESSION_COOKIE_SAMESITE = 'Lax'
68
69
Remember that in your browser "SameSite=None" attribute MUST also
70
have the "Secure" attribute, which is required in order to use "SameSite=None", otherwise the cookie will be blocked, so you must also set::
71
72
SESSION_COOKIE_SECURE = True
73
.. Note::
- djangosaml2 will attempt to set the ``SameSite`` attribute of the SAML session cookie to ``None`` so that it can be
+ djangosaml2 will by default attempt to set the ``SameSite`` attribute of the SAML session cookie to ``None`` so that it can be
used in cross-site requests, but this is only possible with Django 3.1 or higher. If you are experiencing issues with
unsolicited requests or cookies not being sent (particularly when using the HTTP-POST binding), consider upgrading
to Django 3.1 or higher. If you can't do that, configure "allow_unsolicited" to True in pySAML2 configuration.
setup.py
@@ -27,7 +27,7 @@ def read(*rnames):
setup(
name="djangosaml2",
- version="1.5.8",
+ version="1.6.0",
description="pysaml2 integration for Django",
long_description=read("README.md"),
long_description_content_type="text/markdown",
0 commit comments