===== DocuSign ===== This page shows how to enable a shibboleth IDP v4 to authenticate and send attributes to a DocuSign Service Provider . external references : * https://wiki.shibboleth.net/confluence/display/IDP4/Home * https://support.docusign.com/fr/guides/org-admin-guide ===== DocuSign demo SP ===== In order to validate configuration , the DocuSign Vendor gave us a demo SP to test parameters . https://appdemo.docusign.com ==== Claim domains ==== DocuSign needs a TXT record in the client DNS for the associated domain {{:docpublic:systemes:shibboleth:shib-docusign-sp-domain-claim.png?300|}} sample TXT record in DNS zone : domain.fr IN TXT "docusign=ab64a181-0838-4ae8-9955-4493a6309d34" ==== Declare IDP ==== There's no way to use our academic Discovery Service (WAYF) , so we need to declare all of our entities IDP in the DocuSign SP : {{:docpublic:systemes:shibboleth:shib-docusign-sp-idp-declare.png?300|}} ==== Configure IDP End Points ==== After declaration of our IDP host and certificate, we can now define IDP SSO / metadata SAML EndPoints : {{:docpublic:systemes:shibboleth:shib-docusign-sp-idp-end-points-definition.png?300|}} We also set that we use signed AuthN and use Post Method . ==== DocuSign SP Metadata ==== From the Action button on the right side of the IDP lists, we can "show EndPoints" which contains the SP metadata URL that can be downloaded to our IDP for relying party truts . [root@idptest metadata]# pwd /opt/shibboleth-idp/metadata [root@idptest metadata]# wget https://account-d.docusign.com/organizations/cd450-d4aa-4f12-9b59-1160332/saml2/metadata/aa14dc60-d3ff-4f14-9e59-446044682220 this raw xml file download is quite "rude" to read, for ease of use, it can be renamed to an approprite filename (docusign.xml) and transform it to a more readble xml (indentation) format : [root@idptest metadata]# mv aa14dc60-d3ff-4f14-9e59-446044682220 docusign.xml [root@idptest metadata]# xmlstarlet fo docusign.xml > docusign-readable.xml === SP metadata certificate === the DocuSign SP certificate is included in these freshly downloaded metadata, we can extract it to a dedicated file that will be loaded in our metadata-provider for sign checking . get certificate from SP metadata element X509Certificate : MIIGvTCCBaW ... YBlA== to a docusing.pem file in an openssl x509 file format : # cat ./metadata/docusign.pem -----BEGIN CERTIFICATE----- MIIGvTCCBaW .. YBlA== -----END CERTIFICATE----- === load SP metadata in our IDP === Now that we have the SP metadata, we can load it in our IDP configuration, and declare that it is signed by the aboved SP certificate : [root@idptest conf]# vim metadata-providers.xml we keept commented the validUntil check , because by default there's no "validUntil" value in docusign SP medatada . ===== Docusign SAML specificities ==== ==== Cannot Encrypt assertions ==== while initial tests failed, we realized that it was related to our shibboleth IDP that encrypts SAML assertions (by design/default/best-practice ) So we need to disable SAML encryption , cf **encryptAssertions="false"** for that specific SP **c:relyingPartyIds=...** below : [root@idptet conf]# vim relying-party.xml ==== NameID ==== DocuSign expect by default an identifier (SAML NameID) that is persistent and mapped to the mail attribute . By default and design for dataProtection, shibboleth IDP uses a transcient NameID with a random value . So we need to define a persistent NameID based on the mail attibute for seamless authN with Docusign . this is done in saml-nameid.xml with activating ** ** and associated saml-nameid.properties : [root@idptest conf]# vim saml-nameid.xml I keept shibboleth.SAML2AttributeSourcedGenerator as commented for example above, that was a way to designated a **candidate** SP dedicated to that NameID Generator, but finally here in this test IDP for docusign , default is persistent ID for all . in **saml-nameid.properties** we define the use of the mail attribute associated with a Salt here the **idp.persistentId.generator = shibboleth.ComputedPersistentIdGenerator** is defined (no need for a database storage) idp.persistentId.useUnfilteredAttributes = true idp.persistentId.sourceAttribute = mail idp.persistentId.encoding = BASE64 #jehan idp.persistentId.algorithm = SHA idp.persistentId.salt = secretpassfor202101isi # needs to long enough ! # To use a database, use shibboleth.StoredPersistentIdGenerator idp.persistentId.generator = shibboleth.ComputedPersistentIdGenerator authN is associated with the authn Flow Password process in the IDP: [root@idpt conf]# grep authn.flows idp.properties idp.authn.flows=Password and define the ldap backend with a filter based on mail attribute : [root@idptest conf]# vim ldap.properties idp.authn.LDAP.userFilter = (&(mail={user})(employeeType=Permanent)) ##idp.attribute.resolver.LDAP.searchFilter = (uid=$resolutionContext.principal) idp.attribute.resolver.LDAP.searchFilter = (mail=$resolutionContext.principal) ==== Mapped Attributes ==== Now that authN is configured , we also need to send attributes to DocuSign SP in order to match mandatory attributes at first connexion in order to dynamically create account. these are the mandatory attributes : * sn (surname) * givenName * mail and optionnally * permissionProfileId this one allows to match a permission profile at login, for example sending a employeetyp attribute for Staff people could set their default profile to DS-Sender and for employeetype: employee associated the default profile to simple DS-viewer . :!: beware that these attributes are define in the interface with their urn/oid code, the "firendlyNames" sn , givenName, mail .... are not mapped :!: {{:docpublic:systemes:shibboleth:shib-docusign-sp-idp-attributes.png?300|}} ===== shib IDP attribute-resolver ===== In the IDP we use the **attribute-resolver-ldap.xml** (or attribute-resolver.xml) file to define our customized for DocuSign for NameID mail attribute and permission (employeeType) attribute . [root@idptest conf]# grep attribute-resolver-ldap.xml services.xml %{idp.home}/conf/attribute-resolver-ldap.xml ==== mapped attributes ==== in order to map DocuSign domains ID to our mail domains we need to map values attribute-resolver.xml mapped employeType 1601 (.+)@imte.fr 1604 (.+)@imte-atlantic.fr ... 16049193 (.+)@mines-ste.fr idem for staticDSAccountID 24035b51-b871- (.+)@imte.fr 76919292-2f64 (.+)@imte-atlantic.fr ... 557f440a-a124 (.+)@mines-ste.fr ==== Mail rewriting ==== because on our campus we use 3 domains names in our users mail addresses, in order to simplify DocuSign domain claims and IDP declaration (+ metadata) , we recorded only one domain at DocuSign SP and manage to rewrite dynamically on our IDP side the 2 other domains to the 1st one , which is the only one declared on DocuSign . To do that we uses a Mapped Attribute definition like this : [root@idptest conf]# vim attribute-resolver-ldap.xml $1@domain1.eu (.+)@domain2.eu $1@domain1.eu (.+)@domain3.eu when a user connect with it's email address of givenName.Surname@**domain2**.eu , it is finally transmited to DocuSign SP as givenName.Surname@**domain1**.eu . ==== Permission map ==== We also used a mapped attribute definition in oder to match Roles/Permission of DS-Sender vs DS-viewer , repectivelly 1122394 and 1122395 1122394 Permanent 1122395 Doctorant 1122395 Vacataire ==== static AttributeDefinition for AccountID ==== DocuSign support told us also to send a static value for the accoundID so that automatic profile affectation could be done we can get our API account ID from the E-Signature parameter screen , left menu => API-Keys {{:docpublic:systemes:shibboleth:shib-docusign-sp-accoundid.png?300|}} then we need our IDP to map and send that static value for everyone, so we creted a staticDataconnector and the associated decated static AttributeDefinition for thos DocuSign authZ feature with the creation of a custom staticDSAccountID attribute : references : * https://wiki.shibboleth.net/confluence/display/IDP4/StaticDataConnector * https://wiki.shibboleth.net/confluence/display/IDP4/SimpleAttributeDefinition in conf/attribute-resolver-ldap.xml ai4dc9cfa7-dd39-aad1-884c-2f9b17574224 ==== Special case when unsing NAT ( checkAddress="false" ) ==== clients in specific site which don't have many public IPs addresses use NAT , and it breaks the flow of using a proxied IDP In that case we must disable "checkAddress" in the IDP (as proxy) configuration . Analagous to the SP, there's a checkAddress setting on the SAML2.SSO profile configuration bean. https://wiki.shibboleth.net/confluence/display/IDP4/SAML2SSOConfiguration#55804373d9264505e7b248218c3ea26c3fd35a11 from examples in the doc: * https://wiki.shibboleth.net/confluence/display/IDP4/RelyingPartyConfiguration I understand that I can specify the checkAddress attribute only for those "2nd Hand/backends" IDPs of my idp-proxy by listing them specifically in relying-party.xml : https://idp.school1.fr/idp/shibboleth https://idp.school2.fr/idp/shibboleth https://multipass.school3.fr/idp/shibboleth