|
29 | 29 | from django.utils.http import is_safe_url |
30 | 30 | from django.views.decorators.csrf import csrf_exempt |
31 | 31 | from django.views.decorators.http import require_POST |
32 | | -from saml2 import BINDING_HTTP_POST, BINDING_HTTP_REDIRECT |
| 32 | +from saml2 import BINDING_HTTP_REDIRECT, BINDING_HTTP_POST |
| 33 | +from saml2.client_base import LogoutError |
| 34 | +from saml2.metadata import entity_descriptor |
33 | 35 | from saml2.ident import code, decode |
34 | 36 | from saml2.metadata import entity_descriptor |
35 | 37 | from saml2.response import (SignatureError, StatusAuthnFailed, StatusError, |
36 | 38 | StatusNoAuthnContext, StatusRequestDenied, |
37 | 39 | UnsolicitedResponse) |
38 | 40 | from saml2.s_utils import UnsupportedBinding |
| 41 | +from saml2.response import ( |
| 42 | + StatusError, StatusAuthnFailed, SignatureError, StatusRequestDenied, |
| 43 | + UnsolicitedResponse, StatusNoAuthnContext, |
| 44 | +) |
| 45 | +from saml2.mdstore import SourceNotFound |
39 | 46 | from saml2.sigver import MissingKey |
40 | 47 | from saml2.validate import ResponseLifetimeExceed, ToEarly |
41 | 48 | from saml2.xmldsig import ( # support for SHA1 is required by spec |
@@ -122,7 +129,15 @@ def login(request, |
122 | 129 | }) |
123 | 130 |
|
124 | 131 | selected_idp = request.GET.get('idp', None) |
125 | | - conf = get_config(config_loader_path, request) |
| 132 | + try: |
| 133 | + conf = get_config(config_loader_path, request) |
| 134 | + except SourceNotFound as excp: |
| 135 | + msg = ('Error, IdP EntityID was not found ' |
| 136 | + 'in metadata: {}') |
| 137 | + logger.exception(msg.format(excp)) |
| 138 | + return HttpResponse(msg.format(('Please contact ' |
| 139 | + 'technical support.')), |
| 140 | + status=500) |
126 | 141 |
|
127 | 142 | kwargs = {} |
128 | 143 | # pysaml needs a string otherwise: "cannot serialize True (type bool)" |
@@ -176,17 +191,18 @@ def login(request, |
176 | 191 | logger.debug('Redirecting user to the IdP via %s binding.', binding) |
177 | 192 | if binding == BINDING_HTTP_REDIRECT: |
178 | 193 | try: |
179 | | - # do not sign the xml itself, instead use the sigalg to |
180 | | - # generate the signature as a URL param |
181 | | - sig_alg_option_map = {'sha1': SIG_RSA_SHA1, |
182 | | - 'sha256': SIG_RSA_SHA256} |
183 | | - sig_alg_option = getattr(conf, '_sp_authn_requests_signed_alg', 'sha1') |
184 | | - sigalg = sig_alg_option_map[sig_alg_option] if sign_requests else None |
185 | 194 | nsprefix = get_namespace_prefixes() |
| 195 | + if sign_requests: |
| 196 | + # do not sign the xml itself, instead use the sigalg to |
| 197 | + # generate the signature as a URL param |
| 198 | + sig_alg_option_map = {'sha1': SIG_RSA_SHA1, |
| 199 | + 'sha256': SIG_RSA_SHA256} |
| 200 | + sig_alg_option = getattr(conf, '_sp_authn_requests_signed_alg', 'sha1') |
| 201 | + kwargs["sigalg"] = sig_alg_option_map[sig_alg_option] |
186 | 202 | session_id, result = client.prepare_for_authenticate( |
187 | 203 | entityid=selected_idp, relay_state=came_from, |
188 | | - binding=binding, sign=False, sigalg=sigalg, |
189 | | - nsprefix=nsprefix, **kwargs) |
| 204 | + binding=binding, sign=False, nsprefix=nsprefix, |
| 205 | + **kwargs) |
190 | 206 | except TypeError as e: |
191 | 207 | logger.error('Unable to know which IdP to use') |
192 | 208 | return HttpResponse(str(e)) |
@@ -376,7 +392,13 @@ def logout(request, config_loader_path=None): |
376 | 392 | 'The session does not contain the subject id for user %s', |
377 | 393 | request.user) |
378 | 394 |
|
379 | | - result = client.global_logout(subject_id) |
| 395 | + try: |
| 396 | + result = client.global_logout(subject_id) |
| 397 | + except LogoutError as exp: |
| 398 | + logger.exception('Error Handled - SLO not supported by IDP: {}'.format(exp)) |
| 399 | + auth.logout(request) |
| 400 | + state.sync() |
| 401 | + return HttpResponseRedirect('/') |
380 | 402 |
|
381 | 403 | state.sync() |
382 | 404 |
|
|
0 commit comments