10
10
11
11
from saml2 .entity import Entity
12
12
13
+ import saml2 .attributemaps as attributemaps
14
+
13
15
from saml2 .mdstore import destinations
14
16
from saml2 .profile import paos , ecp
15
17
from saml2 .saml import NAMEID_FORMAT_TRANSIENT
18
20
from saml2 .samlp import AttributeQuery
19
21
from saml2 .samlp import AuthzDecisionQuery
20
22
from saml2 .samlp import AuthnRequest
23
+ from saml2 .samlp import Extensions
24
+ from saml2 .extension import sp_type
25
+ from saml2 .extension import requested_attributes
21
26
22
27
import saml2
23
28
import time
@@ -207,7 +212,7 @@ def create_authn_request(self, destination, vorg="", scoping=None,
207
212
nameid_format = None ,
208
213
service_url_binding = None , message_id = 0 ,
209
214
consent = None , extensions = None , sign = None ,
210
- allow_create = False , sign_prepare = False , sign_alg = None ,
215
+ allow_create = None , sign_prepare = False , sign_alg = None ,
211
216
digest_alg = None , ** kwargs ):
212
217
""" Creates an authentication request.
213
218
@@ -235,26 +240,30 @@ def create_authn_request(self, destination, vorg="", scoping=None,
235
240
236
241
args = {}
237
242
238
- try :
239
- args ["assertion_consumer_service_url" ] = kwargs [
240
- "assertion_consumer_service_urls" ][0 ]
241
- del kwargs ["assertion_consumer_service_urls" ]
242
- except KeyError :
243
+ if self .config .getattr ('hide_assertion_consumer_service' , 'sp' ):
244
+ args ["assertion_consumer_service_url" ] = None
245
+ binding = None
246
+ else :
243
247
try :
244
248
args ["assertion_consumer_service_url" ] = kwargs [
245
- "assertion_consumer_service_url" ]
246
- del kwargs ["assertion_consumer_service_url " ]
249
+ "assertion_consumer_service_urls" ][ 0 ]
250
+ del kwargs ["assertion_consumer_service_urls " ]
247
251
except KeyError :
248
252
try :
249
- args ["assertion_consumer_service_index " ] = str ( kwargs [
250
- "assertion_consumer_service_index" ])
251
- del kwargs ["assertion_consumer_service_index " ]
253
+ args ["assertion_consumer_service_url " ] = kwargs [
254
+ "assertion_consumer_service_url" ]
255
+ del kwargs ["assertion_consumer_service_url " ]
252
256
except KeyError :
253
- if service_url_binding is None :
254
- service_urls = self .service_urls (binding )
255
- else :
256
- service_urls = self .service_urls (service_url_binding )
257
- args ["assertion_consumer_service_url" ] = service_urls [0 ]
257
+ try :
258
+ args ["assertion_consumer_service_index" ] = str (
259
+ kwargs ["assertion_consumer_service_index" ])
260
+ del kwargs ["assertion_consumer_service_index" ]
261
+ except KeyError :
262
+ if service_url_binding is None :
263
+ service_urls = self .service_urls (binding )
264
+ else :
265
+ service_urls = self .service_urls (service_url_binding )
266
+ args ["assertion_consumer_service_url" ] = service_urls [0 ]
258
267
259
268
try :
260
269
args ["provider_name" ] = kwargs ["provider_name" ]
@@ -268,7 +277,7 @@ def create_authn_request(self, destination, vorg="", scoping=None,
268
277
# all of these have cardinality 0..1
269
278
_msg = AuthnRequest ()
270
279
for param in ["scoping" , "requested_authn_context" , "conditions" ,
271
- "subject" , "scoping" ]:
280
+ "subject" ]:
272
281
try :
273
282
_item = kwargs [param ]
274
283
except KeyError :
@@ -288,23 +297,37 @@ def create_authn_request(self, destination, vorg="", scoping=None,
288
297
args ["name_id_policy" ] = kwargs ["name_id_policy" ]
289
298
del kwargs ["name_id_policy" ]
290
299
except KeyError :
291
- if allow_create :
292
- allow_create = "true"
293
- else :
294
- allow_create = "false"
300
+ if allow_create is None :
301
+ allow_create = self .config .getattr ("name_id_format_allow_create" , "sp" )
302
+ if allow_create is None :
303
+ allow_create = "false"
304
+ else :
305
+ if allow_create is True :
306
+ allow_create = "true"
307
+ else :
308
+ allow_create = "false"
295
309
296
310
if nameid_format == "" :
297
311
name_id_policy = None
298
312
else :
299
313
if nameid_format is None :
300
314
nameid_format = self .config .getattr ("name_id_format" , "sp" )
301
315
316
+ # If no nameid_format has been set in the configuration
317
+ # or passed in then transient is the default.
302
318
if nameid_format is None :
303
319
nameid_format = NAMEID_FORMAT_TRANSIENT
320
+
321
+ # If a list has been configured or passed in choose the
322
+ # first since NameIDPolicy can only have one format specified.
304
323
elif isinstance (nameid_format , list ):
305
- # NameIDPolicy can only have one format specified
306
324
nameid_format = nameid_format [0 ]
307
325
326
+ # Allow a deployer to signal that no format should be specified
327
+ # in the NameIDPolicy by passing in or configuring the string 'None'.
328
+ elif nameid_format == 'None' :
329
+ nameid_format = None
330
+
308
331
name_id_policy = samlp .NameIDPolicy (allow_create = allow_create ,
309
332
format = nameid_format )
310
333
@@ -321,6 +344,75 @@ def create_authn_request(self, destination, vorg="", scoping=None,
321
344
except KeyError :
322
345
nsprefix = None
323
346
347
+ try :
348
+ force_authn = kwargs ['force_authn' ]
349
+ except KeyError :
350
+ force_authn = self .config .getattr ('force_authn' , 'sp' )
351
+ finally :
352
+ if force_authn :
353
+ args ['force_authn' ] = 'true'
354
+
355
+ conf_sp_type = self .config .getattr ('sp_type' , 'sp' )
356
+ conf_sp_type_in_md = self .config .getattr ('sp_type_in_metadata' , 'sp' )
357
+ if conf_sp_type and conf_sp_type_in_md is False :
358
+ if not extensions :
359
+ extensions = Extensions ()
360
+ item = sp_type .SPType (text = conf_sp_type )
361
+ extensions .add_extension_element (item )
362
+
363
+ requested_attrs = self .config .getattr ('requested_attributes' , 'sp' )
364
+ if requested_attrs :
365
+ if not extensions :
366
+ extensions = Extensions ()
367
+
368
+ attributemapsmods = []
369
+ for modname in attributemaps .__all__ :
370
+ attributemapsmods .append (getattr (attributemaps , modname ))
371
+
372
+ items = []
373
+ for attr in requested_attrs :
374
+ friendly_name = attr .get ('friendly_name' )
375
+ name = attr .get ('name' )
376
+ name_format = attr .get ('name_format' )
377
+ is_required = str (attr .get ('required' , False )).lower ()
378
+
379
+ if not name and not friendly_name :
380
+ raise ValueError (
381
+ "Missing required attribute: '{}' or '{}'" .format (
382
+ 'name' , 'friendly_name' ))
383
+
384
+ if not name :
385
+ for mod in attributemapsmods :
386
+ try :
387
+ name = mod .MAP ['to' ][friendly_name ]
388
+ except KeyError :
389
+ continue
390
+ else :
391
+ if not name_format :
392
+ name_format = mod .MAP ['identifier' ]
393
+ break
394
+
395
+ if not friendly_name :
396
+ for mod in attributemapsmods :
397
+ try :
398
+ friendly_name = mod .MAP ['fro' ][name ]
399
+ except KeyError :
400
+ continue
401
+ else :
402
+ if not name_format :
403
+ name_format = mod .MAP ['identifier' ]
404
+ break
405
+
406
+ items .append (requested_attributes .RequestedAttribute (
407
+ is_required = is_required ,
408
+ name_format = name_format ,
409
+ friendly_name = friendly_name ,
410
+ name = name ))
411
+
412
+ item = requested_attributes .RequestedAttributes (
413
+ extension_elements = items )
414
+ extensions .add_extension_element (item )
415
+
324
416
if kwargs :
325
417
_args , extensions = self ._filter_args (AuthnRequest (), extensions ,
326
418
** kwargs )
0 commit comments