When setting up single sign-on (SSO) using Vanilla's Security Assertion Markup Language (SAML) SSO plugin against your own authentication provider or a third-party authentication provider, you may encounter several possible points of failure. SAML is a very secure authentication method that requires a precise configuration, and is not necessarily easy to troubleshoot. This article discusses these pain points, and what can be done about them.
SAML overview
SAML is a protocol for exchanging user data securely between a Service Provider (in our case, Vanilla) and an Identity Provider (either your authentication server or a third-party server). SAML delivers the data in an XML document containing Assertions, which are claims, or data, about the user being authenticated.
The basic SAML 2.0 flow
- In a Vanilla community, a user clicks the 'Sign In' prompt. Their browser is redirected to the sign in page of the Identity Provider that you have configured in the SAML addon in the Vanilla Dashboard with the GET variable
SAML Request
. The SAML Request
is a compressed, base64-encoded XML document that tells the Identity Provider which Service Provider is making the request. - The Identity Provider presents the user with a Sign In form. Once the user has been authenticated, the Identity Provider POSTs back the Response to the ReturnURL. The
SAML Response
, like the SAML Request
, is a compressed, base64-encoded, signed XML document with either an error message or, if successful, all the 'Assertions' (also known as 'Claims' or user data) for the user. - The Service Provider (Vanilla) will decode the
SAML Response
, read the Assertions, verify the signature, and translate the Assertions into useable data for either starting a session for an existing user (by matching the UniqueID or, if there isn't one, the Email in the Assertions with an existing user), or creating a new user.
For more information on how to configure your Vanilla SAML SSO connection, see this article.
Troubleshooting
You can use Audit Logger to view the SAML Event logs; simply filter the logs by "saml."
Check out the article below to learn how to access and use Audit Logger.
SAML Request
Your identity provider (IdP) will receive a SAML Request from Vanilla when a user initiates a log in from your Vanilla community. It will be base64_encoded and gzdeflated without compression. Here is a, example of what we send:
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="$id" Version="2.0" IssueInstant="$issueInstant" Destination="$destination" IsPassive="false" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" AssertionConsumerServiceURL="$returnURL"> <saml:Issuer>$issuer</saml:Issuer> <samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" AllowCreate="true"></samlp:NameIDPolicy> <samlp:RequestedAuthnContext Comparison="exact"> <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef> </samlp:RequestedAuthnContext></samlp:AuthnRequest>
In the above example:
$id
is a randomly generated string$issueInstant
is the timestamp (e.g., now)$destination
is the Sign In URL on your IdP as configured in the forum Dashboard.$returnURL
is the entry point in the Vanilla community where the SAML Response will be sent (e.g., https://forum.mydomain.com/entry/connect/saml?authKey=my_saml_connection)$issuer
is the EntityID from the community Dashboard (applicationID).
SAML Response
To see what SAML Response your IdP is sending to your community, view the Event Log in the Vanilla Dashboard and filter on saml_response_received
. Below is an example of a SAML response that is structured in a way that our system can parse and use:
<samlp:Response Destination="https://forum.mydomain.com/entry/connect/saml?authKey=my_saml_connection" ID="_3d8468fe676f01fe3ff3" InResponseTo="vf-16c181a13aa765aeca8bdf5f97901f702659aff4" IssueInstant="2020-04-10T03:43:47.667Z" Version="2.0" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"><saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">urn:mysamlapp.auth0.com</saml:Issuer><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></samlp:Status><saml:Assertion ID="_sgBT9hCKhQGiSpAbAc8dqeeEjw927PG1" IssueInstant="2020-04-10T03:43:47.635Z" Version="2.0" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"><saml:Issuer>urn:mysamlapp.auth0.com</saml:Issuer><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><Reference URI="#_sgBT9hCKhQGiSpAbAc8dqeeEjw927PG1"><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><DigestValue>0LUaOC5zG5e9637598cdb0k6U=</DigestValue></Reference></SignedInfo><SignatureValue>ZuUPV1EsWzg5Xl3/.......fbOPyh0bidNFCT04aHEw==</SignatureValue><KeyInfo><X509Data><X509Certificate>MIIDEzC.........4d7OM/4=</X509Certificate></X509Data></KeyInfo></Signature><saml:Subject><saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">auth0|5604072ba0a9b7fd3c2c2939</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData InResponseTo="vf-16c181a13aa765aeca8bdf5f97901f702659aff4" NotOnOrAfter="2020-04-10T04:43:47.635Z" Recipient="https://dev.vanilla.localhost/entry/connect/saml?authKey=saml"/></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="2020-04-10T03:43:47.635Z" NotOnOrAfter="2020-04-10T04:43:47.635Z"><saml:AudienceRestriction><saml:Audience>5e96388a49473</saml:Audience></saml:AudienceRestriction></saml:Conditions><saml:AuthnStatement AuthnInstant="2020-04-10T03:43:47.635Z" SessionIndex="_MDo2sNieG_1LNk6n0n-jZ09XrZV1Vpe6"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement><saml:AttributeStatement xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><saml:Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml:AttributeValue xsi:type="xs:string">auth0|5604072ba0a9b7fd3c2c2939</saml:AttributeValue></saml:Attribute><saml:Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml:AttributeValue xsi:type="xs:string">john.doe@gmail.com</saml:AttributeValue></saml:Attribute><saml:Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml:AttributeValue xsi:type="xs:string">John Doe</saml:AttributeValue></saml:Attribute><saml:Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml:AttributeValue xsi:type="xs:string">john.doe@gmail.com</saml:AttributeValue></saml:Attribute><saml:Attribute Name="http://schemas.auth0.com/identities/default/provider" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml:AttributeValue xsi:type="xs:string">auth0</saml:AttributeValue></saml:Attribute><saml:Attribute Name="http://schemas.auth0.com/identities/default/connection" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml:AttributeValue xsi:type="xs:string">Username-Password-Authentication</saml:AttributeValue></saml:Attribute><saml:Attribute Name="http://schemas.auth0.com/identities/default/isSocial" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml:AttributeValue xsi:type="xs:boolean">false</saml:AttributeValue></saml:Attribute><saml:Attribute Name="http://schemas.auth0.com/picture" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml:AttributeValue xsi:type="xs:string">https://cdn.myprofilepic.png</saml:AttributeValue></saml:Attribute><saml:Attribute Name="http://schemas.auth0.com/nickname" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml:AttributeValue xsi:type="xs:string">JohnnyBoy</saml:AttributeValue></saml:Attribute><saml:Attribute Name="http://schemas.auth0.com/sid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml:AttributeValue xsi:type="xs:string">NWU5NjM4NDJiOWM1ZQ</saml:AttributeValue></saml:Attribute><saml:Attribute Name="http://schemas.auth0.com/email_verified" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml:AttributeValue xsi:type="xs:boolean">false</saml:AttributeValue></saml:Attribute><saml:Attribute Name="http://schemas.auth0.com/clientID" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml:AttributeValue xsi:type="xs:string">5e96388a49473</saml:AttributeValue></saml:Attribute><saml:Attribute Name="http://schemas.auth0.com/updated_at" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml:AttributeValue xsi:type="xs:anyType">Fri Apr 10 2020 03:43:47 GMT+0000 (Coordinated Universal Time)</saml:AttributeValue></saml:Attribute><saml:Attribute Name="http://schemas.auth0.com/created_at" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><saml:AttributeValue xsi:type="xs:anyType">Thu Sep 24 2015 14:22:35 GMT+0000 (Coordinated Universal Time)</saml:AttributeValue></saml:Attribute></saml:AttributeStatement></saml:Assertion></samlp:Response>
Common error messages
"The SAML response was not valid."
This is a generic error that covers multiple possible points of failure. It could be:
- The signature could not be located in the Response.
- No References node was found in the Response. The Response node is expected to be found as a child of the SignedInfo node.
- Your Response has more than one set of Assertions. Vanilla expects everything to be the child of one Assertion node.
- Timing issues. SAML Responses MUST have
NotBefore
and NotOnOrAfter
values that protect from replay attacks. It could be that your server's clocks are not properly synchronized.
"You are not allowed to GET."
- Your SAML Response should be POSTed to the entry endpoint. Any response sent using the GET protocol will be rejected.
"The SAMLRequest signature was not valid."
- The most common cause of this error is an invalid certificate configured in your Vanilla Dashboard. See Invalid Certificate.
Invalid certificate
The IdP Certificate configured in the SAML addon in the Dashboard MUST be a valid x509 Certificate. If your connections are failing, you can test your certificate using OpenSSL's command line utility. If your certificate is called certificate.crt
, perform the following command:
openssl x509 -in certificate.crt -text -noout
Missing Email or Name
You may be passing the Email or Name in your SAML response, and yet users are still prompted to enter and Email or a Name to identify themselves in the community.
In the Dashboard's left-hand menu, click the Event Log link under Technical (if you don't see it, contact Vanilla Support).
- Filter on "saml_response_received" to see what is being passed.
- Make sure the saml:Attribute Names are mapped properly in the SAML addon.
- The Name attribute has to be an exact match.
If this is what is being passed:
<saml:AttributeStatement xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <saml:Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/photo" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"> <saml:AttributeValue xsi:type="xs:string"></saml:AttributeValue> </saml:Attribute> <saml:Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"> <saml:AttributeValue xsi:type="xs:string">johndoe@gmail.com</saml:AttributeValue> </saml:Attribute> <saml:Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"> <saml:AttributeValue xsi:type="xs:string">JohnDoe</saml:AttributeValue> </saml:Attribute></saml:AttributeStatement>
Then, in the SAML addon, map the names like this: