swdevlin
swdevlin

Reputation: 57

In pysaml2, how does one include attributes in the initial AuthNResponse?

I have the example IdP/SP working ok. I can hook up my app to the example IdP and the handshake works ok. However, the initial AuthNResponse includes only the eduPersonTargetedID and I want it to include other attibutes, like sn, email, etc. I know the response includes a link to the attribute service but I need the attributes in the AuthNResponse.

Any suggestions/pointers on how to accomplish that?

Thanks, Shawn

Upvotes: 3

Views: 1134

Answers (1)

identigral
identigral

Reputation: 3969

You pass a dict that maps keys of your to-be attributes to their values:

IDENTITY = {"surName": ["Jeter"], "givenName": ["Derek"],"title": ["shortstop"]}
server.create_authn_response(IDENTITY,...); # other arguments are omitted for this example

Doing so yields this <AttributeStatement> in the emitted response:

<ns1:AttributeStatement>
                <ns1:Attribute FriendlyName="givenName" Name="urn:oid:2.5.4.42" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
                    <ns1:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">Derek</ns1:AttributeValue>
                </ns1:Attribute>
                <ns1:Attribute FriendlyName="surName" Name="urn:oid:2.5.4.4" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
                    <ns1:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">Jeter</ns1:AttributeValue>
                </ns1:Attribute>
                <ns1:Attribute FriendlyName="title" Name="urn:oid:2.5.4.12" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
                    <ns1:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">shortstop</ns1:AttributeValue>
                </ns1:Attribute>
</ns1:AttributeStatement>

As you can see, FriendlyName of the <Attribute> element is set to the name of the key in IDENTITY dict. The value of <AttributeValue> element is set to the value of the corresponding dict entry based on the key. Each <Attribute> element also has Name and NameFormat attributes. Values of these come from a configuration map you also have to set up.

Configuration maps are files that are loaded from a directory pointed to by attribute_map_dir in the identity provider config file:

CONFIG = {
    "entityid": "http://saml.example.com:saml/idp.xml",
    ...
    "attribute_map_dir": "attributemaps"
}

In the attributemaps directory, multiple files could exist. Each file is Python source with a MAP dict that has the SAML identifier (name) of the attribute format that your identity provider will support and to and fro nested maps. The to map is used by the identity provider to translate from the name of the (incoming) key in the IDENTITY dict to the value of (outgoing) Name attribute in <AttributeValue> element.

X500ATTR_OID = "urn:oid:2.5.4."

MAP = {
    "identifier": "urn:oasis:names:tc:SAML:2.0:attrname-format:uri",
    "fro": {
        ...
    },
    "to": {
        'surName': X500ATTR_OID+'4',
        'givenName': X500ATTR_OID+'42',
         ...
        'title': X500ATTR_OID+'12'
    }
}

You can copy the maps from pysaml2 source and modify them as needed. The keys/values in to nested map and the value of identifier will be determined by what your SAML service provider expects/supports. FriendlyName doesn't matter, it's used for readability but the spec doesn't rely on it.

Upvotes: 1

Related Questions