|
16 | 16 | import datetime
|
17 | 17 |
|
18 | 18 |
|
19 |
| -def auth_response(session_id, uid): |
20 |
| - """Generates a fresh signed authentication response""" |
| 19 | +def auth_response(session_id, |
| 20 | + uid, |
| 21 | + audience='http://sp.example.com/saml2/metadata/', |
| 22 | + acs_url='http://sp.example.com/saml2/acs/', |
| 23 | + metadata_url='http://sp.example.com/saml2/metadata/', |
| 24 | + attribute_statements=None): |
| 25 | + """Generates a fresh signed authentication response |
| 26 | +
|
| 27 | + Params: |
| 28 | + session_id: The session ID to generate the reponse for. Login set an |
| 29 | + outstanding session ID, i.e. djangosaml2 waits for a response for |
| 30 | + that session. |
| 31 | + uid: Unique identifier for a User (will be present as an attribute in |
| 32 | + the answer). Ignored when attribute_statements is not ``None``. |
| 33 | + audience: SP entityid (used when PySAML validates the response |
| 34 | + audience). |
| 35 | + acs_url: URL where the response has been posted back. |
| 36 | + metadata_url: URL where the SP metadata can be queried. |
| 37 | + attribute_statements: An alternative XML AttributeStatement to use in |
| 38 | + lieu of the default (uid). The uid argument is ignored when |
| 39 | + attribute_statements is not ``None``. |
| 40 | + """ |
21 | 41 | timestamp = datetime.datetime.now() - datetime.timedelta(seconds=10)
|
22 | 42 | tomorrow = datetime.datetime.now() + datetime.timedelta(days=1)
|
23 | 43 | yesterday = datetime.datetime.now() - datetime.timedelta(days=1)
|
24 | 44 |
|
25 |
| - saml_response_tpl = """<?xml version='1.0' encoding='UTF-8'?> |
26 |
| -<samlp:Response xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Destination="http://sp.example.com/saml2/acs/" ID="id-88b9f586a2a3a639f9327485cc37c40a" InResponseTo="%(session_id)s" IssueInstant="%(timestamp)s" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://idp.example.com/simplesaml/saml2/idp/metadata.php</saml:Issuer><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" /></samlp:Status><saml:Assertion ID="id-093952102ceb73436e49cb91c58b0578" IssueInstant="%(timestamp)s" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://idp.example.com/simplesaml/saml2/idp/metadata.php</saml:Issuer><saml:Subject><saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" NameQualifier="" SPNameQualifier="http://sp.example.com/saml2/metadata/">1f87035b4c1325b296a53d92097e6b3fa36d7e30ee82e3fcb0680d60243c1f03</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData InResponseTo="%(session_id)s" NotOnOrAfter="%(tomorrow)s" Recipient="http://sp.example.com/saml2/acs/" /></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="%(yesterday)s" NotOnOrAfter="%(tomorrow)s"><saml:AudienceRestriction><saml:Audience>http://sp.example.com/saml2/metadata/</saml:Audience></saml:AudienceRestriction></saml:Conditions><saml:AuthnStatement AuthnInstant="%(timestamp)s" SessionIndex="%(session_id)s"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement><saml:AttributeStatement><saml:Attribute FriendlyName="uid" Name="urn:oid:0.9.2342.19200300.100.1.1" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml:AttributeValue xsi:nil="true" xsi:type="xs:string">%(uid)s</saml:AttributeValue></saml:Attribute></saml:AttributeStatement></saml:Assertion></samlp:Response>""" |
| 45 | + if attribute_statements is None: |
| 46 | + attribute_statements = ( |
| 47 | + '<saml:AttributeStatement>' |
| 48 | + '<saml:Attribute FriendlyName="uid" Name="urn:oid:0.9.2342.19200300.100.1.1" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">' |
| 49 | + '<saml:AttributeValue xsi:nil="true" xsi:type="xs:string">' |
| 50 | + '%(uid)s' |
| 51 | + '</saml:AttributeValue>' |
| 52 | + '</saml:Attribute>' |
| 53 | + '</saml:AttributeStatement>' |
| 54 | + ) % {'uid': uid} |
| 55 | + |
| 56 | + saml_response_tpl = ( |
| 57 | + "<?xml version='1.0' encoding='UTF-8'?>" |
| 58 | + '<samlp:Response xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Destination="%(acs_url)s" ID="id-88b9f586a2a3a639f9327485cc37c40a" InResponseTo="%(session_id)s" IssueInstant="%(timestamp)s" Version="2.0">' |
| 59 | + '<saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">' |
| 60 | + 'https://idp.example.com/simplesaml/saml2/idp/metadata.php' |
| 61 | + '</saml:Issuer>' |
| 62 | + '<samlp:Status>' |
| 63 | + '<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />' |
| 64 | + '</samlp:Status>' |
| 65 | + '<saml:Assertion ID="id-093952102ceb73436e49cb91c58b0578" IssueInstant="%(timestamp)s" Version="2.0">' |
| 66 | + '<saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">' |
| 67 | + 'https://idp.example.com/simplesaml/saml2/idp/metadata.php' |
| 68 | + '</saml:Issuer>' |
| 69 | + '<saml:Subject>' |
| 70 | + '<saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" NameQualifier="" SPNameQualifier="%(metadata_url)s">' |
| 71 | + '1f87035b4c1325b296a53d92097e6b3fa36d7e30ee82e3fcb0680d60243c1f03' |
| 72 | + '</saml:NameID>' |
| 73 | + '<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">' |
| 74 | + '<saml:SubjectConfirmationData InResponseTo="%(session_id)s" NotOnOrAfter="%(tomorrow)s" Recipient="%(acs_url)s" />' |
| 75 | + '</saml:SubjectConfirmation>' |
| 76 | + '</saml:Subject>' |
| 77 | + '<saml:Conditions NotBefore="%(yesterday)s" NotOnOrAfter="%(tomorrow)s">' |
| 78 | + '<saml:AudienceRestriction>' |
| 79 | + '<saml:Audience>' |
| 80 | + '%(audience)s' |
| 81 | + '</saml:Audience>' |
| 82 | + '</saml:AudienceRestriction>' |
| 83 | + '</saml:Conditions>' |
| 84 | + '<saml:AuthnStatement AuthnInstant="%(timestamp)s" SessionIndex="%(session_id)s">' |
| 85 | + '<saml:AuthnContext>' |
| 86 | + '<saml:AuthnContextClassRef>' |
| 87 | + 'urn:oasis:names:tc:SAML:2.0:ac:classes:Password' |
| 88 | + '</saml:AuthnContextClassRef>' |
| 89 | + '</saml:AuthnContext>' |
| 90 | + '</saml:AuthnStatement>' |
| 91 | + '%(attribute_statements)s' |
| 92 | + '</saml:Assertion>' |
| 93 | + '</samlp:Response>') |
27 | 94 | return saml_response_tpl % {
|
28 |
| - 'uid': uid, |
29 | 95 | 'session_id': session_id,
|
| 96 | + 'audience': audience, |
| 97 | + 'acs_url': acs_url, |
| 98 | + 'metadata_url': metadata_url, |
| 99 | + 'attribute_statements': attribute_statements, |
30 | 100 | 'timestamp': timestamp.strftime('%Y-%m-%dT%H:%M:%SZ'),
|
31 | 101 | 'tomorrow': tomorrow.strftime('%Y-%m-%dT%H:%M:%SZ'),
|
32 | 102 | 'yesterday': yesterday.strftime('%Y-%m-%dT%H:%M:%SZ'),
|
|
0 commit comments