Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Wiki Markup
{span:style=font-size:2em;font-weight:bold} JAX-RS: OAuth2 Assertions {span}


{toc}

h1. Introduction

[OAuth 2.0|http://tools.ietf.org/html/draft-ietf-oauth-v2] supports different types of access token grants. [OAuth2 Assertions|http://tools.ietf.org/html/draft-ietf-oauth-assertions-10] draft "provides a framework for the use of assertions
with OAuth 2.0" and [SAML2 Bearer Assertion Profiles for OAuth2|http://tools.ietf.org/html/draft-ietf-oauth-saml2-bearer-15] draft specifically provides for the use of SAML2 Bearer assertions.

These assertions can be used as token grants, but also, if needed, for getting 3rd party clients authenticated. Note the clients can use assertions as grants but use for example Basic authentication mechanism, or use say an authorization code grant and the assertion to authenticate, and finally, they can use assertions as a grant and as an authentication token.

Currently CXF supports SAML2 Bearer assertions as grants and authentication tokens.

See also the [JAX-RS OAuth2] page for information about OAuth 2.0 support in CXF.

h1. SAML2 Bearer

h2. Access Token Grant

[This section|http://tools.ietf.org/html/draft-ietf-oauth-saml2-bearer-15#section-2.1] explains how SAML2 Bearer assertions can be used as token grants. The value of grant_type parameter is "urn:ietf:params:oauth:grant-type:saml2-bearer".


It is really just another grant type, but whose actual value is a SAML assertion. The specification provides an [example|http://tools.ietf.org/html/draft-ietf-oauth-saml2-bearer-15#section-4] of how such an assertion may look like.

The additional restriction is that the assertions have to be encoded using Base64Url encoding. 
Here is how a request may look like:

{code}
POST /token HTTP/1.1
Content-Type: application/x-www-form-urlencoded

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Asaml2-bearer&
assertion=Base64UrlEncoded-SAML2-Bearer-Assertion
{code}

h3. Client code

The following example shows how to use SAML2 Bearer assertion as a grant with CXF OAuth2 client code:

{code:java}
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.rs.security.common.CryptoLoader;
import org.apache.cxf.rs.security.oauth2.client.OAuthClientUtils;
import org.apache.cxf.rs.security.oauth2.common.AccessTokenGrant;
import org.apache.cxf.rs.security.oauth2.common.ClientAccessToken;
import org.apache.cxf.rs.security.oauth2.grants.saml.Saml2BearerGrant;
import org.apache.cxf.rs.security.saml.SAMLUtils;
import org.apache.cxf.rs.security.saml.SAMLUtils.SelfSignInfo;
import org.apache.ws.security.components.crypto.Crypto;

//1: create web client
String address = "https://localhost:8080/oauth2/token";
WebClient wc = WebClient.create(address);
wc.type(MediaType.APPLICATION_FORM_URLENCODED).accept(MediaType.APPLICATION_JSON);

//2. Create and self-sign SAML assertion        
Crypto crypto = new CryptoLoader().loadCrypto(CRYPTO_RESOURCE_PROPERTIES);
SelfSignInfo signInfo = new SelfSignInfo(crypto, "alice", "password"); 
        
String assertion =  SAMLUtils.createAssertion(new SamlCallbackHandler(),
                                              signInfo).assertionToString();

//3. Send it as a token grant to Access Token Service and get some access token back
AccessTokenGrant grant = new Saml2BearerGrant(assertion);
ClientAccessToken at = OAuthClientUtils.getAccessToken(wc, 
                                                       new OAuthClientUtils.Consumer("alice", "alice"), 
                                                       grant,
                                                       false);
{code}

The code above prepares an info for a new SAML assertion be self-signed, loading a Crypto instance with crypto [properties|http://svn.apache.org/repos/asf/cxf/trunk/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/alice.properties], and uses SAMLUtils to create and sign the assertion (using Crypto, plus user alias and password). Saml2BearerGrant will get the assertion Base64Url-encoded.

This is nearly as simple as using other token grants, the step 2 will often me omitted in more involved cases as it will be the job of Identity Providers to issue OAuth2 SAML2 Bearer assertions. Step 2 needs to be done when testing or when getting client acting [on behalf of itself|http://tools.ietf.org/html/draft-ietf-oauth-assertions-10#section-6.2] for example. 
  
When doing step 2, the main effort is to do with getting a SAML assertion populated - use a SAML callback handler like [this one|http://svn.apache.org/repos/asf/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/SamlCallbackHandler.java], it is actually quite easy to build the assertion.

h3. Access Token Service

Here is how one may configure Access Token Service:

{code:xml}
<bean id="dataProvider" class="org.apache.cxf.systest.jaxrs.security.oauth2.OAuthDataProviderImpl"/>
<bean id="samlGrantHandler" class="org.apache.cxf.rs.security.oauth2.grants.saml.Saml2BearerGrantHandler">
  <property name="dataProvider" ref="dataProvider"/>
</bean>
<bean id="oauthJson" class="org.apache.cxf.rs.security.oauth2.provider.OAuthJSONProvider"/>

<bean id="serviceBean" class="org.apache.cxf.rs.security.oauth2.services.AccessTokenService">
  <property name="dataProvider" ref="dataProvider"/>
  <property name="grantHandlers">
     <list>
       <ref bean="samlGrantHandler"/>
     </list>
  </property>
</bean>

<jaxrs:server address="https://localhost:${testutil.ports.jaxrs-oauth2}/oauth2">
   <jaxrs:serviceBeans>
      <ref bean="serviceBean"/>
   </jaxrs:serviceBeans>
   <jaxrs:providers>
      <ref bean="oauthJson"/>
   </jaxrs:providers>
   <jaxrs:properties>
     <entry key="ws-security.signature.properties" value="org/apache/cxf/systest/jaxrs/security/alice.properties"/>
   </jaxrs:properties>
</jaxrs:server>
{code}


h2. Authentication Token