Return-Path: X-Original-To: apmail-cxf-commits-archive@www.apache.org Delivered-To: apmail-cxf-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 4C231EA7F for ; Sun, 3 Mar 2013 19:48:32 +0000 (UTC) Received: (qmail 90070 invoked by uid 500); 3 Mar 2013 19:48:32 -0000 Delivered-To: apmail-cxf-commits-archive@cxf.apache.org Received: (qmail 90014 invoked by uid 500); 3 Mar 2013 19:48:32 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 90007 invoked by uid 99); 3 Mar 2013 19:48:32 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 03 Mar 2013 19:48:32 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 03 Mar 2013 19:48:30 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 55F4C238889B for ; Sun, 3 Mar 2013 19:48:11 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r852831 - in /websites/production/cxf/content: cache/docs.pageCache docs/jaxrs-oauth2-assertions.html Date: Sun, 03 Mar 2013 19:48:11 -0000 To: commits@cxf.apache.org From: buildbot@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20130303194811.55F4C238889B@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: buildbot Date: Sun Mar 3 19:48:10 2013 New Revision: 852831 Log: Production update by buildbot for cxf Modified: websites/production/cxf/content/cache/docs.pageCache websites/production/cxf/content/docs/jaxrs-oauth2-assertions.html Modified: websites/production/cxf/content/cache/docs.pageCache ============================================================================== Binary files - no diff available. Modified: websites/production/cxf/content/docs/jaxrs-oauth2-assertions.html ============================================================================== --- websites/production/cxf/content/docs/jaxrs-oauth2-assertions.html (original) +++ websites/production/cxf/content/docs/jaxrs-oauth2-assertions.html Sun Mar 3 19:48:10 2013 @@ -125,7 +125,7 @@ Apache CXF -- JAXRS OAuth2 Assertions +

Introduction

@@ -242,7 +242,203 @@ ClientAccessToken at = OAuthClientUtils. -

Authentication Token

+

Authentication Token

+ +

As noted in the introduction, SAML2 Bearer assertions may also act as client authentication credentials, when requesting an access token, irrespectively of the actual grant type. For example:

+ +
+
+POST /token HTTP/1.1
+Content-Type: application/x-www-form-urlencoded
+
+grant_type=authorization_code
+&code=12345678
+&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Asaml2-bearer
+&client_assertion=Base64UrlEncoded-SAML2-Bearer-Assertion
+
+
+ +

Note "client_assertion_type" with a value "urn:ietf:params:oauth:client-assertion-type:saml2-bearer" indicates that the type of assertion used as an authentication token is "urn:ietf:params:oauth:client-assertion-type:saml2-bearer", while the "client_assertion" parameter carries the actual value of the token.

+ +

Client Code

+ +

The following example shows how to use SAML2 Bearer assertion as an authentication token:

+ +
+
+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.oauth2.saml.Base64Utility;
+import org.apache.cxf.rs.security.oauth2.saml.Constants;
+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. Base64Url-encode it
+String encodedAssertion = Base64UrlUtility.encode(assertion);
+        
+Map<String, String> extraParams = new HashMap<String, String>();
+extraParams.put(Constants.CLIENT_AUTH_ASSERTION_TYPE, Constants.CLIENT_AUTH_SAML2_BEARER);
+extraParams.put(Constants.CLIENT_AUTH_ASSERTION_PARAM, encodedAssertion);
+
+// Use whatever token grant is required 
+AccessTokenGrant accessTokenGrant = ...
+       
+ClientAccessToken at = OAuthClientUtils.getAccessToken(wc, 
+                                                       accessTokenGrant,
+                                                       extraParams);
+
+
+ +

The above code is similar to the example when SAML2 Bearer assertion is used as a grant except that this time the assertion is Base64Url-encoded in the code - note steps 2 and likely 3 will not be required when the assertion came from IP.
+Next, the encoded assertion is used as part of the token request payload, note that it does not matter what grant type is actually used.

+ +

A different approach to dealing with the assertion directly in the client code is to use org.apache.cxf.rs.security.oauth2.auth.saml.Saml2BearerAuthOutInterceptor interceptor which will add the assertion to the existing form payload, for example:

+ +
+
+JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
+
+Map<String, Object> properties = new HashMap<String, Object>();
+properties.put("ws-security.callback-handler", 
+               "org.apache.cxf.systest.jaxrs.security.saml.KeystorePasswordCallback");
+properties.put("ws-security.saml-callback-handler", 
+               "org.apache.cxf.systest.jaxrs.security.oauth2.SamlCallbackHandler2");
+properties.put("ws-security.signature.username", "alice");
+properties.put("ws-security.signature.properties", CRYPTO_RESOURCE_PROPERTIES);
+properties.put("ws-security.self-sign-saml-assertion", "true");
+bean.setProperties(properties);
+        
+bean.getOutInterceptors().add(new Saml2BearerAuthOutInterceptor());
+        
+WebClient wc = bean.createWebClient();
+wc.type(MediaType.APPLICATION_FORM_URLENCODED).accept(MediaType.APPLICATION_JSON);
+
+// Use whatever token grant is required 
+AccessTokenGrant accessTokenGrant = ...
+       
+ClientAccessToken at = OAuthClientUtils.getAccessToken(wc, 
+                                                       accessTokenGrant);
+
+
+ +

Access Token Service

+ +

Here is how one may configure Access Token Service:

+ +
+
+<bean id="dataProvider" class="org.apache.cxf.systest.jaxrs.security.oauth2.OAuthDataProviderImpl"/>
+<bean id="oauthJson" class="org.apache.cxf.rs.security.oauth2.provider.OAuthJSONProvider"/>
+<bean id="samlAuthHandler" class="org.apache.cxf.rs.security.oauth2.auth.saml.Saml2BearerAuthHandler"/>
+
+<bean id="serviceBean" class="org.apache.cxf.rs.security.oauth2.services.AccessTokenService">
+  <property name="dataProvider" ref="dataProvider"/>
+  <property name="grantHandlers">
+     <list>
+       <!-- list of required grant handlers -->
+     </list>
+  </property>
+</bean>
+
+<jaxrs:server 
+       address="https://localhost:${testutil.ports.jaxrs-oauth2}/oauth2-auth"> 
+       <jaxrs:serviceBeans>
+          <ref bean="serviceBean"/>
+       </jaxrs:serviceBeans>
+       <jaxrs:providers>
+          <ref bean="oauthJson"/>
+          <ref bean="samlAuthHandler"/>
+       </jaxrs:providers>
+       
+       <jaxrs:properties>
+           <entry key="ws-security.signature.properties" 
+                  value="org/apache/cxf/systest/jaxrs/security/alice.properties"/>
+       </jaxrs:properties>
+        
+</jaxrs:server>
+
+
+ +

Client Acting on Behalf of Itself

+ +

In the Client Acting on Behalf of Itself use either org.apache.cxf.rs.security.oauth2.grants.saml.Saml2BearerClientCredentialsGrant :

+ +
+
+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.Saml2BearerClientCredentialsGrant;
+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();
+
+AccessTokenGrant accessTokenGrant = new Saml2BearerClientCredentialsGrant(assertion);
+       
+ClientAccessToken at = OAuthClientUtils.getAccessToken(wc, 
+                                                       accessTokenGrant,
+                                                       extraParams);
+
+
+ +

or ClientCredentialsGrant in combination with Saml2BearerAuthOutInterceptor:

+ +
+
+JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
+
+Map<String, Object> properties = new HashMap<String, Object>();
+properties.put("ws-security.callback-handler", 
+               "org.apache.cxf.systest.jaxrs.security.saml.KeystorePasswordCallback");
+properties.put("ws-security.saml-callback-handler", 
+               "org.apache.cxf.systest.jaxrs.security.oauth2.SamlCallbackHandler2");
+properties.put("ws-security.signature.username", "alice");
+properties.put("ws-security.signature.properties", CRYPTO_RESOURCE_PROPERTIES);
+properties.put("ws-security.self-sign-saml-assertion", "true");
+bean.setProperties(properties);
+        
+bean.getOutInterceptors().add(new Saml2BearerAuthOutInterceptor());
+        
+WebClient wc = bean.createWebClient();
+wc.type(MediaType.APPLICATION_FORM_URLENCODED).accept(MediaType.APPLICATION_JSON);
+
+// Use whatever token grant is required 
+AccessTokenGrant accessTokenGrant = new ClientCredentialsGrant();
+       
+ClientAccessToken at = OAuthClientUtils.getAccessToken(wc, accessTokenGrant);
+
+