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.
- 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:SPSSODescriptor
AuthnRequestsSigned
=
"false"
WantAssertionsSigned
=
"true"
protocolSupportEnumeration
=
"urn:oasis:names:tc:SAML:2.0:protocol"
>
<
md:Extensions
>
<
mdui:UIInfo
>
<!-- <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: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:Dependency
ref
=
"myLDAP"
/>
<
resolver:AttributeEncoder
xsi:type
=
"enc:SAML2StringNameID"
nameFormat
=
"urn:oasis:names:tc:SAML:2.0:nameid-format:unspecified"
/>
<
ad:Template
>
<![CDATA[
]]>
</
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: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
>
<
afp:AttributeRule
attributeID
=
"transientId"
>
</
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.