blob: 90b3aaefe2c2115477632e869abebf725d747ebc [file] [log] [blame]
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<html>
<head>
<link type="text/css" rel="stylesheet" href="/resources/site.css">
<script src='/resources/space.js'></script>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<meta name="keywords" content="business integration, EAI, SOA, Service Oriented Architecture, web services, SOAP, JBI, JMS, WSDL, XML, EDI, Electronic Data Interchange, standards support, integration standards, application integration, middleware, software, solutions, services, CXF, open source">
<meta name="description" content="Apache CXF, Services Framework - JAXRS OAuth2 Assertions">
<link type="text/css" rel="stylesheet" href="/resources/highlighter/styles/shCoreCXF.css">
<link type="text/css" rel="stylesheet" href="/resources/highlighter/styles/shThemeCXF.css">
<script src='/resources/highlighter/scripts/shCore.js'></script>
<script src='/resources/highlighter/scripts/shBrushBash.js'></script>
<script src='/resources/highlighter/scripts/shBrushXml.js'></script>
<script src='/resources/highlighter/scripts/shBrushJava.js'></script>
<script>
SyntaxHighlighter.defaults['toolbar'] = false;
SyntaxHighlighter.all();
</script>
<title>
Apache CXF -- JAXRS OAuth2 Assertions
</title>
</head>
<body onload="init()">
<table width="100%" cellpadding="0" cellspacing="0">
<tr>
<td id="cell-0-0" colspan="2">&nbsp;</td>
<td id="cell-0-1">&nbsp;</td>
<td id="cell-0-2" colspan="2">&nbsp;</td>
</tr>
<tr>
<td id="cell-1-0">&nbsp;</td>
<td id="cell-1-1">&nbsp;</td>
<td id="cell-1-2">
<!-- Banner -->
<div class="banner" id="banner"><div><table border="0" cellpadding="0" cellspacing="0" width="100%"><tr><td align="left" colspan="1" nowrap>
<a shape="rect" href="http://cxf.apache.org/" title="Apache CXF"><span style="font-weight: bold; font-size: 170%; color: white">Apache CXF</span></a>
</td><td align="right" colspan="1" nowrap>
<a shape="rect" href="http://www.apache.org/" title="The Apache Sofware Foundation"><img border="0" alt="ASF Logo" src="http://cxf.apache.org/images/asf-logo.png"></a>
</td></tr></table></div></div>
<!-- Banner -->
<div id="top-menu">
<table border="0" cellpadding="1" cellspacing="0" width="100%">
<tr>
<td>
<div align="left">
<!-- Breadcrumbs -->
<a href="index.html">Index</a>&nbsp;&gt;&nbsp;<a href="restful-services.html">RESTful Services</a>&nbsp;&gt;&nbsp;<a href="jax-rs.html">JAX-RS</a>&nbsp;&gt;&nbsp;<a href="jax-rs-oauth2.html">JAX-RS OAuth2</a>&nbsp;&gt;&nbsp;<a href="jaxrs-oauth2-assertions.html">JAXRS OAuth2 Assertions</a>
<!-- Breadcrumbs -->
</div>
</td>
<td>
<div align="right">
<!-- Quicklinks -->
<div id="quicklinks"><p><a shape="rect" href="http://cxf.apache.org/download.html">Download</a> | <a shape="rect" href="http://cxf.apache.org/docs/index.html">Documentation</a></p></div>
<!-- Quicklinks -->
</div>
</td>
</tr>
</table>
</div>
</td>
<td id="cell-1-3">&nbsp;</td>
<td id="cell-1-4">&nbsp;</td>
</tr>
<tr>
<td id="cell-2-0" colspan="2">&nbsp;</td>
<td id="cell-2-1">
<table>
<tr valign="top">
<td height="100%">
<div id="wrapper-menu-page-right">
<div id="wrapper-menu-page-top">
<div id="wrapper-menu-page-bottom">
<div id="menu-page">
<!-- NavigationBar -->
<div id="navigation"><ul class="alternate"><li><a shape="rect" href="overview.html">Overview</a></li><li><a shape="rect" href="how-tos.html">How-Tos</a></li><li><a shape="rect" href="frontends.html">Frontends</a></li><li><a shape="rect" href="databindings.html">DataBindings</a></li><li><a shape="rect" href="transports.html">Transports</a></li><li><a shape="rect" href="configuration.html">Configuration</a></li><li><a shape="rect" href="debugging-and-logging.html">Debugging and Logging</a></li><li><a shape="rect" href="tools.html">Tools</a></li><li><a shape="rect" href="restful-services.html">RESTful Services</a></li><li><a shape="rect" href="wsdl-bindings.html">WSDL Bindings</a></li><li><a shape="rect" href="service-routing.html">Service Routing</a></li><li><a shape="rect" href="dynamic-languages.html">Dynamic Languages</a></li><li><a shape="rect" href="ws-support.html">WS-* Support</a></li><li><a shape="rect" href="advanced-integration.html">Advanced Integration</a></li><li><a shape="rect" href="deployment.html">Deployment</a></li><li><a shape="rect" href="schemas-and-namespaces.html">Use of Schemas and Namespaces</a></li></ul><hr><ul class="alternate"><li><p>Search</p></li></ul><form enctype="application/x-www-form-urlencoded" method="get" id="cse-search-box" action="http://www.google.com/cse">
<div>
<input type="hidden" name="cx" value="002890367768291051730:o99qiwa09y4">
<input type="hidden" name="ie" value="UTF-8">
<input type="text" name="q" size="21">
<input type="submit" name="sa" value="Search">
</div>
</form>
<script type="text/javascript" src="http://www.google.com/cse/brand?form=cse-search-box&amp;lang=en"></script><hr><ul class="alternate"><li><a shape="rect" href="http://cxf.apache.org/javadoc/latest/">API 3.2.x (Javadoc)</a></li><li><a shape="rect" href="http://cxf.apache.org/javadoc/latest-3.1.x/">API 3.1.x (Javadoc)</a></li><li><a shape="rect" href="http://cxf.apache.org/">CXF Website</a></li></ul><p>&#160;</p><p><a shape="rect" class="external-link" href="http://www.apache.org/events/current-event.html"><span class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image confluence-external-resource" src="http://www.apache.org/events/current-event-125x125.png" data-image-src="http://www.apache.org/events/current-event-125x125.png"></span></a></p></div>
<!-- NavigationBar -->
</div>
</div>
</div>
</div>
</td>
<td height="100%">
<!-- Content -->
<div class="wiki-content">
<div id="ConfluenceContent"><h1 id="JAXRSOAuth2Assertions-JAXRS:OAuth2Assertions">JAXRS: OAuth2 Assertions</h1><p><style type="text/css">/*<![CDATA[*/
div.rbtoc1636141659354 {padding: 0px;}
div.rbtoc1636141659354 ul {list-style: disc;margin-left: 0px;}
div.rbtoc1636141659354 li {margin-left: 0px;padding-left: 0px;}
/*]]>*/</style></p><div class="toc-macro rbtoc1636141659354">
<ul class="toc-indentation"><li><a shape="rect" href="#JAXRSOAuth2Assertions-JAXRS:OAuth2Assertions">JAXRS: OAuth2 Assertions</a></li><li><a shape="rect" href="#JAXRSOAuth2Assertions-Introduction">Introduction</a></li><li><a shape="rect" href="#JAXRSOAuth2Assertions-SAML2Bearer">SAML2 Bearer</a>
<ul class="toc-indentation"><li><a shape="rect" href="#JAXRSOAuth2Assertions-Mavendependencies">Maven dependencies</a></li><li><a shape="rect" href="#JAXRSOAuth2Assertions-AccessTokenGrant">Access Token Grant</a>
<ul class="toc-indentation"><li><a shape="rect" href="#JAXRSOAuth2Assertions-Clientcode">Client code</a></li><li><a shape="rect" href="#JAXRSOAuth2Assertions-AccessTokenService">Access Token Service</a></li></ul>
</li><li><a shape="rect" href="#JAXRSOAuth2Assertions-AuthenticationToken">Authentication Token</a>
<ul class="toc-indentation"><li><a shape="rect" href="#JAXRSOAuth2Assertions-ClientCode">Client Code</a></li><li><a shape="rect" href="#JAXRSOAuth2Assertions-AccessTokenService.1">Access Token Service</a></li></ul>
</li><li><a shape="rect" href="#JAXRSOAuth2Assertions-ClientActingonBehalfofItself">Client Acting on Behalf of Itself</a></li></ul>
</li><li><a shape="rect" href="#JAXRSOAuth2Assertions-JWTBearer">JWT Bearer</a>
<ul class="toc-indentation"><li><a shape="rect" href="#JAXRSOAuth2Assertions-AccessTokenGrant.1">Access Token Grant</a>
<ul class="toc-indentation"><li><a shape="rect" href="#JAXRSOAuth2Assertions-Clientcode.1">Client code</a></li><li><a shape="rect" href="#JAXRSOAuth2Assertions-AccessTokenService.2">Access Token Service</a></li></ul>
</li><li><a shape="rect" href="#JAXRSOAuth2Assertions-AuthenticationToken.1">Authentication Token</a>
<ul class="toc-indentation"><li><a shape="rect" href="#JAXRSOAuth2Assertions-ClientCode.1">Client Code</a></li><li><a shape="rect" href="#JAXRSOAuth2Assertions-AccessTokenService.3">Access Token Service</a></li></ul>
</li></ul>
</li></ul>
</div><h1 id="JAXRSOAuth2Assertions-Introduction">Introduction</h1><p><a shape="rect" class="external-link" href="https://tools.ietf.org/html/rfc6749" rel="nofollow">OAuth 2.0</a> supports different types of access token grants. The <a shape="rect" class="external-link" href="http://tools.ietf.org/html/rfc7521" rel="nofollow">OAuth2 Assertions</a> spec "provides a framework for the use of assertions with OAuth 2.0 in the form of a new client authentication mechanism and a new authorization grant type". More specifically, the <a shape="rect" class="external-link" href="https://tools.ietf.org/html/rfc7522" rel="nofollow">SAML2 Bearer Assertion Profiles for OAuth2</a> spec provides for the use of SAML2 Bearer assertions, and the <a shape="rect" class="external-link" href="http://tools.ietf.org/html/rfc7523" rel="nofollow">JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants</a> spec providers for the use of JWT Bearer tokens.</p><p>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.</p><p>Currently CXF supports both SAML2 Bearer and JWT Bearer assertions as grants and authentication tokens.</p><p>See the <a shape="rect" href="jax-rs-oauth2.html">JAX-RS OAuth2</a> page for information about OAuth 2.0 support in CXF. Please also check the <a shape="rect" href="jax-rs-saml.html">JAX-RS SAML</a> page for more information about SAML support.</p><p>&#160;</p><h1 id="JAXRSOAuth2Assertions-SAML2Bearer">SAML2 Bearer</h1><h2 id="JAXRSOAuth2Assertions-Mavendependencies">Maven dependencies</h2><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default">&lt;dependency&gt;
&lt;groupId&gt;org.apache.cxf&lt;/groupId&gt;
&lt;artifactId&gt;cxf-rt-rs-security-oauth2-saml&lt;/artifactId&gt;
&lt;version&gt;${cxf.version}&lt;/version&gt;
&lt;/dependency&gt;
</pre>
</div></div><h2 id="JAXRSOAuth2Assertions-AccessTokenGrant">Access Token Grant</h2><p><a shape="rect" class="external-link" href="http://tools.ietf.org/html/rfc7522#section-2.1" rel="nofollow">This section</a> 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".</p><p>It is really just another grant type, but whose actual value is a SAML assertion. The specification provides an <a shape="rect" class="external-link" href="http://tools.ietf.org/html/rfc7522#section-4" rel="nofollow">example</a> of how such an assertion may look like.</p><p>The additional restriction is that the assertions have to be encoded using Base64Url encoding. <br clear="none"> Here is how a request may look like:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default">POST /token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Asaml2-bearer&amp;
assertion=Base64UrlEncoded-SAML2-Bearer-Assertion
</pre>
</div></div><h3 id="JAXRSOAuth2Assertions-Clientcode">Client code</h3><p>The following example shows how to use SAML2 Bearer assertion as a grant with CXF OAuth2 client code:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default">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);
</pre>
</div></div><p>The code above prepares an info for a new SAML assertion be self-signed, loading a Crypto instance with crypto <a shape="rect" class="external-link" href="http://svn.apache.org/repos/asf/cxf/trunk/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/alice.properties">properties</a>, and uses SAMLUtils to create and sign the assertion (using Crypto, plus user alias and password). Saml2BearerGrant will get the assertion Base64Url-encoded - unless the assertion has already been encoded with CXF Base64UrlUtility or came encoded from IP - in this case Saml2BearerGrant constructor accepting an 'encoded' property will have to be used, with the value set to "true".</p><p>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 <a shape="rect" class="external-link" href="http://tools.ietf.org/html/rfc7521#section-6.2" rel="nofollow">on behalf of itself</a> for example.</p><p>Instead of using SelfSignInfo utility one can create an empty CXF Message and set required properties on it and passing it to SAMLUtils - see the example on how to use SAML Bearer assertions for the authentication below.</p><p>When doing step 2, the main effort is to do with getting a SAML assertion populated - use a SAML callback handler like <a shape="rect" class="external-link" href="http://svn.apache.org/repos/asf/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/SamlCallbackHandler.java">this one</a>, it is actually quite easy to build the assertion.</p><h3 id="JAXRSOAuth2Assertions-AccessTokenService">Access Token Service</h3><p>Here is how one may configure Access Token Service:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default">&lt;bean id="dataProvider" class="org.apache.cxf.systest.jaxrs.security.oauth2.OAuthDataProviderImpl"/&gt;
&lt;bean id="samlGrantHandler" class="org.apache.cxf.rs.security.oauth2.grants.saml.Saml2BearerGrantHandler"&gt;
&lt;property name="dataProvider" ref="dataProvider"/&gt;
&lt;/bean&gt;
&lt;bean id="oauthJson" class="org.apache.cxf.rs.security.oauth2.provider.OAuthJSONProvider"/&gt;
&lt;bean id="serviceBean" class="org.apache.cxf.rs.security.oauth2.services.AccessTokenService"&gt;
&lt;property name="dataProvider" ref="dataProvider"/&gt;
&lt;property name="grantHandlers"&gt;
&lt;list&gt;
&lt;ref bean="samlGrantHandler"/&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;jaxrs:server address="https://localhost:${testutil.ports.jaxrs-oauth2}/oauth2"&gt;
&lt;jaxrs:serviceBeans&gt;
&lt;ref bean="serviceBean"/&gt;
&lt;/jaxrs:serviceBeans&gt;
&lt;jaxrs:providers&gt;
&lt;ref bean="oauthJson"/&gt;
&lt;/jaxrs:providers&gt;
&lt;jaxrs:properties&gt;
&lt;entry key="security.signature.properties" value="org/apache/cxf/systest/jaxrs/security/alice.properties"/&gt;
&lt;/jaxrs:properties&gt;
&lt;/jaxrs:server&gt;
</pre>
</div></div><h2 id="JAXRSOAuth2Assertions-AuthenticationToken">Authentication Token</h2><p>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:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default">POST /token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&amp;code=12345678
&amp;client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Asaml2-bearer
&amp;client_assertion=Base64UrlEncoded-SAML2-Bearer-Assertion
</pre>
</div></div><p>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.</p><h3 id="JAXRSOAuth2Assertions-ClientCode">Client Code</h3><p>The following example shows how to use SAML2 Bearer assertion as an authentication token:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default">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&lt;String, String&gt; extraParams = new HashMap&lt;String, String&gt;();
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);
</pre>
</div></div><p>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.<br clear="none"> 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.</p><p>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:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default">JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
Map&lt;String, Object&gt; properties = new HashMap&lt;String, Object&gt;();
properties.put("security.callback-handler",
"org.apache.cxf.systest.jaxrs.security.saml.KeystorePasswordCallback");
properties.put("security.saml-callback-handler",
"org.apache.cxf.systest.jaxrs.security.oauth2.SamlCallbackHandler2");
properties.put("security.signature.username", "alice");
properties.put("security.signature.properties", CRYPTO_RESOURCE_PROPERTIES);
properties.put("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);
</pre>
</div></div><h3 id="JAXRSOAuth2Assertions-AccessTokenService.1">Access Token Service</h3><p>Here is how one may configure Access Token Service:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default">&lt;bean id="dataProvider" class="org.apache.cxf.systest.jaxrs.security.oauth2.OAuthDataProviderImpl"/&gt;
&lt;bean id="oauthJson" class="org.apache.cxf.rs.security.oauth2.provider.OAuthJSONProvider"/&gt;
&lt;bean id="samlAuthHandler" class="org.apache.cxf.rs.security.oauth2.auth.saml.Saml2BearerAuthHandler"/&gt;
&lt;bean id="serviceBean" class="org.apache.cxf.rs.security.oauth2.services.AccessTokenService"&gt;
&lt;property name="dataProvider" ref="dataProvider"/&gt;
&lt;property name="grantHandlers"&gt;
&lt;list&gt;
&lt;!-- list of required grant handlers --&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;jaxrs:server
address="https://localhost:${testutil.ports.jaxrs-oauth2}/oauth2-auth"&gt;
&lt;jaxrs:serviceBeans&gt;
&lt;ref bean="serviceBean"/&gt;
&lt;/jaxrs:serviceBeans&gt;
&lt;jaxrs:providers&gt;
&lt;ref bean="oauthJson"/&gt;
&lt;ref bean="samlAuthHandler"/&gt;
&lt;/jaxrs:providers&gt;
&lt;jaxrs:properties&gt;
&lt;entry key="security.signature.properties"
value="org/apache/cxf/systest/jaxrs/security/alice.properties"/&gt;
&lt;/jaxrs:properties&gt;
&lt;/jaxrs:server&gt;
</pre>
</div></div><h2 id="JAXRSOAuth2Assertions-ClientActingonBehalfofItself">Client Acting on Behalf of Itself</h2><p>In the <a shape="rect" class="external-link" href="http://tools.ietf.org/html/rfc7521#section-6.2" rel="nofollow">Client Acting on Behalf of Itself</a> use either org.apache.cxf.rs.security.oauth2.grants.saml.Saml2BearerClientCredentialsGrant :</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default">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);
</pre>
</div></div><p>or ClientCredentialsGrant in combination with Saml2BearerAuthOutInterceptor:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default">JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
Map&lt;String, Object&gt; properties = new HashMap&lt;String, Object&gt;();
properties.put("security.callback-handler",
"org.apache.cxf.systest.jaxrs.security.saml.KeystorePasswordCallback");
properties.put("security.saml-callback-handler",
"org.apache.cxf.systest.jaxrs.security.oauth2.SamlCallbackHandler2");
properties.put("security.signature.username", "alice");
properties.put("security.signature.properties", CRYPTO_RESOURCE_PROPERTIES);
properties.put("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);
</pre>
</div></div><p>&#160;</p><h1 id="JAXRSOAuth2Assertions-JWTBearer">JWT Bearer</h1><p>See <a shape="rect" href="https://cwiki.apache.org/confluence/display/CXF20DOC/JAX-RS+OAuth2#JAX-RSOAuth2-SAMLandJWTAssertions">this CXF OAuth2 section</a> for the information about the implementation details.</p><h2 id="JAXRSOAuth2Assertions-AccessTokenGrant.1">Access Token Grant</h2><p><a shape="rect" class="external-link" href="http://tools.ietf.org/html/rfc7523#section-2.1" rel="nofollow">This section</a> explains how JWT Bearer tokens can be used as token grants. The value of grant_type parameter is "urn:ietf:params:oauth:grant- type:jwt-bearer".</p><p>It is really just another grant type, but whose actual value is a JWT Token. The specification provides an <a shape="rect" class="external-link" href="http://tools.ietf.org/html/rfc7523#section-4" rel="nofollow">example</a> of how such an assertion may look like.</p><p>Here is how a request may look like:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default">POST /token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&amp;
assertion=X.Y.Z
</pre>
</div></div><h3 id="JAXRSOAuth2Assertions-Clientcode.1">Client code</h3><p>CXF BigQuery demo <a shape="rect" class="external-link" href="https://github.com/apache/cxf/blob/master/distribution/src/main/release/samples/jax_rs/big_query/src/main/java/demo/jaxrs/server/BigQueryServer.java#L75" rel="nofollow">shows</a> how a so called Google Service Client can prepare a signed JWT token and use JwtBearerGrant in order to issue a JWT Bearer grant request and get a new access token back. CXF WebClient is used in the demo code but OAuthClientUtils can also be used.</p><h3 id="JAXRSOAuth2Assertions-AccessTokenService.2">Access Token Service</h3><p>Here is how one may configure the Access Token Service:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default">&lt;bean id="dataProvider" class="org.apache.cxf.systest.jaxrs.security.oauth2.OAuthDataProviderImpl"/&gt;
&lt;bean id="jwtGrantHandler" class="org.apache.cxf.rs.security.oauth2.grants.jwt.JwtBearerGrantHandler"&gt;
&lt;property name="dataProvider" ref="dataProvider"/&gt;
&lt;/bean&gt;
&lt;bean id="oauthJson" class="org.apache.cxf.rs.security.oauth2.provider.OAuthJSONProvider"/&gt;
&lt;bean id="serviceBean" class="org.apache.cxf.rs.security.oauth2.services.AccessTokenService"&gt;
&lt;property name="dataProvider" ref="dataProvider"/&gt;
&lt;property name="grantHandlers"&gt;
&lt;list&gt;
&lt;ref bean="jwtGrantHandler"/&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;jaxrs:server address="https://localhost:${testutil.ports.jaxrs-oauth2}/oauth2"&gt;
&lt;jaxrs:serviceBeans&gt;
&lt;ref bean="serviceBean"/&gt;
&lt;/jaxrs:serviceBeans&gt;
&lt;jaxrs:providers&gt;
&lt;ref bean="oauthJson"/&gt;
&lt;/jaxrs:providers&gt;
&lt;jaxrs:properties&gt;
&lt;entry key="rs.security.keystore.type" value="jks" /&gt;
&lt;entry key="rs.security.keystore.alias" value="myclientkey"/&gt;
&lt;entry key="rs.security.keystore.password" value="cspass"/&gt;
&lt;entry key="rs.security.keystore.file" value="clientstore.jks" /&gt;
&lt;entry key="rs.security.signature.algorithm" value="RS256" /&gt;
&lt;/jaxrs:properties&gt;
&lt;/jaxrs:server&gt;
</pre>
</div></div><h2 id="JAXRSOAuth2Assertions-AuthenticationToken.1">Authentication Token</h2><p>As noted in the introduction, JWT Bearer tokens may also act as client authentication credentials, when requesting an access token, irrespectively of the actual grant type. For example:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default">POST /token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&amp;code=12345678
&amp;client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&amp;client_assertion=X.Y.Z
</pre>
</div></div><p>Note "client_assertion_type" with a value "urn:ietf:params:oauth:client-assertion-type:jwt-bearer" indicates that the type of assertion used as an authentication token is "urn:ietf:params:oauth:client-assertion-type:jwt-bearer", while the "client_assertion" parameter carries the actual value of the token.</p><h3 id="JAXRSOAuth2Assertions-ClientCode.1">Client Code</h3><p>Suppose the client is acting on behalf of itself to request a token, effectively using Client Credentials grant. In this case it will use <a shape="rect" class="external-link" href="https://github.com/apache/cxf/blob/master/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/jwt/JwtBearerClientCredentialsGrant.java" rel="nofollow">JwtBearerClientCredentialsGrant</a>.</p><h3 id="JAXRSOAuth2Assertions-AccessTokenService.3">Access Token Service</h3><p>Here is how one may configure Access Token Service:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default">&lt;bean id="dataProvider" class="org.apache.cxf.systest.jaxrs.security.oauth2.OAuthDataProviderImpl"/&gt;
&lt;bean id="oauthJson" class="org.apache.cxf.rs.security.oauth2.provider.OAuthJSONProvider"/&gt;
&lt;bean id="jwtAuthHandler" class="org.apache.cxf.rs.security.oauth2.grants.jwt.JwtBearerAuthHandler"/&gt;
&lt;bean id="serviceBean" class="org.apache.cxf.rs.security.oauth2.services.AccessTokenService"&gt;
&lt;property name="dataProvider" ref="dataProvider"/&gt;
&lt;property name="grantHandlers"&gt;
&lt;list&gt;
&lt;!-- list of required grant handlers --&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;jaxrs:server
address="https://localhost:${testutil.ports.jaxrs-oauth2}/oauth2-auth"&gt;
&lt;jaxrs:serviceBeans&gt;
&lt;ref bean="serviceBean"/&gt;
&lt;/jaxrs:serviceBeans&gt;
&lt;jaxrs:providers&gt;
&lt;ref bean="oauthJson"/&gt;
&lt;ref bean="jwtAuthHandler"/&gt;
&lt;/jaxrs:providers&gt;
&lt;jaxrs:properties&gt;
&lt;entry key="security.signature.properties"
value="org/apache/cxf/systest/jaxrs/security/alice.properties"/&gt;
&lt;/jaxrs:properties&gt;
&lt;/jaxrs:server&gt;
</pre>
</div></div></div>
</div>
<!-- Content -->
</td>
</tr>
</table>
</td>
<td id="cell-2-2" colspan="2">&nbsp;</td>
</tr>
<tr>
<td id="cell-3-0">&nbsp;</td>
<td id="cell-3-1">&nbsp;</td>
<td id="cell-3-2">
<div id="footer">
<!-- Footer -->
<div id="site-footer">
<a href="http://cxf.apache.org/privacy-policy.html">Privacy Policy</a> -
(<a href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=30755503">edit page</a>)
(<a href="https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=30755503&amp;showComments=true&amp;showCommentArea=true#addcomment">add comment</a>)<br>
Apache CXF, CXF, Apache, the Apache feather logo are trademarks of The Apache Software Foundation.<br>
All other marks mentioned may be trademarks or registered trademarks of their respective owners.
</div>
<!-- Footer -->
</div>
</td>
<td id="cell-3-3">&nbsp;</td>
<td id="cell-3-4">&nbsp;</td>
</tr>
<tr>
<td id="cell-4-0" colspan="2">&nbsp;</td>
<td id="cell-4-1">&nbsp;</td>
<td id="cell-4-2" colspan="2">&nbsp;</td>
</tr>
</table>
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try {
var pageTracker = _gat._getTracker("UA-4458903-1");
pageTracker._trackPageview();
} catch(err) {}</script>
</body>
</html>