Skip to content

User specified hostnames for redirect #148

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
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
18 changes: 18 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,24 @@ If you want to allow several authentication mechanisms in your project
you should set the LOGIN_URL option to another view and put a link in such
view to the ``/saml2/login/`` view.

Handling Post-Login Redirects
-----------------------------
It is often desireable for the client to maintain the URL state (or at least manage it) so that
the URL once authentication has completed is consistent with the desired application state (such
as retaining query parameters, etc.) By default, the HttpRequest objects get_host() method is used
to determine the hostname of the server, and redirect URL's are allowed so long as the destination
host matches the output of get_host(). However, in some cases it becomes desireable for additional
hostnames to be used for the post-login redirect. In such cases, the setting::

SAML_ALLOWED_HOSTS = []

May be set to a list of allowed post-login redirect hostnames (note, the URL components beyond the hostname
may be specified by the client - typically with the ?next= parameter.)

In the absence of a ?next= parameter, the LOGIN_REDIRECT_URL setting will be used (assuming the destination hostname
either matches the output of get_host() or is included in the SAML_ALLOWED_HOSTS setting)


Preferred Logout binding
------------------------
Use the following setting to choose your preferred binding for SP initiated logout requests::
Expand Down
19 changes: 17 additions & 2 deletions djangosaml2/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,16 @@ def login(request,
came_from = settings.LOGIN_REDIRECT_URL

# Ensure the user-originating redirection url is safe.
if not is_safe_url(url=came_from, allowed_hosts={request.get_host()}):
# By setting SAML_ALLOWED_HOSTS in settings.py the user may provide a list of "allowed"
# hostnames for post-login redirects, much like one would specify ALLOWED_HOSTS .
# If this setting is absent, the default is to use the hostname that was used for the current
# request.
saml_allowed_hosts = set(getattr(settings, 'SAML_ALLOWED_HOSTS', [request.get_host()]))

if not is_safe_url(url=came_from, allowed_hosts=saml_allowed_hosts):
came_from = settings.LOGIN_REDIRECT_URL


# if the user is already authenticated that maybe because of two reasons:
# A) He has this URL in two browser windows and in the other one he
# has already initiated the authenticated session.
Expand Down Expand Up @@ -348,7 +355,15 @@ def assertion_consumer_service(request,
if not relay_state:
logger.warning('The RelayState parameter exists but is empty')
relay_state = default_relay_state
if not is_safe_url(url=relay_state, allowed_hosts={request.get_host()}):

# Ensure the user-originating redirection url is safe.
# By setting SAML_ALLOWED_HOSTS in settings.py the user may provide a list of "allowed"
# hostnames for post-login redirects, much like one would specify ALLOWED_HOSTS .
# If this setting is absent, the default is to use the hostname that was used for the current
# request.
saml_allowed_hosts = set(getattr(settings, 'SAML_ALLOWED_HOSTS', [request.get_host()]))

if not is_safe_url(url=relay_state, allowed_hosts=saml_allowed_hosts):
relay_state = settings.LOGIN_REDIRECT_URL
logger.debug('Redirecting to the RelayState: %s', relay_state)
return HttpResponseRedirect(relay_state)
Expand Down