Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions docs/backends/openid.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@ the first transaction; the earlier callback is rejected. Unsolicited assertions
are rejected, including for anonymous users. Always use the normal backend
initiation path.

When the framework supports restoring sessions, only a session identifier carried
by the provider-signed ``openid.return_to`` can select that session. Missing or
mismatched state requires the user to restart authentication.
The signed ``openid.return_to`` cannot select a session. OpenID callbacks use
the browser's current session and reject the former session identifier in the
return URL or callback. Missing or mismatched state requires the user to
restart authentication. In-progress logins started before this change must
also restart.

The generic ``openid`` backend remains provider-selectable because the
application user supplies its provider URL. Backends configured for one
Expand All @@ -51,9 +53,9 @@ Custom backends with a fixed ``URL`` receive provider binding automatically.
A custom backend that computes a fixed-provider URL in ``openid_url()`` must
override ``requires_openid_provider_binding()`` to return ``True``. Provider
discovery URLs and discovered provider endpoints must use HTTPS; there is no
setting to disable this validation. Custom strategies that implement session
restoration must restore the complete OpenID session state and update
session-derived pipeline arguments, including the authenticated user.
setting to disable this validation. Custom backends must validate callbacks
against the initiating browser session. The old strategy session-restoration
methods have been removed; custom backends that used them must migrate.

Custom backends overriding authorization URL or HTML generation must include
the transaction value in the provider-signed return URL, for example by calling
Expand Down
52 changes: 26 additions & 26 deletions docs/backends/saml.rst
Original file line number Diff line number Diff line change
Expand Up @@ -306,32 +306,32 @@ usually return the response with a cross-site POST request. Django's default
``SESSION_COOKIE_SAMESITE = "Lax"`` setting prevents the session cookie from
being sent with that request.

``social-auth-app-django`` preserves the server-side session identifier in
SAML ``RelayState`` and restores the session before validating the response.
The restored session key is rotated before continued use; do not override
restoration in a way that retains the old key or changes the initiating user.
Use a current ``social-auth-app-django`` release and a server-side Django
session engine. In multi-instance deployments, every instance that can handle
the login or callback must use the same session storage. Database and cached
database engines meet this requirement when configured with shared services.
The cache engine must use a shared backend, and the file engine is suitable
only for a single instance or a shared filesystem. The signed-cookie session
backend cannot restore session changes through this mechanism.

Also verify that the login was initiated by the same browser, that the Identity
Provider returns ``RelayState`` unchanged, and that only one SAML login is
active for the Identity Provider in that browser session.

If the callback carries an authenticated Django session for a different user
than the session restored from ``RelayState``, ``social-auth-app-django``
rejects it with a ``user_mismatch`` error and preserves the current session.
Restart the SAML login while signed in as the account that should receive the
association.

As a workaround, ``SESSION_COOKIE_SAMESITE`` can be set to ``"None"`` so the
cookie is sent with the cross-site POST. This requires secure HTTPS cookies and
reduces the protection provided by the SameSite policy, so prefer server-side
session restoration.
``social-auth-core`` first returns a short page on the application origin.
That page automatically reposts the SAML response to the completion endpoint;
the browser's SameSite=Lax session cookie accompanies the second POST. If
automatic submission is blocked, the user can select **Continue signing in**.
The backend then checks the signed response against the AuthnRequest in that
browser session. Use ``social-auth-core`` 7.0.0 or later. Integrations with
custom strategy responses must support the headers described in
:doc:`Strategies <../strategies>`. The older session identifier in
``RelayState`` is ignored. In-progress SAML logins started before upgrading
must restart.

Verify that login was initiated by the same browser and that only one SAML
login is active for the Identity Provider in that browser session. Browser
policies blocking automatic form submission may require the user to select
the continuation button.

SAML responses without a matching SP AuthnRequest are rejected by default.
Deployments that require IdP-initiated SSO can set
``SOCIAL_AUTH_SAML_ALLOW_IDP_INITIATED = True``. This accepts unsolicited
signed responses for anonymous browsers and therefore permits login CSRF:
someone with a trusted IdP account can cause another anonymous browser to
sign in as them. Do not enable it where browser-bound login is required.

``SESSION_COOKIE_SAMESITE = "None"`` also sends the cookie with the initial
cross-site POST, but requires secure HTTPS cookies and reduces SameSite
protection. The browser return page works with the default ``"Lax"`` setting.

**Error: "Missing needed parameter first_name (configured by attr_first_name)"**

Expand Down
2 changes: 1 addition & 1 deletion docs/security.rst
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ Review the selected backend's limits, especially :doc:`backends/telegram`,
:doc:`backends/vk` and :doc:`backends/odnoklassnikiru`.

For Django, see :doc:`configuration/django` for protected routes and launch
bridges, :doc:`backends/saml` for cross-site session restoration, and
bridges, :doc:`backends/saml` for the SAML browser return flow, and
:ref:`partial-pipeline` for confirmation and template requirements.

.. _oauth2-transaction-state:
Expand Down
11 changes: 11 additions & 0 deletions docs/strategies.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ Session::
"""Pop session value for given key"""
raise NotImplementedError('Implement in subclass')

``get_session_id()`` and ``restore_session()`` have been removed from the
strategy interface. Callbacks must use the initiating browser's session;
custom backends that used these methods need to migrate to browser-bound
correlation.


Settings::

Expand All @@ -76,6 +81,12 @@ Responses::
"""Render given template or raw html with given context"""
raise NotImplementedError('Implement in subclass')

``BaseStrategy.html_with_headers(content, headers)`` is a required strategy
hook for returning HTML with the specified HTTP headers. SAML POST callbacks
use it for a protected browser return page. Integrations must implement this
hook using their framework's response API. A custom strategy without the hook
fails closed during SAML completion. The Django strategy implements it.


Effective pipeline request data
-------------------------------
Expand Down
Loading