The road to hell is paved with SAML Assertions
This section focuses on SAML 2.0. The most important components of the SAML specification are the following:
Assertions are XML structures that contain packaged security information about the user. The two mostly used assertion types are
- Authentication Assertions that contain the information that the user has proven their identity
- Attribute Assertions that contain specific information about the user in the format of attributes ( such as email address, name, etc. )
SAML protocols describe how certain SAML elements (including assertions) are packaged within request and response elements, and gives the processing rules that SAML entities must follow when producing or consuming these elements. The Authentication Request Protocol is described later on.
SAML bindings describe how a SAML message must be mapped on non SAML related messaging formats and communication protocols. For instance the HTTP Redirect Binding defines how SAML messages are formatted when carried directly in the URL query string of an HTTP GET request. A SAML request is transmitted via an SAMLRequest query parameter, the value of which is deflated, base64 encoded and URL encoded.
The identity provider is the SAML authority that holds the information about users and can issue assertions for them to use in Service Providers.
The service provider is the SAML consumer that consumes the information (in the form of assertions) about the users in order to allow them access to resources.
Web Browser SSO Example
A simple example of the Web Browser SSO Profile is the case where the service provider uses the HTTP Redirect binding and the identity provider uses the HTTP POST binding. The actors involved are
- The principal (user) using a browser
- The Identity Provider
- The Service Provider
SAML2.0 Web Browser SSO Profile Example
It all starts with a user attempting to access a protected resource at some service (or explicitly asking to log in). The service is configured to allow/enforce federated login and as such presents or redirects the user to a Discovery Service interface in order to select their Identity Provider. Upon user selection, and given that it knows and trusts the selected Identity Provider, the Service Provider creates a SAML Authentication Request that looks like this:
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="_bec424fa5103428909a30ff1e31168327f79474984" Version="2.0" IssueInstant="2016-04-14T11:39:34Z" ForceAuthn="false" IsPassive="false" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" AssertionConsumerServiceURL="https://myserviceprovider.atsomeorg.com/Shibboleth.sso/SAML2/POST"> <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://myserviceprovider.atsomeorg.com/shibboleth</saml:Issuer> <samlp:NameIDPolicy xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" AllowCreate="true" /> </samlp:AuthnRequest>
- Issuer is the EntityID of the Service Provider which is a URI like string that uniquely identifies it. The Issuer denotes which Service Provider requests the user authentication.
- IssueIstant indicates when this request is made and the ID is an internal identifier that the Service Provider uses to match the SAML Response that it will later receive to the originating request.
The user’s browser is then redirected to the respective URL at the Identity Provider depending on the binding that is used and that SAML Authentication Request is passed as a string query parameter in the HTTP GET ( after it has been deflated , base64 encoded and URL encoded ).
Upon receiving the SAML Request, the Identity Provider checks that it knows and trusts the Service Provider that sends it, validates the contents of the Request and prompts the user for authentication. If the user authenticates successfully, the Identity Provider generates a SAML response, that looks something like this:
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_8e8dc5f69a98cc4c1ff3427e5ce34606fd672f91e6" Version="2.0" IssueInstant="2016-04-14T11:40:48Z" Destination="test</saml:AttributeValue> </saml:Attribute> <saml:Attribute Name="eduPersonAffiliation" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"> <saml:AttributeValue xsi:type="xs:string">users</saml:AttributeValue> <saml:AttributeValue xsi:type="xs:string">examplerole1</saml:AttributeValue> </saml:Attribute> </saml:AttributeStatement> </saml:Assertion> </samlp:Response>
and instructs the user browser to make a HTTP POST request to – in this case – https://myserviceprovider.atsomeorg.com/Shibboleth.sso/SAML2/POST.
- InResponseTo contains the value that was sent as an ID in the SAML Request so that the Service Provider can match this to the request it sent. ( and to avoid replay attacks )
- IssueIstant, NotBefore and NotOnOrAfter define a time interval for which the SAML Response ( and Assertion ) is valid, in order to protect against replay attacks.
- The Assertion contains in Issuer field so that the Service Provider can verify that the Assertion comes from the Identity Provider it expects it to come from.
- The Assertion also contains an AudienceRestriction element that defines that this Assertion is targeted for a specific Service Provider and cannot be used for any other Service Provider.
- The Assertion contains a Subject element which identifies the authenticated principal(user)
- The AttributeStatement part of the Assertion contains attributes and their values for the specific user that comes as authenticated.
The Assertion (and possibly the whole SAML Response) is signed with a XML Signature that protects the integrity of the Assertion (or response) and verifies that it has not been modified in transit.
Upon receiving the SAML Response, the Service Provider can verify its contents and structure, validate the signature and subsequently treat the user as authenticated initiating a web session for them.
By now, you should have wondered about at least a couple of things:
- How does the Service Provider know and trust the Identity Provider?
- How does the Identity Provider know and trust the Service Provider?
- The Identity Provider signs that Assertion with what?
- How does the Service Provider verify the signature when it receives the Assertion?
What is purposely left out here for brevity is that the Identity Provider and the Service Provider need to bootstrap their trust somehow before all the above can happen. In order to do that, they need to exchange metadata. The metadata contain information like the certificate with the public key that corresponds to the private key that the Identity Provider uses to sign the Assertions, the URLs that correspond to each entity’s bindings, the algorithms they support/request, etc. There are two ways for them to know each other’s metadata
- Either the Identity Provider and the Service Provider bootstrap their trust relationship bilaterally by exchanging metadata in a secure manner.
- Or both delegate this trust to a 3rd party by joining a Federation. The Federation Operator then assumes the task to gather the metadata from all entities that participate, sign and publish the aggregates. Each Identity Provider and Service Provider then consumes that metadata in order to get information about the rest of the entities that participate in that Federation.