This post continues our look at SAML v2.0 and how it compares to JSON Web Tokens (JWT). In the last post, we looked at the history, specs, and basics of SAML v2.0. In this post, we begin exploring SAML v2.0 use cases in detail.
SAML2 In The Wild
The average user might not realize that SAML2 has become the workhorse of federation in most enterprise environments. Granted, the OAuth2/OpenIDConnect paradigm is gaining traction, but SAML2 remains prevalent, especially in large organizations. You could see SAML2 used for:
- Google Apps & Google Mail access
- Azure Office 365
- AWS Management Console
- JEE applications that use Container Managed Security
At some point, your own organization will have to deal with Single Sign On of web applications (whether home-grown, SaaS, or some other third-party). SAML2 has been the defacto standard in the enterprise for accomplishing this for nearly the past decade (though, the last few years, OpenID Connect and OAuth2 have been gaining traction). If these are new concepts to your organization, then at some point your business partner will tell you to integrate with a third-party vendor, the vendor will tell you to support SAML, and your internal information security department will tell you the world is at an end. If this sounds familiar, you’ve come to the right place.
SAML 2.0 Use Cases
In this and future posts, we will cover the following SAML 2.0 use cases:
- Service Provider (SP)-initiated Web App Single Sign-On (SSO)
- Identity Provider (IdP)-initiated Web App SSO
- SOAP Web Services & SAML 2.0
- REST APIs & SAML 2.0
- Single Logout
Use Case 1: SP-Initiated Web App Single Sign-On
SP-initiated Web App SSO is one the most common uses of SAML. It is part of the Web Browser SSO Profile defined in Section 4.1 of the SAML 2.0 Profiles Specification. Together with the HTTP POST, HTTP GET, and HTTP Artifact Bindings, which are defined in the SAML 2.0 Bindings specification, these specification lays out the details of how SP-initiated SSO works. In this scenario, there is an Identity Provider (IdP) and a Service Provider (or Relying Party). There is also a user agent (typically a browser) and a user that needs to be authenticated and authorized to access the resource that is hosted by the service provider. This desired result can be achieved several different ways depending on the specific use case; I’m presenting a common combination of design decisions that are all within spec.
Figure 1: Service Provider Initiated SAML-Based Web App Single Sign-On (SSO)
The SAML 2.0 Profile provides a detailed description of what is happening in Figure-1, which starts on page 16, line 404.
In 2012, I presented at Red Hat Summit about security integration and federation with the JBoss Middleware Stack (centered on PicketLink, its federated identity layer). One of the three Security Integration scenarios covered was SP-Initiated Web App SSO with two web applications. This example came from that presentation. The next diagram shows the steps involved in SP-Initiated SSO with two applications and IdP using JBoss EAP and PicketLink.
Figure 2: Detailed View of SAML2-Based SSO redirects in JBoss + PicketLink
Figure 2 shows a web browser (user agent) interacting with two web apps hosted on different JBoss containers. An IdP authenticates the user and issues a SAML Assertion that is trusted by the application servers.
In step 1, the user launches the Sales app’s initial page. The JBoss container intercepts the request, finds no authentication information, and returns a 302 Redirect Message (with a SAMLRequest parameter) that instructs the browser to send the request to the preconfigured IdP. In step 2, the redirected request is sent to the PicketLink IdP; The SAMLRequest parameter contains a base64-encoded AuthnRequest message (described below). This message contains details needed by the IdP to process the user authentication for the Sales application. The response for step 2 is a login form where the user can enter a userid and password since the user is not authenticated against the IdP. In step 3, the user has entered credentials and clicked submit. JEE-practitioners will recognize the HTTP POST to /idp/j_security_check as the standard servlet container-managed security authentication mechanism for form-based authentication. If the user was authenticated successfully, another 302 Redirect Message is returned — redirecting to the original IdP endpoint.
Step 4 is the replay of the AuthnRequest being sent to the IdP with authentication information (a JSESSIONID cookie that ties back to an authenticated security session); the response for step 4 is a redirect back to the Sales app landing page with a SAMLResponse parameter (described below), which contains a SAML Assertion. Step 5 is a redirected call being sent to the Sales application with the SAMLPResponse parameter. The JBoss container extracts and validates the SAMLPResponse value and the SAML Assertion that it contains. The validation steps are described in SAML 2.0 Assertions and Protocol. Assuming success, the container creates a security context for the user and processes the application request — building the Sales app welcome page. Step 6 retrieves a GIF image
In step 7, the user accesses the Employee application on the second JBoss container. The request contains no security session information ; so, JBoss responds with a 302 Redirect Message to the IdP — just like before. In step 8, the browser sends the AuthnRequest message to the IdP. The user has already been authenticated against the IdP; the IdP sees that the browser request contains information about an authenticated security session for the user, processes the AuthnRequest message, generates a SAMLPResponse message, and places it in a SAMLResponse parameter as part of yet another redirect back to the Employee application.
In Step 9, the browser sends an HTTP GET message to the landing page of the Employee application. The JBoss container intercepts the request, extracts the SAMLPResponse message, validates it, validates the SAML Assertion it contains, and builds a security context for the user’s session. The container returns the Employee app welcome page with a JSESSIONID cookie to track the new security session. Step 10 is a request for an image on the Employee welcome page.
Figure 2 references two interesting data structures that are worth looking at in more detail: SAMLRequest and SAMLResponse.
In the example above, the HTTP GET binding is used and the SAML Request query parameter contains a base64-encoded AuthNRequest data structure, which looks something like the following:
<samlp:AuthnRequest xmlns:samlp=”urn:oasis:names:tc:SAML:2.0:protocol” xmlns:saml=”urn:oasis:names:tc:SAML:2.0:assertion” ID=”324232532452345245" Version=”2.0" IssueInstant=”2016–05–01T00:00:00" ProtocolBinding=”urn:oasis:names:tc:SAML:2.0:bindings:HTTP-GET” AssertionConsumerServiceURL=”https://sp.levvel.io/sso/saml2/acs"> <saml:Issuer>https://app1.levvel.io/login</saml:Issuer> </samlp:AuthnRequest>
The AuthnRequest element contains an Issuer element and several notable attributes (ProtocolBinding, AssertionConsumerServiceURL). The Issuer element provides the audience for the resulting SAML Assertion (this will appear in the Audience information). The AssertionConsumerServiceURL attribute provides the URL to which the IdP should redirect the user(with a SAMLResponse parameter) once authenticated. The ProtocolBinding attribute defines what binding should be used.The SAMLResponse parameter contains a Response data structure similar to the following:
<?xml version="1.0"?> <samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="response_1234567890" Version="2.0" IssueInstant="2016-05-01T00:00:00Z" Destination="https://sp.levvel.io/sso/saml2/acs" InResponseTo="848473578359886934987350988240234904302987753898345"> <saml:Issuer>https://idp.levvel.io/sso/saml2/token</saml:Issuer> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha256"/> <ds:Reference URI="#response_1234567890"> <ds:Transforms> <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> </ds:Transforms> <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256"/> <ds:DigestValue>kdmrndicowplkqdmduc=</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue> [ omitted for brevity... ] </ds:SignatureValue> <ds:KeyInfo> <ds:X509Data> <ds:X509Certificate> [ omitted for brevity... ] </ds:X509Certificate> </ds:X509Data> </ds:KeyInfo> </ds:Signature> <samlp:Status> <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/> </samlp:Status> <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="saml2_0123456789" IssueInstant="2016-05-01T00:00:00.000Z" Version="2.0"> [omitted for brevity. See example here…] </saml:Assertion> </samlp:Response>
We covered the SAML Assertion in the first post in this series. The Response element contains issuer, signature, status, and assertion elements.
- The issuer element contains a URL describing the IdP that generated this SAMLPResponse.
- The signature element contains a signature over the response element.
- The status element contains the status of the AuthNRequest processing.
As noted in Figure 2 and its description, the browser redirects the SAMLPResponse to the SP, which validates the signature and other information in the the SAMLPResponse and SAML Assertion. If all validations are passed, a security context will be created on the application server for the SP . The SAML Assertion is generally disregarded at this point on the SP (some JEE Application Servers will keep a copy of the original SAML Assertion cached in the Security Context); it is absolutely disregarded after this by the browser. Depending on the application server technology in use, some type of session tracking cookie (or a similar mechanism) will be used to track the security session.
Every vendor that supports Web App SSO for a service provider has a cacophony of configuration parameters that can be mind boggling. I”ve worked with WAS, JBoss,TAMeb/WebSEAL, and other platforms that support SAML2. None of them were simple to setup for the first time in a new environment.. Going into the details of any of these platforms is beyond the scope of this post, if you you need help with setting up SAML2-based Web App SSO on any platform, contact me.
Use Case #2: Web App SSO — IdP Initiated
Identity Provider Initiated Web App SSO is a subset of the step described in Use Case #1. In particular, it is steps #5 through #6 in the generic SP-Initiated SSO sequence that represent the steps involved in IdP-Initiated Web App SSO. This is the simplest form of Web App SSO defined by the SAML 2.0 spec. Interestingly, this is the only type of Web App SSO defined by the SAML 1.1 spec. The steps involved in IdP Initiated Web App SSO are:
- Authenticate against the IdP (the details are highly context-specific).
- Redirected to page with list of SPs that preregistered with IdP that are presented as a list of links or a menu.
- Request sent to IdP endpoint that generates SAMLPResponse message and returns a page to the browser that contains a form that must be submitted to the Service Provider that contains a SAMLPResponse Message.
- User submits this form to the Service Provider’s ACS URL.
- The Service Provider validates the SAMLPResponse message and the SAML Assertion that it contains per the SAML 2.0 spec. Assuming success, the Service Provider builds a Security Context for the user’s session. The user is redirected to the Service Provider application’s landing page.
Figure 3: Identity Provider (IdP) Initiated SAML-based Web Application Single Sign On (SSO)
Since the details are highly dependent upon the IdP and it is similar to Use Case #1, we won’t go into further detail here.
Stay tuned as we continue our exploration of SAML2 Use Cases.