May 18, 2016
TABLE OF CONTENTS
This post continues our series regarding API security and will be the first in a subseries dedicated to the topics of Security Assertion Markup Language (SAML) and JSON Web Tokens (JWTs). These posts will build upon concepts already discussed in the Digital Signature Series and API Security vs. Web Application Series.
The first part of this subseries discusses SAML 2.0 use cases and requirements. Although there are many SAML 2.0 use cases, we’ll focus on the use of SAML 2.0 Bearer Tokens for Web Application single sign-on and with SOAP Web Services and WS-Security, because these are a forebearer to the use of JWT with APIs.
This stuff has been around a while; I gave a presentation at IBM Impact in 2011 on the use of SAML with SOAP Web Services and an Enterprise Service Bus (ESB). I have deployed SOAP-based ESBs in several shops that use SAML 2.0, WS-Trust, and WS-Security as the basis of the security model. When I first saw the JWT, OAuth2, and OpenID Connect specs, I saw something that was similar to what I had been working with and familiar–but, simpler.
SAML is a family of OASIS specifications created by the Security Services Technical Committee that describes an “XML-based framework for communicating user authentication, entitlement, and attribute information” to actors participating in a trust relationship. The Security Services Technical Committee has a motto published on their website:
Defining and maintaining a standard, XML-based framework for creating and exchanging security information between online partners. That sums up nicely what SAML is all about. The SAML specification defines several actors that are present in every use case: Identity Provider (IdP), Relying Party (RP) or Service Provider (SP), and principal. The IdP authenticates principals and issues tokens (or assertions). The SP is an application or resource that is protected and requires authentication and authorization of any principal wishing to access it. The principal (typically a user, though maybe system actor) is an entity that can be authenticated.
Authentication is the process of the principal proving its identity to the system. Authorization is the process by which a protected system (the SP, in this case) makes a decision of whether an authenticated principal is allowed to access the system. Sometimes, the authentication and authorization decisions are offloaded from the Service Provider to an intermediary such as an Enterprise Service Bus (ESB) or Security Gateway.
A SAML 2.0 token or assertion (the term the specification uses) is an XML document that contains (or can contain) information about:
The authenticated principal is generally referred to as a “subject.” and is typically a simple username, a user’s distiniguished name (DN), an email address, or a domain qualified username. This name typically references a user defined in the user repository (LDAP, Active Directory, etc) that is part of the IdP. We’ll talk more about user repositories later.
The security attributes could include role information, LDAP attributes, highly context-specific attributes that are meaningful to the SP, or just about anything else. These security attributes are an example of claims in a claims-based identity system. SAML is an example of an implementation of a claims-based identity system. Claims-based identity provides a common framework for actors, applications, or systems to acquire identity information about users and the issuer (or authority) that issued those claims. In this system, a claim is a statement (think of it as a SAML attribute, the username, group information, or the like for our purposes) that one subject—the issuer—makes about another subject, the principal. We’ll call this the abstraction and theory behind SAML 2.0 and JWT. We’ll come back to claims-based identity down the road.
The SAML 2.0 spec defines a concept called “Subject Confirmation Method.” The most common one is the bearer subject confirmation method. This allows SAML 2.0 assertions to act as bearer tokens. We described bearer tokens extensively here. The subject confirmation method is the mechanism by which an entity provides evidence of the relationship between the subject named in the token and the SAML assertion’s claims. By definition, there are no additional steps needed to establish the relationship between the subject and the claims for bearer tokens. The relationship is implicit, per the spec. You might recall from our earlier discussion of bearer tokens that the really useful ones include a digital signature, which is interesting, since that breaks the notion that the relationship is implicit. But that’s how bearer tokens usually work in the real world. A bearer token with a digital signature is also far more secure than one that is not (but, it does have its limitations).
The other two subject confirmation methods are sender vouches and holder-of-keys. I’ve only used sender vouches in one shop and have never actually used holder-of-keys in the real world.
A couple of years ago, I was in a shop that was using the IBM Integration Stack (including WebSphere DataPower) to integrate SAP and dozens of other Commercial Off The Shelf (COTS) products with Active Directory Federation Server v2.0 (ADFS) as the IdP. The SAP modules in play did not support bearer tokens—only sender vouches and hold-of-key was supported. ADFS did not support sender vouches; DataPower supported all three subject confirmation methods. So, the SOAP Consumer obtained a SAML bearer token from ADFS, made a SOAP call to DataPower, DataPower validated the token and swapped it out for a sender vouches SAML token that it generated, then sent the request with sender vouches token to an SAP Service Provider. I will often use the term “security integration” to describe this type of integration work.
Here is an example of a SAML 2.0 token:
<?xml version="1.0" encoding="UTF-8"?> <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_0" IssueInstant="2016-05-14T00:10:00.123Z" Version="2.0"> <saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">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/2001/04/xmldsig-more#rsa-sha256"/> <ds:Reference URI="#_1"> <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#sha1"/> <ds:DigestValue>M9CyzmcJfLg8JDO48590345f9sfdew0</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> <saml:Subject xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"> <saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">email@example.com</saml:NameID> <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"> <saml:SubjectConfirmationData NotOnOrAfter="2016-05-14T00:15:00.123Z" Recipient="https://app1.levvel.io/login"/> </saml:SubjectConfirmation> </saml:Subject> <saml:Conditions NotBefore="2016-05-14T00:10:00.123Z" NotOnOrAfter="2016-05-14T00:15:00.123Z" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"> <saml:AudienceRestriction xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"> <saml:Audience>https://app1.leevvel.io/login</saml:Audience> </saml:AudienceRestriction> </saml:Conditions> <saml:AttributeStatement> <saml:Attribute Name="givenName"> <saml:AttributeValue>John</saml:AttributeValue> </saml:Attribute> <saml:Attribute Name="surname"> <saml:AttributeValue>Doe</saml:AttributeValue> </saml:Attribute> <saml:Attribute Name="roles"> <saml:AttributeValue>admin</saml:AttributeValue> <saml:AttributeValue>advancedView</saml:AttributeValue> </saml:Attribute> </saml:AttributeStatement> <saml:AuthnStatement AuthnInstant="2016-05-14T00:10:00.123Z" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"> <saml:AuthnContext xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"> <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml:AuthnContextClassRef> </saml:AuthnContext> </saml:AuthnStatement> </saml:Assertion>
Obviously, this is an XML document. It’s top-level element is called Assertion (hence, the name SAML Assertion). I will also refer to this as a SAML token on occasion, though this isn’t taken from the spec. Below are the sub-elements and their function, in order:
The SAML 2.0 spec addresses authentication and authorization concerns. From a practical standpoint, however, there is almost always additional information placed in the Assertion and additional processing steps needed for the Authorization step beyond what the spec defines in all but the most trivial of use cases. One such case is Web App Single Sign-On, where any authenticated user is allowed to access the web application. A very common example of additional information that needs to be passed as custom claims (SAML Attributes) in SAML 2.0 bearer tokens is role information, or a list of groups of which the principal is a member. Defining and processing the authorization policy that maps the SP’s resources to specific roles or other claims is a separate topic.
Numerous edge cases and optional features exist in the SAML 2.0 family of specs that I won’t get into here. For the most part, they are not important to our discussion. It is important, however, to remember that the SAML 2.0 spec is very flexible and has numerous optional pieces. Likewise, some pieces of the spec can be a bit vague and open to interpretation. In other words, the SAML 2.0 token with which you may be dealing could look almost exactly like the one above or look different in multiple places.
I always try to give the history behind how things got to be the way they are because I find this helpful in understanding both the larger picture and how the individual pieces fit into it. Without the backstory, it will be difficult to understand what motivated the creators of the latest thing (in this case, JWT). The history of SAML2, WS-Security, and WS-Trust is filled with complexity and frustration; the writers of the JWT, OAuth2, and OpenID Connect specs were very familiar with these difficulties. SAML builds on top of the XML, XSD, XML Signature, XML Encryption, HTTP, and SOAP specifications.
The SAML 1.0 spec was published in November, 2002. Shortly after that, the SAML 1.1 specification was published in September, 2003. Around this same time, the Liberty Alliance was producing a body of work that extended SAML 1.0 that eventually formed the basis of SAML 2.0. The SAML 2.0 specification was published in March, 2005. I won’t cover the details of SAML 1.0, since it is not commonly used at this point, though I have seen SAML 1.1 Assertion in use in a production environment within the past year. SAML 2.0 is much more commonplace, however.
SAML 1.1 and 2.0 are not a single spec, but rather a family of inter-related specs. I’m dumping the list straight from the Oasis website in this section; not terribly creative, but it prevents me from having to go look this stuff up constantly. I will reference this periodically throughout this series. Today, SAML 2.0 is the workhorse of Federation and SSO throughout most large enterprises. It is beginning to be supplanted by OAuth 2.0 and OpenID Connect..
From the OASIS Website, we have:
The approved specification set consists of:
The original approved specification set (without errata markup) consists of:
In the next post, we will begin looking at the various use cases for SAML v2.0 and examples of each. This part of the SAML topic is admittedly not very interesting, but it serves as a very important first step toward our eventual goal of a detailed comparison of SAML v2.0 and JWT. These first couple posts on the topic should also serve as a useful introduction to those who are unfamiliar with the topic. Stay tuned; there is much more to come on the topic of SAML & JWT.
Robert C. Broeckelmann Jr.
At the end of lunch with a mentee, I used the items on our table to express the fundamental concepts of Kubernetes. Sometime after explaining the purpose of the Kubernetes scheduler, she asked a question I spent the next several weeks thinking about.
API design is crucial, giving structure to application interaction. Given cross-functional teams and applications, development time is reduced with a clear, intuitive way to access data. API development often follows two approaches: REST and GraphQL.
As of June 2018, the state of California passed a new privacy law that could lead to more consequences for US-based companies than the European Union’s General Data Protection Regulation (GDPR). Here's what you need to know and how to be compliant.
Before your data scientists wring value out of your reams of data, it has to be accessible and, on some basic level, coherently arranged. To harness all that brainpower, you need to keep the data wrangling to a minimum. Enter the data lake.