SAML & Single Sign-On
Dr. Dobb's Journal November 2003
An XML-based language for authentication
By S. Srivatsa Sivan
S. Srivatsa Sivan is a senior software engineer for HP's India Software Operations. He can be contacted at srivatsa.sivan [email protected]
Single Sign-On (SSO) refers to the ability of a system to authenticate users once, then subsequently authorize or reject those users across multiple services. Web applications and web services that provide access and interaction between multiple disparate applications and services require SSO functionality, and one approach to providing it is through use of the Security Assertions Markup Language (SAML); http://www.oasis-open.org/committees/security/.
Developed under the auspices of OASIS (a nonprofit, international standards group), SAML is an XML framework for exchanging authentication/authorization information. SAML includes XML schemas that define the information exchanged, as well as the protocols for requesting and responding to these messages.
SAML elements describe both "subjects," which exchange information on the network, and "assertions," which include information about the subjects (who the subjects are, what they can do, and/or what information can be exchanged). SAML defines assertions for authentication, authorization, and attributes.
In this article, I use SAML to implement SSO for a hypothetical web portal (portal.com) offering services to customers. These services include content services that need SSO to retain the consistency desired by the web portal. The web portal uses SAML to convince the external service of the authenticity and authorization of users on the web portal. In this way, the external service can decide whether to honor the web portal's assertions during its own authentication/authorization process.
Included in the content-based services that portal.com offers are third-party content services, such as a greeting service from greetings.com. If authentication occurred at portal.com and is passed to greetings.com (through SAML), then greetings.com is satisfied with the authentication that has already happened in portal.com. In other words, portal.com acts as the SAML assertion producer and greetings.com as the SAML assertion/relying consumer; see Figure 1.
For starters (see step 1, Figure 1), customers use browsers to access portal.com via HTTP requests shown in Listing One. Since portal.com requires authentication (step 2), you should assume that the site uses a password mechanism for authentication and presents a login page to users. The HTTP message looks similar to Listing Two.
Customers then fill in and submit the login form with a username/password (step 3); see Listing Three. At portal.com, authentication is done for the given username/password (step 4). If authentication passes, users are shown a list of available services (Listing Four), including greetings.com. The href portion of the link in Listing Four points to a service called AssertionCreator, which is present in the portal.com domain. The chosen service's URL, (http://www.greetings.com/) is passed to the AssertionCreator service as part of the query string. Customers then select the greetings service (step 5), the request is forwarded to AssertionCreator, and the destination service URL is sent along with the request as part of the URL query string.
The real SAML part starts at the AssertionCreator service (step 6). When the greetings service is chosen, the request is forwarded to the AssertionCreator service with the destination service's URL as part of the query string. This service creates the authentication assertion for customers (Listing Five), based on the authentication information they used for login. AssertionCreator also creates a unique random SAML token, called an "artifact," which is associated with the created assertion.
The SAML authentication assertion has three broad parts:
- The inner part of the assertion is common to all assertions. This portion contains details about which versions of SAML are being used and what version is acceptable (<MajorVersion> and <MinorVersion>), who the issuer of the assertion is (<Issuer>), and when the assertion is/was issued (<IssuerInstant>).
- A set of conditions applies to the assertions. The conditions have to be validated to True for the assertion to be relied upon. If conditions are not valid, then the issuing authority cannot be held responsible for the validity of the assertion. Here, the condition is that the assertion is valid only between the <NotBefore> and <NotOnOrAfter> time period. Also, the <Assertion> is valid only for the specified audience contained in the <Audience> element.
- Information about the authentication includes details about the subject who was authenticated (<NameIdentifier>) and what the method of authentication was (<AuthenticationMethod>).
The <ConfirmationMethod> element is a URI reference that specifies that the browser/artifact profile is used for this assertion.
The assertion does not contain the password because the receiver of the assertion (greetings.com) trusts the authentication that has happened with the issuing authority (portal.com). Consequently, the assertion receiver (greetings.com) need not perform any further authentication. This frees SAML from any underlying authentication mechanism.
This assertion is created and stored against an Assertion artifacta unique random number that is used by the relying party to retrieve the assertion. After creating the assertion and artifact, the AssertionCreator service forwards the request to the destination URL (http://www.greetings .com/) with the artifact as part of the query string; see Listing Six.
Upon receiving the request with the SAML assertion artifact, greetings.com retrieves the artifact (step 7). Then, greetings.com has to send a request to portal.com to get the assertions corresponding to the artifact. The Simple Object Access Protocol (SOAP) request sends this SAML protocol request to portal.com (Listing Seven).
The SAMLProtocol request, embedded in a SOAP message to portal.com, consists of three main parts:
- Common attributes, which contain details about the common attributes of the SAML protocol. The common attributes could be the version of the SAML protocol that is being used and what version is acceptable (<MajorVersion> and <MinorVersion>), and the time when this request was issued (<IssueInstant>).
- AssertionArtifact, which consists of the assertion artifact that was received by greetings.com.
- RespondWith, which defines what the requesting site (greetings.com) is expecting in reply to this request.
An optional <ds:Signature> element lets you include digital signatures, thereby making the requests and assertions more secure.
Upon receiving the SOAP message requesting assertions, portal.com retrieves the Assertion artifact from the message (step 8). It uses this artifact to retrieve the assertion it created in step 6 corresponding to this artifact. It then sends this assertion to greetings.com in the form of a SOAP response; see Listing Eight.
The SAML protocol response is embedded in the SOAP message. There are three main parts to the SOAP response.
- SAML protocol's common attributes, which consist of the attributes that are common to the SAML protocol responses. It has information such as the version number (<MajorVersion> and <MinorVersion>), the request ID of the request to which this is a response (<InResponseTo>), the response URL (<Recipient>), and so on.
- Assertion. The actual assertion about the Subject is appended to the message. (This assertion was created in step 6.)
- Status, which gives information about the status of the request.
The SOAP response with the assertion is then sent to greetings.com.
When greetings.com receives the SOAP response containing the assertions, it processes the assertions and finds out who the Subject is and how the Subject was authenticated in portal.com. Based on this information, greetings.com decides if it can allow access to its resources to the Subject.
Assuming that greetings.com accepts the assertions (step 10), the Customer is allowed access to greetings.com. By using SAML, I have transferred authentication information from portal.com to greetings.com (a federated site of portal.com), thereby eliminating the need to log into greeting.com again and, thus, achieving Single Sign-On.
In general, large integrated portals have difficulty in providing SSO functionality because there has been no standard defined for exchanging authentication messages. SAML defines XML formats for such message exchanges. With the introduction of SAML, message exchanges become more standardized, thereby making SSO possible between disparate web entities.
GET http://www.portal.com HTTP 1.0 <other HTTP components >
HTTP 1.0 200 OK Content-type : text/html ContentLength : nnnn <form> <...Login form...> </form> <other HTTP components >
POST http://www.portal.com HTTP 1.0 <form> <username=...... > <password=.......> </form> <other HTTP components >
<html> <body> <....other html components... > <a href=http://www.portal.com/AssertionCreator? serviceURL=www.greetings.com> Greetings Service </a> <a href= other services url > Other Services </a> </body> </html>
<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance AssertionID="VN5zxvNB+vtelx5uiOdbKHtVmH+u" IssueInstant="2002-12-20T06:39:36Z" Issuer="http://www.portal.com" MajorVersion="1" MinorVersion="0" > <saml:Conditions NotBefore="2002-12-20T06:39:35Z" NotOnOrAfter="2002-12-0T06:40:06Z"> <saml:AudienceRestrictionCondition> <saml:Audience>http://www.greetings.com</saml:Audience> </saml:AudienceRestrictionCondition> </saml:Conditions> <saml:AuthenticationStatement AuthenticationMethod = "Password" AuthenticationInstant="2002-12-20T06:39:36Z"> <saml:Subject > <saml:NameIdentifier>Customer'sLoginName</saml:NameIdentifier> <saml:SubjectConfirmation> <saml:ConfirmationMethod> urn:oasis:names:tc:SAML:1.0:cm:artifact-01 </saml:ConfirmationMethod> </saml:SubjectConfirmation> </saml:Subject> </saml:AuthenticationStatement> </saml:Assertion>
GET http://www.greeting.com?SAMLart=<AssertionArtifact> HTTP 1.0 <other http 1.0 components >
POST www.portal.com HTTP1.0 Host: www.greetings.com Content-type : text/xml Content-length : nnnn SOAPAction : http://www.oasis-open.org/committees/security <soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"> <soap-env:Header/> <soap-env:Body> < samlp:Request xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol" IssueInstant="2002-12-20T06:39:40Z" MajorVersion="1" MinorVersion="0" RequestID="0PSbtwzxi03kwCGWhi/wCwN8JMBU"> < samlp:AssertionArtifact> AAP5E18Eyd5Sm2ixiXrk9kaZ92HwMBtedSjAOqZlDqPsRp4NNNwW0R/h </samlp:AssertionArtifact> <samlp:RespondWith> saml:AuthenticationStatement </samlp:RespondWith> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> [Digital Signature Elements] </ds:Signature> </samlp:Request> </soap-env:Body> </soap-env:Envelope>
HTTP /1.0 200 OK Content-type : text/xml Content_Length :nnn <soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"> <soap-env:Header/> <soap-env:Body> <samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol" InResponseTo="0PSbtwzxi03kwCGWhi/wCwN8JMBU" IssueInstant="2002-12-20T06:39:36Z" MajorVersion="1" MinorVersion="0" Recipient=http://www.greetings.com ResponseID="t0isXqwoUc40E0XVnL5/BtZo6y2Y"> <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance AssertionID="VN5zxvNB+vtelx5uiOdbKHtVmH+u" IssueInstant="2002-12-20T06:39:36Z" Issuer="http://www.portal.com" MajorVersion="1" MinorVersion="0" > <saml:Conditions NotBefore="2002-12-20T06:39:35Z" NotOnOrAfter="2002-12-0T06:40:06Z"> <saml:AudienceRestrictionCondition> <saml:Audience> http://www.greetings.com </saml:Audience> </saml:AudienceRestrictionCondition> </saml:Conditions> <saml:AuthenticationStatement AuthenticationMethod = "Password" AuthenticationInstant="2002-12-20T06:39:36Z"> <saml:Subject > <saml:NameIdentifier> CustomerUserName </saml:NameIdentifier> <saml:SubjectConfirmation> <saml:ConfirmationMethod> urn:oasis:names:tc:SAML:1.0:cm:artifact-01 </saml:ConfirmationMethod> </saml:SubjectConfirmation> </saml:Subject> </saml:AuthenticationStatement> </saml:Assertion> <samlp:Status> <samlp:StatusCode Value="samlp:Success"/> </samlp:Status> </samlp:Response> </soap-env:Body> </soap-env:Envelope>