SAML Profiles for OAuth

From IIW

Session: Tuesday Session 4 Space H

Conference: IIW 10 May 17-19, 2009 this is the complete Complete Set of Notes

Overview

At IIW 2010a, a small group gathered to discuss use-cases we've been seeing for using OAuth 2 together with SAML. The following attempts to capture the essence of that discussion, as well as additional conversations I've had with people throughout the industry. In short, a number of us are seeing real use-cases, and real customer demand; there is even some prior art to learn from in early WRAP deployments. Hopefully this can act as a catalyst for formalized profiling within the community as to avoid fragmentation.

Exchanging a SAML Assertion for an OAuth Token

While OAuth 2 provides a basic Assertion Flow, it's real intent is to provide a pattern for message exchange; the flow itself is somewhat useless without further profiling, or at least a private understanding between the various parties in the OAuth exchange. It's clear that a profile of the assertion flow for use with SAML is required if we are to hope for interop and vendor software to emerge. First a use-case.

Use-Case:

A company has an existing relationship with cloud service provider. In order to provide improved control over credentials used to access the service, as well as a simplified user experience, the company and service provider have established web single sign-on using the Web SSO Profile of SAML 2. With the company acting as an IDP, their users are easily provided access to the service without exposing their corporate password, or managing new credentials.

The company now wishes to establish integration with data services that act on the user's behalf; for instance syncing calendar and contact information. While a traditional 3-legged flow of OAuth 2 could be used to establish individual access or refresh tokens, the company wishes to perform this synchronization as a back-office process on a nightly basis. Given an existing trust relationship has been established by the company it is neither required, nor desired to have all of their users perform the OAuth dance to establish these tokens; rather the company would like to use a signed SAML assertion to interact with the API. (Note this is conceptually similar to 2-legged OAuth: [1]) In turn, the service provider would prefer the simplicity and consistency of simple OAuth 2 bearer tokens be used for access to all their services.

Using the SAML profile of the OAuth 2 Assertion flow, the company is able to rapidly write a integration client. This client fetches a SAML assertion from their IDP software, and presents it to the service providers Authorization Server. Having previously establish a trust relationship through the exchange of SAML metadata, the Authorization server validates the signature and contents of the assertion, and issues a access_token on behalf of the subject of the assertion. The company is than able to impersonate the user with the service providers data services, acting on their behalf. The company syncs the user's calendar and contacts, and disposes of the access token. Subsequent access uses a new SAML assertion, rather an refresh_tokens as to maintain the existing trust relationship (refresh tokens would essentially bootstrapo a new trust relationship )

Presented as swim lanes, the exchange might look like this:

SAMLAssertionFlow.png

Design Goals for profiling the Assertion Flow

1) Attempt to match the simplicity of OAuth 2: While SAML can be complex when you view the specification as a whole, focus must be placed on profiling a thin and simple path. Initial emphasis is placed on bearer-tokens.

2) Piggy back on the relative success of Web SSO: The Web SSO Profiles are the most broadly deployed and well understood aspect of SAML, and of these, the HTTP POST Binding is arguably the most popular, as well as the closest in nature to the assertion flow. Modeling the profile after these proven deployments likely provides the shortest path to working code, leverage of existing software, and existing methods of trust establishment. While this last subject requires improvement, this is a broader issue that this profile would benefit from.


Proposal

The SAML Assertion Flow Profile builds upon the Assertion Flow by specifying the exact format and assertion values to be used with SAML 2.0. Specifically, it is intended to provide interoperability with the SAML 2.0 Web Browser SSO Profile [2] and the SAML HTTP POST Binding [3] by allowing the authorization server to process SAML assertions with the same format and characteristics as those used in SAML Web SSO.

format: “urn:oasis:names:tc:SAML:2.0:profiles:oauth2:assertion”

assertion: The value of the assertion parameter MUST contain a valid SAML Assertion. The SAML Assertion MAY be enclosed in a valid SAML Response. If enclosed in a SAML Response, the Assertion MAY inherit it’s signature from the Response per SAML Core 5.3. The value of the parameter MUST be form-encoded by applying the base-64 encoding rules to the XML representation of the message. The base64-encoded value MAY be line-wrapped at a reasonable length in accordance with common practice.

As with SAML web SSO, the assertions used in this profile are one time use assertions. The mechanism by which the client obtains the assertion is out of scope for this profile.

All protocol, assertion format, and processing rules that are defined by the SAML 2.0 Web Browser SSO Profile, and scoped by the SAML HTTP POST Binding MUST be adhered to in this profile, with the following clarifications and exceptions:

  • The authorization server MUST accept unsolicited SAML <Response> messages. AuthnRequest messages MAY be used, but their usage is left unspecified by this profile
  • RelayState data is omitted from this Profile
  • The form-encoding specified by the POST binding is superseded by the assertion_request message defined in section 3.6.2

For example, the client makes the following HTTPS request (line breaks are for display purposes only):

    POST /authorize HTTP/1.1
    Host: server.example.com
    type=assertion_request&client_id=s6BhdRkqt3&format=uurn:oasis:names:tc:SAML:2.0:profiles:oauth2:assertion&assertion=PHNhbWxwOl...[ommited for brevity]...ZT4%3D
 

The response is a standard OAuth 2 response


Protocol for Clients Requesting SAML Assertions

The previous section covered how a client would use a SAML assertion over the OAuth 2 assertion flow, and the related processing rules. However, it did not specify protocol for obtaining an assertion. There are a variety of mechanisms by which an assertion may be obtained by the client

Self Issued: The client may be intelligent enough to issue it's own SAML assertions directly. It should be noted that this is only appropriate for clients where the private key may be appropriately secured.

Active Clients: This client is intelligent, and knows how to interact with it's IDP in order to authenticate and obtain an assertion for the subject using the client.

  • WS-Trust - an enterprise may want to use this internally
  • OAuth2 - an OAuth 2 flow could be used between the client and the IDP - basically the same as WS-Trust but loosely "restful"
  • The company IdP server acts as a intermediary (of sorts) between the client and the cloud authorization server. Client requests access token from IdP SAML Gateway and Authorization Server using something like Username and Password Flow or Client Credentials Flow. IdP validates the request and generates a SAML assertion that it sends to the cloud Authorization Server using an Assertion Flow. The access token is passed back all the way to the client.
  • Some profile of SAML similar to ECP?

NEED SUGGESTIONS IN THIS SECTION

Passing OAuth Responses over SAML

In addition to the classic STS pattern that the assertion flow defines, there is desire to provide optimized exchanges of OAuth tokens, piggybacking on SAML as a transport and pre-established trust mechanism. This is conceptually similar to the OpenID + OAuth flow defined here: [ http://step2.googlecode.com/svn/spec/openid_oauth_extension/latest/openid_oauth_extension.html ]

Use Case: "IDP knows the SP is going to want a token"

A Cloud Application is assembling a application market place, where related business applications ( Connected Application ) will be able to integrate with the main application through single sign-on and data services. ( Note existing examples of this include Google Apps Marketplace, Intuit Marketplace, Salesforce AppExchange, etc) As part of this marketplace, the Cloud Application will be acting as an SAML IDP to the Connected Application acting as a SAML Service Provider, and the connected application will be accessing data services at the IDP using OAuth. Technically you have an IDP (SAML) which is also a Authorization Server(OAuth2), and a Service Provider (SAML) which is also a Client (OAuth2)

When a developer launches a new Connected Application in the marketplace, they've established the appropriate SAML metadata to allow for single sign-on between the IDP and the SP. When an admin installs the Connected Application into the their tenant in the multi-tenant Cloud Application, they explicitly grant permission for the Connected Application to access protected resources. This delegates authority for all users to the application.

When a user logs into the Cloud Application, they see a list of Connected Applications they have access to. The user clicks on a link from this list, which kicks of a SAML exchange between the two parties. When a SAML Response is sent to the Connected Application, it includes a OAuth Response as part of an Attribute Assertion. This response includes an access token ( and optional response token ) is valid for the subject of the assertion, and for the resources which the admin granted permission for.

The Connected Application receives the SAML Assertion, processes it, establishes session for the user, and uses the oauth token to call protected resources in order to personalize the experience for the user. No subsequent user level delegation or oauth dance is required.

Presented as swim lanes, the exchange might look like this:

GiveOAuthResponse.png


Proposal

It is known by the IDP/Authorization Server that a SP/client requires an access_token in order to act on-behalf of a user. In addition the IDP may choose to issue a refresh_token. The manner by which this is known, and the trust between the two is out of scope.

When the IDP generates the SAML assertion, it includes an Attribute statement, with an attribute conforming to the xml format of the OAuth 2 specification.


Option 1:

		<saml:AttributeStatement>
			<saml:Attribute Name="access_token" xmlns:oauth="TBD based on oauth spec">
				<saml:AttributeValue xsi:type="xs:string">SlAV32hkKG</saml:AttributeValue>
			</saml:Attribute>
			<saml:Attribute Name="refresh_token" xmlns:oauth="TBD based on oauth spec">
				<saml:AttributeValue xsi:type="xs:string">8xLOxBtZp8</saml:AttributeValue>
			</saml:Attribute>
		</saml:AttributeStatement>



Option 2:

		<saml:AttributeStatement>
			<saml:Attribute Name="oauth_response" xmlns:oauth="TBD based on oauth spec">
			<saml:AttributeValue>
				<oauth:OAuth>
					<oauth:access_token>SlAV32hkKG</access_token>
					<oauth:refresh_token>8xLOxBtZp8</refresh_token>
 				</oauth:OAuth>
			</saml:AttributeValue>
			</saml:Attribute>
		</saml:AttributeStatement>


Requesting OAuth Tokens via SAML

There is also some need for the reverse of the previous use case - the IDP is an OAuth Client, and needs to access services on the user's behalf.

Use Case: “I want to log the user in, and access protected resources at the Service Provider, without requiring their password”

NOTE: This use-case is essentially the same as the first use-case, but rather than using the Assertion Flow, it is simply an optimization of the existing 3 legged OAuth Flow.

A company has an existing relationship with cloud service provider. In order to provide improved control over credentials used to access the service, as well as a simplified user experience, the company and service provider have established web single sign-on using the Web SSO Profile of SAML 2. With the company acting as an IDP, their users are easily provided access to the service without exposing their corporate password, or managing new credentials.

The company now wishes to establish integration with data services that act on the user's behalf; for instance syncing calendar and contact information. In order to do this, they will negotiate access_tokens and refresh_tokens individually for each user that they send to the service provider. Since the user's login to the service provider via SAML, the flow to both authenticate the user and issue OAuth tokens is quite complex - if the OAuth redirect is done first, the user must be authenticated, so they are sent back to the IDP. If the user authenticates first, the SP needs to know to send the user back to the IDP to start the OAuth dance. The company and service provider would like an optimized flow for both logging the user into the service provider and accessing the OAuth token.

Proposal

In order to do this:

  • A SAML Response is sent over Web SSO Profile to the Service Provider. It includes a Relay State of an oauth authorization request
  • The SAML is processed, session is established, and the client is redirected to authorization URL included in the relay state.
  • Since the Session is already established, the user only needs to grant access to the service
  • User is returned to IDP in a regular OAuth flow
  • The IDP gets it's access_token/refresh_token and sends the user on their way to the service

		<form method="post" action="https://sp.example.com/SAML2/SSO/POST" ...>
			<input type="hidden" name="SAMLResponse" value="Base64 encoded response" />
			<input type="hidden" name="RelayState" value="https://sp.example.com/authorize?type=web_server&client_id=s6BhdRkqt3&redirect_uri=https%3A%2F%2Fidp%2Ecom%2Fcb" />
			<input type="submit" value="Submit" />
 		</form>

This basically works already with existing software


What's next

Who should be involved?

If you've made it this far, than perhaps you.

What are the right profiles?

I've seen use-cases for these. What others exist?

Where is the right place for this work?

IETF? OASIS?