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.