46
46
from saml2 .samlp import AuthnRequest
47
47
from saml2 .sigver import MissingKey
48
48
from saml2 .validate import ResponseLifetimeExceed , ToEarly
49
- from saml2 .xmldsig import ( # support for SHA1 is required by spec
50
- SIG_RSA_SHA1 , SIG_RSA_SHA256 )
51
49
52
50
from .cache import IdentityCache , OutstandingQueriesCache , StateCache
53
51
from .conf import get_config
@@ -160,6 +158,8 @@ def get(self, request, *args, **kwargs):
160
158
configured_idps = available_idps (conf )
161
159
selected_idp = request .GET .get ('idp' , None )
162
160
161
+ sso_kwargs = {}
162
+
163
163
# Do we have a Discovery Service?
164
164
if not selected_idp :
165
165
discovery_service = getattr (settings , 'SAML2_DISCO_URL' , None )
@@ -193,7 +193,8 @@ def get(self, request, *args, **kwargs):
193
193
selected_idp = list (configured_idps .keys ())[0 ]
194
194
195
195
# choose a binding to try first
196
- binding = getattr (settings , 'SAML_DEFAULT_BINDING' , saml2 .BINDING_HTTP_POST )
196
+ binding = getattr (settings , 'SAML_DEFAULT_BINDING' ,
197
+ saml2 .BINDING_HTTP_POST )
197
198
logger .debug (f'Trying binding { binding } for IDP { selected_idp } ' )
198
199
199
200
# ensure our selected binding is supported by the IDP
@@ -225,18 +226,17 @@ def get(self, request, *args, **kwargs):
225
226
)
226
227
227
228
client = Saml2Client (conf )
228
- http_response = None
229
229
230
230
# SSO options
231
231
sign_requests = getattr (conf , '_sp_authn_requests_signed' , False )
232
- sso_kwargs = {}
232
+
233
233
if sign_requests :
234
234
sso_kwargs ["sigalg" ] = settings .SAML_CONFIG ['service' ]['sp' ]\
235
235
.get ('signing_algorithm' ,
236
236
saml2 .xmldsig .SIG_RSA_SHA256 )
237
237
sso_kwargs ["digest_alg" ] = settings .SAML_CONFIG ['service' ]['sp' ]\
238
- .get ('digest_algorithm' ,
239
- saml2 .xmldsig .DIGEST_SHA256 )
238
+ .get ('digest_algorithm' ,
239
+ saml2 .xmldsig .DIGEST_SHA256 )
240
240
241
241
# pysaml needs a string otherwise: "cannot serialize True (type bool)"
242
242
if getattr (conf , '_sp_force_authn' , False ):
@@ -249,6 +249,8 @@ def get(self, request, *args, **kwargs):
249
249
250
250
logger .debug (f'Redirecting user to the IdP via { binding } binding.' )
251
251
_msg = 'Unable to know which IdP to use'
252
+ http_response = None
253
+
252
254
if binding == saml2 .BINDING_HTTP_REDIRECT :
253
255
try :
254
256
session_id , result = client .prepare_for_authenticate (
@@ -260,6 +262,7 @@ def get(self, request, *args, **kwargs):
260
262
return HttpResponse (_msg )
261
263
else :
262
264
http_response = HttpResponseRedirect (get_location (result ))
265
+
263
266
elif binding == saml2 .BINDING_HTTP_POST :
264
267
if self .post_binding_form_template :
265
268
# get request XML to build our own html based on the template
@@ -268,10 +271,12 @@ def get(self, request, *args, **kwargs):
268
271
except TypeError as e :
269
272
logger .error (f'{ _msg } : { e } ' )
270
273
return HttpResponse (_msg )
274
+
271
275
session_id , request_xml = client .create_authn_request (
272
276
location ,
273
277
binding = binding ,
274
- ** sso_kwargs )
278
+ ** sso_kwargs
279
+ )
275
280
try :
276
281
if isinstance (request_xml , AuthnRequest ):
277
282
# request_xml will be an instance of AuthnRequest if the message is not signed
@@ -287,14 +292,16 @@ def get(self, request, *args, **kwargs):
287
292
},
288
293
})
289
294
except TemplateDoesNotExist as e :
290
- logger .error (f'TemplateDoesNotExist: { e } ' )
295
+ logger .error (
296
+ f'TemplateDoesNotExist: [{ self .post_binding_form_template } ] - { e } '
297
+ )
291
298
292
299
if not http_response :
293
300
# use the html provided by pysaml2 if no template was specified or it doesn't exist
294
301
try :
295
302
session_id , result = client .prepare_for_authenticate (
296
303
entityid = selected_idp , relay_state = next_path ,
297
- binding = binding )
304
+ binding = binding , ** sso_kwargs )
298
305
except TypeError as e :
299
306
_msg = f"Can't prepare the authentication for { selected_idp } "
300
307
logger .error (f'{ _msg } : { e } ' )
@@ -373,7 +380,8 @@ def post(self, request, attribute_mapping=None, create_unknown_user=None):
373
380
except ResponseLifetimeExceed as e :
374
381
_exception = e
375
382
logger .info (
376
- ("SAML Assertion is no longer valid. Possibly caused by network delay or replay attack." ), exc_info = True )
383
+ ("SAML Assertion is no longer valid. Possibly caused "
384
+ "by network delay or replay attack." ), exc_info = True )
377
385
except SignatureError as e :
378
386
_exception = e
379
387
logger .info ("Invalid or malformed SAML Assertion." , exc_info = True )
@@ -428,7 +436,8 @@ def post(self, request, attribute_mapping=None, create_unknown_user=None):
428
436
for sc in assertion .subject .subject_confirmation :
429
437
if sc .method == SCM_BEARER :
430
438
assertion_not_on_or_after = sc .subject_confirmation_data .not_on_or_after
431
- assertion_info = {'assertion_id' : assertion .id , 'not_on_or_after' : assertion_not_on_or_after }
439
+ assertion_info = {'assertion_id' : assertion .id ,
440
+ 'not_on_or_after' : assertion_not_on_or_after }
432
441
break
433
442
434
443
if callable (attribute_mapping ):
0 commit comments