Concur Solutions
Concur Solutions considers themselves "SAML compatible but not SAML compliant". Essentially this means there are many limitations in their SSO implementation, and integration with a Shibboleth IdP is quite non-intuitive and non-standard. For example,
- Concur does not share their SP metadata, and does not consume IdP metadata via SAMLP. Instead they require unsolicited, or IdP-initiated, SSO sessions.
- Concur requires the IdP signing certificate to be supplied via email.
- Concur ignores SAML attributes and looks only in the SAML subject for a NameID containing an identifier in the form userID@domain.edu. The userID in this case is the identifier provisioned to Concur via file transfer from the HR or ERP system.
The Concur SAML integration guide, and Concur mobile app integration guide, are provided only under NDA. However, the steps here should help establish the SSO partnership.
Concur integration with Shibboleth IdP
- Provide a copy of the IdP signing certificate to Concur via email.
- Ensure IdP-initiated SSO is enabled in the IdP.
- This is enabled by default in Shibboleth IdP 2.3.0 and above.
https://wiki.shibboleth.net/confluence/display/SHIB2/IdPUnsolicitedSSO
- This is enabled by default in Shibboleth IdP 2.3.0 and above.
- Configure the Concur SP metadata into the IdP (modified version provided here).
- Provide the metadata to the IdP file system, then configure it into relying-party.xml.
Ensure the NameIDFormat in the SP metadata matches the nameFormat used in the AttributeEncoder of the AttributeDefinition in attribute-resolver.xml.
<md:EntityDescriptor entityID="https://www.concursolutions.com" xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"> <md:SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"> <md:Extensions> <mdui:UIInfo> <mdui:DisplayName xml:lang="en">Concur Solutions</mdui:DisplayName> <!-- <mdui:Description xml:lang="en">Optional description.</mdui:Description> --> <mdui:Logo height="146" width="148">https://www.concur.com/sites/all/themes/Concur6/images/Concur_logo.png</mdui:Logo> </mdui:UIInfo> </md:Extensions> <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:unspecified</md:NameIDFormat> <md:AssertionConsumerService index="1" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://www.concursolutions.com/SAMLRedirector/ClientSAMLLogin.aspx"/> </md:SPSSODescriptor> </md:EntityDescriptor>
Define a NameID attribute in attribute-resolver.xml to be released to Concur.
- Ensure the NameFormat used in the Attribute Encoder matches the NameIDFormat specified in the SP metadata.
See https://wiki.shibboleth.net/confluence/display/SHIB2/IdPAddAttribute.
Also see https://wiki.shibboleth.net/confluence/display/SHIB2/IdPCustomNameIdentifier.
<resolver:AttributeDefinition xsi:type="ad:Template" id="ConcurID"> <resolver:Dependency ref="myLDAP" /> <resolver:AttributeEncoder xsi:type="enc:SAML2StringNameID" nameFormat="urn:oasis:names:tc:SAML:2.0:nameid-format:unspecified" /> <ad:Template> <![CDATA[ ${employeeID}@domain.edu ]]> </ad:Template> <ad:SourceAttribute>sAMAccountName</ad:SourceAttribute> </resolver:AttributeDefinition>
Release that attribute to Concur in attribute-filter.xml.
<afp:AttributeFilterPolicy id="releaseToConcur"> <afp:PolicyRequirementRule xsi:type="basic:AttributeRequesterString" value="https://www.concursolutions.com" /> <afp:AttributeRule attributeID="ConcurID"> <afp:PermitValueRule xsi:type="basic:ANY" /> </afp:AttributeRule> </afp:AttributeFilterPolicy>
- Exclude Concur from receiving the transcientId in attribute-filter.xml.
Concur cannot receive any released attributes other than the ConcurID.
A basic transientId release policy might look like this.
<afp:AttributeFilterPolicy id="releaseTransientIdToAnyone"> <afp:PolicyRequirementRule xsi:type="basic:NOT"> <basic:Rule xsi:type="basic:AttributeRequesterString" value="https://www.concursolutions.com" /> </afp:PolicyRequirementRule> <afp:AttributeRule attributeID="transientId"> <afp:PermitValueRule xsi:type="basic:ANY"/> </afp:AttributeRule> </afp:AttributeFilterPolicy>
Disable assertion encryption and NameID encryption for Concur in relying-party.xml.
Insert this configuration below the Default Relying Party configuration.Â
See https://wiki.shibboleth.net/confluence/display/SHIB2/IdPSAML2SSOProfileConfig.
<rp:RelyingParty id="https://www.concursolutions.com" provider="https://idp.smu.edu/idp/shibboleth" defaultSigningCredentialRef="IdPCredential"> <rp:ProfileConfiguration xsi:type="saml:SAML2SSOProfile" encryptAssertions="never" encryptNameIds="never" /> </rp:RelyingParty>
- Construct and test an unsolicited URL.
Â