Modified: websites/production/cxf/content/docs/jax-rs-oauth2.html
==============================================================================
--- websites/production/cxf/content/docs/jax-rs-oauth2.html (original)
+++ websites/production/cxf/content/docs/jax-rs-oauth2.html Wed Sep 13 15:05:52
2017
@@ -32,9 +32,9 @@
<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/shBrushJava.js'></script>
-<script src='/resources/highlighter/scripts/shBrushXml.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();
@@ -119,11 +119,11 @@ Apache CXF -- JAX-RS OAuth2
<!-- Content -->
<div class="wiki-content">
<div id="ConfluenceContent"><h1 id="JAX-RSOAuth2-JAX-RS:OAuth2">JAX-RS:
OAuth2</h1><p><style type="text/css">/*<![CDATA[*/
-div.rbtoc1505311246131 {padding: 0px;}
-div.rbtoc1505311246131 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1505311246131 li {margin-left: 0px;padding-left: 0px;}
+div.rbtoc1505314879918 {padding: 0px;}
+div.rbtoc1505314879918 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1505314879918 li {margin-left: 0px;padding-left: 0px;}
-/*]]>*/</style></p><div class="toc-macro rbtoc1505311246131">
+/*]]>*/</style></p><div class="toc-macro rbtoc1505314879918">
<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSOAuth2-JAX-RS:OAuth2">JAX-RS: OAuth2</a></li><li><a shape="rect"
href="#JAX-RSOAuth2-Introduction">Introduction</a></li><li><a shape="rect"
href="#JAX-RSOAuth2-Mavendependencies">Maven dependencies</a></li><li><a
shape="rect" href="#JAX-RSOAuth2-ClientRegistration">Client
Registration</a></li><li><a shape="rect"
href="#JAX-RSOAuth2-DevelopingOAuth2Servers">Developing OAuth2 Servers</a>
<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSOAuth2-AuthorizationService">Authorization Service</a>
<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSOAuth2-HowtocreateAuthorizationView">How to create Authorization
View</a></li><li><a shape="rect"
href="#JAX-RSOAuth2-EndUserNameinAuthorizationForm">EndUser Name in
Authorization Form</a></li><li><a shape="rect"
href="#JAX-RSOAuth2-PublicClients(Devices)">Public Clients (Devices)</a>
@@ -156,20 +156,20 @@ div.rbtoc1505311246131 li {margin-left:
</li><li><a shape="rect" href="#JAX-RSOAuth2-SingleSignOn">Single Sign
On</a></li></ul>
</li></ul>
</div><h1 id="JAX-RSOAuth2-Introduction">Introduction</h1><p>New:</p><ul
style="list-style-type: square;"><li>Ehcache, JCache and JPA2
OAuthDataProviders can represent access tokens in JWT</li><li>Client
Certificate Authentication and Token Binding is
supported</li><li>DynamicRegistrationService is enhanced<br clear="none"><br
clear="none"></li></ul><p>CXF provides the implementation of <a shape="rect"
class="external-link" href="http://tools.ietf.org/html/rfc6749"
rel="nofollow">OAuth 2.0</a>. See also the <a shape="rect"
href="jax-rs-oauth.html">JAX-RS OAuth</a> page for information about OAuth
1.0.</p><p>Authorization Code, Implicit, Client Credentials, Resource Owner
Password Credentials, Refresh Token, SAML2 Assertions and JWT assertion grants
are currently supported.</p><p>Custom grant handlers can be
registered.</p><p>OAuth2 is a new protocol which offers a complex yet elegant
solution toward helping end users (resource owners) authorize third-party
providers to access their
resources.</p><p>The OAuth2 flow which is closely related to the original
OAuth 1.0 3-leg flow is called Authorization Code and involves 3 parties: the
end user, the third party service (client) and the resource server which is
protected by OAuth2 filters. Typically a client offers a service feature that
an end user requests and which requires the former to access one or more
protected resources on behalf of this user which are located at the resource
server. For example, the client may need to access the end user's photos in
order to print them and post to the user or read and possibly update a user's
calendar in order to make a booking.</p><p>In order to make it happen, the
third-party service application/client needs to register itself with the OAuth2
server. This happens out-of-band and after the registration the client gets
back a client key and secret pair. Typically the client is expected to provide
the name and description of the application, the application logo URI, one or
more redirect URIs, and other information that may help the OAuth2
authorization server to identify this client to the end user at the
authorization time.</p><p>From then on, the authorization code flow works like
this:<br clear="none"> 1. End User requests the third-party service using a
browser.</p><p>2. The client redirects the end user to OAuth2 Authorization
Service, adding its client id, the state, redirect URI and the optional scope
to the target URI. The state parameter represents the current end user's
request, redirect URI - where the authorization code is expected to be returned
to, and the scope is the list of opaque permissions that the client needs in
order to access the protected resources.</p><p>3. Authorization Service will
retrieve the information about the client using its client id, build an HTML
form and return it to the end user. The form will ask the user if a given
third-party application can be allowed to access some resources on behalf of
this user.</p><p>
4. If the user approves it then Authorization Service will generate an
authorization code and redirect the user back to the redirect uri provided by
the client, also adding a state parameter to the redirect URI.</p><p>5. The
client requests an access token from OAuth2 Access Token Service by providing
an authorization code grant.</p><p>6. After getting an access token token, the
service finally proceeds with accessing the current user's resources and
completes the user's request.</p><p>As you can see the flow can be complex yet
it is very effective. A number of issues may need to be taken care along the
way such as managing expired tokens, making sure that the OAuth2 security layer
is functioning properly and is not interfering with the end user itself trying
to access its own resources, etc.</p><p>Please check the <a shape="rect"
class="external-link" href="https://tools.ietf.org/html/rfc6749"
rel="nofollow">specification</a> as well as other resources available on the
WEB for more
information you may need to know about OAuth2.</p><p>CXF JAX-RS gives the
best effort to making this process as simple as possible and requiring only a
minimum effort on behalf of OAuth2 server developers. It also offers the
utility code for greatly simplifying the way the third-party application can
interact with the OAuth2 service endpoints.</p><h1
id="JAX-RSOAuth2-Mavendependencies">Maven dependencies</h1><div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><dependency>
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-security-oauth2</artifactId>
<version>3.1.7</version>
</dependency>
</pre>
</div></div><h1 id="JAX-RSOAuth2-ClientRegistration">Client
Registration</h1><p>Client Registration is typically done out of band, with the
the dynamic client registration being also possible.<br clear="none"> The
client registration service will offer an HTML form where the clients will
enter their details, see a <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/common/Client.java"
rel="nofollow">Client</a> bean for the currently supported
properties.</p><p>See <a shape="rect" class="external-link"
href="https://github.com/apache/cxf-fediz/blob/master/services/oidc/src/main/java/org/apache/cxf/fediz/service/oidc/clients/ClientRegistrationService.java"
rel="nofollow">this JAX-RS service implementation</a> for one possible
approach.</p><h1 id="JAX-RSOAuth2-DevelopingOAuth2Servers">Developing OAuth2
Servers</h1><p>OAuth2 server is the core piece of the complete OAuth2
-based solution. Typically it contains 3 services for:<br clear="none"> 1.
Authorizing request tokens by asking the end users to let clients access some
of their resources and returning the<br clear="none"> grants back to the client
(Authorization Service)<br clear="none"> 2. Exchanging the token grants for
access tokens (Access Token Service)</p><p>3. Validating access
tokens</p><p> </p><p>CXF offers several JAX-RS service implementations
that can be used to create the OAuth2 servers fast: <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/services/AuthorizationCodeGrantService.java"
rel="nofollow">AuthorizationCodeGrantService</a> and <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/services/ImplicitGrantService.java"
rel="nofollow">ImplicitG
rantService</a> for managing the redirection-based flows, as well as <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/services/AccessTokenService.java"
rel="nofollow">AccessTokenService</a> for exchanging the grants for new
tokens.</p><p>All of these services rely on the custom <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/provider/OAuthDataProvider.java"
rel="nofollow">OAuthDataProvider</a> which persists the access tokens and
converts the opaque scope values to the information that can be presented to
the users. Additionally, <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/code/AuthorizationCodeDataProvider.java"
rel
="nofollow">AuthorizationCodeDataProvider</a> is an <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/provider/OAuthDataProvider.java"
rel="nofollow">OAuthDataProvider</a> which can keep temporary information
about the authorization code grants which needs to be removed after the tokens
are requested in exchange.</p><p>Note that some grants that do not require the
redirection-based support, such as Client Credentials or SAML2 or JWT assertion
grants, and may only require an Access Token Service be operational.</p><p>If
your OAuth2 server does support either Authorization Code or Implicit flow then
either <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/services/AuthorizationCodeGrantService.java"
rel="nofollow">AuthorizationCodeGrantServi
ce</a> and <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/services/ImplicitGrantService.java"
rel="nofollow">ImplicitGrantService</a> need to be registered. If both
services need to be supported then simply register two of them, but note each
service will have its own @Path segment, "/authorize"
and "/authorize-implicit". If you'd like both services listening on the
same path then 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/services/AuthorizationService.java"
rel="nofollow">AuthorizationService</a> and inject <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/services/AuthorizationCodeGrantService.java"
re
l="nofollow">AuthorizationCodeGrantService</a> and <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/services/ImplicitGrantService.java"
rel="nofollow">ImplicitGrantService</a> beans into it.</p><p>If no
AuthorizationCode redirection flow is supported then implementing <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/provider/OAuthDataProvider.java"
rel="nofollow">OAuthDataProvider</a> is sufficent.</p><p>Writing your own <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/code/AuthorizationCodeDataProvider.java"
rel="nofollow">AuthorizationCodeDataProvider</a> or <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/provider/OAuthDataProvider.java"
rel="nofollow">OAuthDataProvider</a> implementation is what is needed to get
the OAuth2 server up and running. In many cases all you need to do is to
persist or remove the Authorization Code Grant data, use one of the available
utility classes to create a new access token and also persist it or remove the
expired one, and finally convert the optional opaque scope values (if any are
supported) to a more view-able information.</p><p>CXF ships several default
provider implementations, see the section on wirting the providers
below.</p><p> </p><h2 id="JAX-RSOAuth2-AuthorizationService">Authorization
Service</h2><p>The main responsibility of OAuth2 Authorization Service is to
present an end user with a form asking the user to allow or deny the client
accessing some of the user resources. CXF offers  <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/services/AuthorizationCodeGrantService.java"
rel="nofollow">AuthorizationCodeGrantService</a> and <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/services/ImplicitGrantService.java"
rel="nofollow">ImplicitGrantService</a> for accepting the redirection
requests, challenging the end users with the authorization forms, handling the
end user decisions and returning the results back to the clients.</p><p>One of
the differences between Authorization Code and Implicit flows is that in the
latter case the grant is the actual access token which is returned as the URI
fragment value to the client script running in the browser. The way the end
user is asked to authorize the client request is similar between the two flows.
In this section we will assu
me that the Authorization Code flow is being used.</p><p>A third-party client
redirects the current user to AuthorizationCodeGrantService, for example, here
is how a redirection may happen:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">Response-Code: 303
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">Response-Code: 303
Headers:
{Location=[http://localhost:8080/services/social/authorize?client_id=123456789&scope=updateCalendar-7&response_type=code
&redirect_uri=http%3A//localhost%3A8080/services/reservations/reserve/complete&state=1],
Date=[Thu, 12 Apr 2012 12:26:21 GMT], Content-Length=[0]}
</pre>
</div></div><p>The client application asks the current user (the browser) to
go to a new address provided by the Location header and the follow-up request
to AuthorizationCodeGrantService will look like this:</p><div class="code panel
pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">Address:
http://localhost:8080/services/social/authorize?client_id=123456789&scope=updateCalendar-7&response_type=code
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">Address:
http://localhost:8080/services/social/authorize?client_id=123456789&scope=updateCalendar-7&response_type=code
&redirect_uri=http%3A//localhost%3A8080/services/reservations/reserve/complete&state=1
Http-Method: GET
Headers: {
@@ -181,16 +181,16 @@ Referer=[http://localhost:8080/services/
}
</pre>
</div></div><p>Note that the end user needs to authenticate. The Request URI
includes the client_id, custom scope value, response_type set to 'code', the
current request state and the redirect uri. Note the scope is optional - the
Authorization Service will usually allocate a default scope; however even if
the client does include an additional custom scope the end user may still not
approve it. The redirect uri is also optional, assuming one or more ones
redirect URIs have been provided at the client registration
time.</p><p>AuthorizationCodeGrantService will report a warning is no secure
HTTPS transport is used:</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">12-Apr-2012 13:26:21
org.apache.cxf.rs.security.oauth2.services.AbstractOAuthService
checkTransportSecurity
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">12-Apr-2012 13:26:21
org.apache.cxf.rs.security.oauth2.services.AbstractOAuthService
checkTransportSecurity
WARNING: Unsecure HTTP, Transport Layer Security is recommended
</pre>
</div></div><p>It can also be configured to reject the requests over insecure
HTTP transport.</p><p>AuthorizationCodeGrantService will retrieve the
information about the <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/common/Client.java"
rel="nofollow">client application</a> to populate an instance of <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/common/OAuthAuthorizationData.java"
rel="nofollow">OAuthAuthorizationData</a> bean and return it.
OAuthAuthorizationData contains application name and URI properties, optional
list of <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/common/OAuthPermission.java"
rel="nofollow">Permiss
ion</a>s and other properties which can be either presented to the user or
kept in the hidden form fields in order to uniquely identify the actual
authorization request when the end user returns the decision.</p><p>One
important OAuthAuthorizationData property is "authenticityToken". It is used
for validating that the current session has not been hijacked -
AuthorizationCodeGrantService generates a random key, stores it in a Servlet
HTTPSession instance and expects the returned authenticityToken value to match
it - this is a recommended approach and it also implies that the
authenticityToken value is hidden from a user, for example, it's kept in a
'hidden' form field. See also "User Session Authenticity" on how <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/provider/SessionAuthenticityTokenProvider.java"
rel="nofollow">SessionAuthenticityTokenProvider</a> can hel
p.</p><p>A number of properties which have been submitted to the authorization
endpoint with the original user redirect need to be made available after the
user has been challenged with the autorization consent form, when the user
makes an authorization decision. These are properties such as 'clientId',
'state', 'redirectUri', and other properties, see <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/common/OAuthRedirectionState.java"
rel="nofollow">this class</a> which is extended by OAuthAuthorizationData. One
simple approach is to have a view handler preparing an authorization form with
<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/common/OAuthAuthorizationData.java"
rel="nofollow">OAuthAuthorizationData</a> to have these properties hidden i
n the form. Another option is to secure them in a session thus making the view
creation process much simpler, see "User Session Authenticity" for one
example.</p><p>The helper "replyTo" property is an absolute URI identifying the
AuthorizationCodeGrantService handler processing the user decision and can be
used by view handlers when building the forms or by other
OAuthAuthorizationData handlers.</p><p>So the populated OAuthAuthorizationData
is finally returned. Note that it's a JAXB XMLRootElement-annotated bean and
can be processed by registered JAXB or JSON providers given that
AuthorizationCodeGrantService supports producing "application/xml" and
"application/json" (See the OAuth Without Browser section below for more). But
in this case we have the end user working with a browser so an HTML form is
what is really expected back.</p><p>AuthorizationCodeGrantService supports
producing "text/html" and simply relies on a registered <a shape="rect"
href="http://cxf.apache.org/docs/jax-
rs-redirection.html#JAX-RSRedirection-WithRequestDispatcherProvider">RequestDispatcherProvider</a>
to set the OAuthAuthorizationData bean as an HttpServletRequest attribute and
redirect the response to a view handler (can be JSP or some other servlet) to
actually build the form and return it to the user. See the section below on
other alternatives on how a view can be created.</p><p>Assuming
RequestDispatcherProvider is used, the following example log shows the initial
response from AuthorizationCodeGrantService:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">12-Apr-2012 13:26:21
org.apache.cxf.jaxrs.provider.RequestDispatcherProvider logRedirection
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">12-Apr-2012 13:26:21
org.apache.cxf.jaxrs.provider.RequestDispatcherProvider logRedirection
INFO: Setting an instance of
"org.apache.cxf.rs.security.oauth2.common.OAuthAuthorizationData" as
HttpServletRequest
attribute "data" and redirecting the response to "/forms/oauthAuthorize.jsp".
</pre>
</div></div><p>Note that a "/forms/oauthAuthorize.jsp" view handler will
create an HTML view - this is a custom JSP handler and whatever HTML view is
required can be created there, using the OAuthAuthorizationData bean for
building the view. Most likely you will want to present a form asking the user
to allow or deny the client accessing some of this user's resources. If
OAuthAuthorizationData has a list of Permissions set then adding the
information about the permissions is needed.</p><p>Next the user makes a
decision and selects a button allowing or denying the client accessing the
resources. The form data are submitted to
AuthorizationCodeGrantService:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">Address:
http://localhost:8080/services/social/authorize/decision
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">Address:
http://localhost:8080/services/social/authorize/decision
Encoding: ISO-8859-1
Http-Method: POST
Content-Type: application/x-www-form-urlencoded
@@ -206,7 +206,7 @@ INFO: updateCalendar-7_status=allow&
&session_authenticity_token=4f0005d9-565f-4309-8ffb-c13c72139ebe&oauthDecision=allow&state=1&client_id=123456789
</pre>
</div></div><p>AuthorizationCodeGrantService will use a
'session_authenticity_token' to validate that the session is valid and will
process the user decision next.</p><p>If the decision is "allow" then it will
check the status of the individual scope values. It relies on the
"scopename_status" convention, if the form has offered the user a chance to
selectively enable individual scopes then name/value pairs such as
"updateCalendar-7_status=allow" are submitted. If none of such pairs is coming
back then it means the user has approved all the default and additional (if
any) scopes.</p><p>Next it will ask OAuthDataProvider to generate an
authorization code grant and return it alongside with the state if any by
redirecting the current user back to the redirect URI:</p><div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">Response-Code: 303
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">Response-Code: 303
Headers: {
Location=[http://localhost:8080/services/reservations/reserve/complete?state=1
&code=5c993144b910bccd5977131f7d2629ab],
@@ -214,7 +214,7 @@ Headers: {
Content-Length=[0]}
</pre>
</div></div><p>which leads to a browser redirecting the user:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">Address:
http://localhost:8080/services/reservations/reserve/complete?state=1&code=5c993144b910bccd5977131f7d2629ab
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">Address:
http://localhost:8080/services/reservations/reserve/complete?state=1&code=5c993144b910bccd5977131f7d2629ab
Http-Method: GET
Headers: {
Accept=[text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8],
@@ -227,7 +227,7 @@ Cookie=[JSESSIONID=1c289vha0cxfe],
http://localhost:8080/services/social/authorize?client_id=mobileClient&response_type=code
</pre>
</div></div><p>Assuming the 'mobileClient' has been registered as public one
with no secret and the service has been set up to support such clients, the end
user will get a chance to authorize this client the same way it can do
confidential clients, and after this user gets back a code (delivered directly
in the response HTML page by default) the user will enter the code securely
into the device which will then replace it for a time-scoped access token by
contacting AccessTokenService.</p><h4
id="JAX-RSOAuth2-SecurecodeacquisitionwithredirectURI">Secure code acquisition
with redirect URI</h4><p>The following <a shape="rect" class="external-link"
href="https://tools.ietf.org/html/draft-ietf-oauth-spop-15"
rel="nofollow">extension</a> is supported to help public clients with redirect
URIs to accept the code securely.</p><p>The public (mobile) client will include
a 'code_verifier' value when requesting the authorization code and it will be
saved by Authorization service, with the help
of the registered AuthorizationCodeDataProvider into an instance of
ServerAuthorizationCodeGrant. The client will next request a token providing
the 'code' and 'code_challenge' - the latter will be compared by
AuthorizationCodeGrantHandler with the original 'code_verifier'. By default,
the 'code_challenge' is expected to be equal to the original 'code_verifier',
but the grant handler can be registered with the custom
org.apache.cxf.rs.security.oauth2.grants.code.CodeVerifierTransformer - CXF
ships a DigestCodeVerifier which implements a transformation mentioned in the
extension.</p><h3 id="JAX-RSOAuth2-FormPostResponseMode">Form Post Response
Mode</h3><p><a shape="rect" class="external-link"
href="http://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html"
rel="nofollow">Form Post Response Mode</a> has been orinially introduced for
OpenId Connect but has been generally recomended recently as a possibly safer
option of returning OAuth2 Authorization Service response to the cli
ents. Starting from CXF 3.1.9, if a client sends a "response_mode=form_post"
parameter during the original redirect, CXF AuthorizationCodeService will
return  <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/common/OOBAuthorizationResponse.java"
rel="nofollow">OOBAuthorizationResponse</a> with its 'redirectUri' property
set - a JSP/etc handler will convert to an HTML form which will re-post the
data to the client callback address.</p><h2
id="JAX-RSOAuth2-AccessTokenService">AccessTokenService</h2><p>The role of <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/services/AccessTokenService.java"
rel="nofollow">AccessTokenService</a> is to exchange a token grant for a new
access token which will be used by the client to access the end user's reso
urces. <br clear="none"> Here is an example request log:</p><div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">Address: http://localhost:8080/services/oauth/token
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">Address: http://localhost:8080/services/oauth/token
Http-Method: POST
Headers: {
@@ -241,7 +241,7 @@ grant_type=authorization_code&code=5
&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fservices%2Freservations%2Freserve%2Fcomplete
</pre>
</div></div><p>This request contains a client_id and client_secret
(Authorization header), the grant_type, the grant value (code) plus the
redirect URI the authorization grant was returned to which is needed for the
additional validation. Note that the alternative client authentication methods
are also possible, in this case the token service will expect a mapping between
the client credentials and the client_id representing the client registration
available.</p><p>After validating the request, the service will find a matching
<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/provider/AccessTokenGrantHandler.java"
rel="nofollow">AccessTokenGrantHandler</a> and request to create a <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/common/ServerAccessT
oken.java" rel="nofollow">ServerAccessToken</a> which is a server-side
representation of the access token.<br clear="none"> The grant handlers, such
as <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/code/AuthorizationCodeGrantHandler.java"
rel="nofollow">AuthorizationCodeGrantHandler</a> may delegate the creation of
the actual access token to data providers, which will create access tokens with
the help of utility classes shipped with CXF or depend on other 3rd party token
libraries.</p><p>The data providers do not strictly required to persist the
data such as access tokens, instead the token key may act as an encrypted bag
capturing all the relevant information.</p><p>Note that AccessTokenService may
not need to have <a shape="rect" class="external-link"
href="https://github.com/apache/cxf/blob/master/rt/rs/security/oauth-parent/oauth2/src/main/java/org/a
pache/cxf/rs/security/oauth2/provider/AccessTokenGrantHandler.java"
rel="nofollow">AccessTokenGrantHandler</a> injected - if it finds out that the
data provider is AuthorizationCodeDataProvider then it will create <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/code/AuthorizationCodeGrantHandler.java"
rel="nofollow">AuthorizationCodeGrantHandler</a> itself. This will work well
unless <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/code/AuthorizationCodeGrantHandler.java"
rel="nofollow">AuthorizationCodeGrantHandler</a> itself needs to be customized
and thus directly injected into AccessTokenService.</p><p>Now that the token
has been created, it is mapped by the service to a <a shape="rect"
class="external-link" href="http://svn.apa
che.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/ClientAccessToken.java">client
access token representation</a> and is returned back as a JSON
payload:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">Response-Code: 200
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">Response-Code: 200
Content-Type: application/json
Headers: {
Cache-Control=[no-store],
@@ -255,7 +255,7 @@ Payload:
</pre>
</div></div><p>The client will use this access token to access the current
user's resources in order to complete the original user's request, for example,
the request to access a user's calendar may look like this:</p><div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">Address:
http://localhost:8080/services/thirdPartyAccess/calendar
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">Address:
http://localhost:8080/services/thirdPartyAccess/calendar
Http-Method: GET
Headers:
{
@@ -264,7 +264,7 @@ Headers:
}
</pre>
</div></div><p>Note that the access token key is passed as the Bearer scheme
value. Other token types such as MAC ones, etc, can be represented
differently.</p><h3 id="JAX-RSOAuth2-AccessTokenTypes">Access Token
Types</h3><p>As mentioned above, AccessTokenService can work with whatever
token is created by a given data provider. This section provides more
information on how CXF may help with supporting Bearer and other token
types.</p><h4 id="JAX-RSOAuth2-Bearer">Bearer</h4><p>The following code
fragment shows how a <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/tokens/bearer/BearerAccessToken.java"
rel="nofollow">BearerAccessToken</a> utility class can be used to create
Bearer tokens:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">import
org.apache.cxf.rs.security.oauth2.common.AccessTokenRegistration;
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">import
org.apache.cxf.rs.security.oauth2.common.AccessTokenRegistration;
import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken;
import org.apache.cxf.rs.security.oauth2.tokens.bearer.BearerAccessToken;
@@ -289,7 +289,7 @@ public class CustomOAuthDataProvider imp
}
</pre>
</div></div><p>CustomOAuthDataProvider will also be asked by
OAuthRequestFilter to validate the incoming Bearer tokens given that they
typically act as database key or key alias, if no Bearer token validator is
registered.</p><p>Note that all the default providers shipped with CXF create
and persist Bearer access tokens themselves.</p><h4
id="JAX-RSOAuth2-HAWK">HAWK</h4><p>Starting from CXF 3.0.0-milestone2 the <a
shape="rect" class="external-link" href="https://github.com/hueniverse/hawk"
rel="nofollow">Hawk</a> scheme is supported instead of MAC (described in the
next section). The way it is supported is identical to the way MAC scheme is
supported in earlier CXF versions. The only differences are: 'Hawk' replaces
'Mac' in the Authorization header, the Hawk token returned by the server will
have 'secret' and 'algorithm' parameters instead of 'mac_key' and
'mac_algorithm' parameters.</p><h4 id="JAX-RSOAuth2-MAC">MAC</h4><p>The text
below applies to CXF up to 3.0.0-milestone2. Start
ing from 3.0.0-milestone2 MAC scheme is not supported, see above about the
Hawk scheme. See also <a shape="rect" class="external-link"
href="https://tools.ietf.org/html/rfc7800" rel="nofollow">OAuth2 Proof Of
Possession Tokens</a> which will be supported in CXF in the future.</p><p>CXF
2.6.2 supports MAC tokens as specified in the latest <a shape="rect"
class="external-link"
href="http://tools.ietf.org/html/draft-ietf-oauth-v2-http-mac-05"
rel="nofollow">MAC Access Authentication draft</a> created by Eran Hammer and
others. MAC tokens offer an option for clients to demonstrate they 'hold' the
token secret issued to them by AccessTokenService.<br clear="none"> It is
recommended that AccessTokenService endpoint issuing MAC tokens enforces a
two-way TLS for an extra protection of the MAC token data returned to
clients.</p><p>The following code fragment shows how a <a shape="rect"
class="external-link"
href="http://svn.apache.org/repos/asf/cxf/branches/2.7.x//rt/rs/security/oauth-parent
/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/MacAccessToken.java">MacAccessToken</a>
utility class can be used to create MAC tokens:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">import
org.apache.cxf.rs.security.oauth2.common.AccessTokenRegistration;
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">import
org.apache.cxf.rs.security.oauth2.common.AccessTokenRegistration;
import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken;
import org.apache.cxf.rs.security.oauth2.tokens.mac.HmacAlgorithm;
import org.apache.cxf.rs.security.oauth2.tokens.mac.MacAccessToken;
@@ -314,7 +314,7 @@ public class CustomOAuthDataProvider imp
}
</pre>
</div></div><p>One can expect the following response:</p><div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">Response-Code: 200
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">Response-Code: 200
Content-Type: application/json
Headers: {
Cache-Control=[no-store],
@@ -328,7 +328,7 @@ Payload:
"mac_algorithm"="hmac-sha-1"}
</pre>
</div></div><p>Note that 'access_token' is the MAC key identifier.</p><p><a
shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/cxf/branches/2.7.x/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/MacAccessTokenValidator.java">MacAccessTokenValidator</a>
has to be registered with OAuthRequestFilter for validating the incoming MAC
tokens. This validator can get a reference to custom <a shape="rect"
class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceVerifier.java">NonceVerifier</a>
with CXF possibly shipping a default implementation in the future.</p><p>The
client can use CXF OAuthClientUtils to create Authorization MAC headers. All is
needed is to provide references to ClientAccessToken representing the MAC token
issued by AccessTokenService and <a shape="rect" class="external-link"
href="http://svn.apac
he.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/HttpRequestProperties.java">HttpRequestProperties</a>
capturing the information about the current request URI:</p><div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">String requestURI = "http://localhost:8080/calendar";
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">String requestURI = "http://localhost:8080/calendar";
WebClient wc = WebClient.create(requestURI);
// represents client registration
@@ -343,7 +343,7 @@ wc.header("Authorization", authHeader);
Calendar calendar = wc.get(Calendar.class);
</pre>
</div></div><p>This code will result in something like:</p><div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">GET /calendar HTTP/1.1
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">GET /calendar HTTP/1.1
Host: localhost
Accept: application/xml
Authorization: MAC id="5b5c8e677413277c4bb8b740d522b378",
@@ -352,7 +352,7 @@ Authorization: MAC id="5b5c8e677413277c4
ts="12345678"
</pre>
</div></div><p>where 'ts' attribute is used to pass a timestamp value.</p><h4
id="JAX-RSOAuth2-EncryptedTokens">Encrypted
Tokens</h4><p><strong>Note</strong>: consider using <a shape="rect"
href="http://cxf.apache.org/docs/jax-rs-jose.html#JAX-RSJOSE-JWEEncryption">JWE
Encryption</a> with JWT access tokens (see next section).</p><p>Typically, the
tokens are persisted in the storage. The alternative approach is to completely
encrypt the token state and return the encrypted representation back to a
client: the processing time to do with the encryption and decryption might
increase but the server wins on avoiding the DB / storage lookups.  
 </p><p>CXF 3.0.0-milestone2 introduces the utility support for encrypting
the state of BearerAccessToken and RefreshToken.</p><p>The tokens can be
encrypted and decrypted with symmetric (secret) keys or certificates (public
and private keys) and the combination of certificates and secret keys.</p><p><a
shape="rect" class="external-li
nk"
href="https://github.com/apache/cxf/blob/master/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/ModelEncryptionSupport.java"
rel="nofollow">ModelEncryptionSupport</a> can be used to encrypt the tokens
using the custom serialization format.</p><p>Note that ServerAuthorizationGrant
and Client can also be encrypted.</p><p> </p><p>The simplest strategy is
to encrypt and decrypt the tokens with the symmetric/secret keys. Every new
token can be encrypted with a unique secret key or all of them can be encrypted
with a single secret key. The utilities provide few methods for creating secret
keys with the default and advanced properties, in addition there are many
examples around on how to create the keys with the specific
properties.</p><p>For example, see
org.apache.cxf.rs.security.oauth2.grants.code.DefaultEncryptingCodeDataProvider
and org.apache.cxf.rs.security.oauth2.provider.DefaultEncryptingOAuthDataProvider
which are ship
ped starting from CXF 3.0.2.</p><p>Here is a typical code demonstrating how
the encryption/decryption works:</p><p> </p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">SecretKey key = CryptoUtils.getSecretKey();
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">SecretKey key = CryptoUtils.getSecretKey();
// create a new token, encrypt its state and return
@@ -368,11 +368,11 @@ return token;
ModelEncryptionSupport.decryptAccessToken(this, encryptedToken, key);</pre>
</div></div><pre> </pre><h4 id="JAX-RSOAuth2-JWTTokens">JWT
Tokens</h4><p>Starting from CXF 3.1.8 some of CXF OAuthDataProvider
implementations (EhCache, JCache and JPA2 based) support Access Token
representations in JWT. This means that ServerAccessTokens created by data
providers are converted to a sequence of JSON JWT claims and then JWS signed
and/or JWE encrypted.</p><p>Custom data providers can extend <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/provider/AbstractOAuthDataProvider.java"
rel="nofollow">AbstractOAuthDataProvider</a> to depend on the code which
converts ServerAccessTokens to JWT and 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/utils/JwtTokenUtils.java"
rel="nofollow">JwtTokenUtils</a> to convert JOSE token repre
sentations back to ServerAccessToken.</p><p>For example, here is how one can
configure one of CXF data providers to use JWT:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><bean id="oauthProvider"
class="org.apache.cxf.rs.security.oauth2.grants.code.DefaultEHCacheCodeDataProvider">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><bean id="oauthProvider"
class="org.apache.cxf.rs.security.oauth2.grants.code.DefaultEHCacheCodeDataProvider">
<property name="useJwtFormatForAccessTokens" value="true"/>
</bean></pre>
</div></div><p>Additionally, in order to sign and/or encrypt, this provider
can be injected with an instance of <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/provider/OAuthJoseJwtProducer.java"
rel="nofollow">OAuthJoseJwtProducer</a> or AccessTokenService endpoint where
this provider is registered can be configured as follows:</p><p> </p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><jaxrs:server id="oauthServer1"
address="https://localhost:${testutil.ports.jaxrs-oauth2-serviceJwt}/services">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><jaxrs:server id="oauthServer1"
address="https://localhost:${testutil.ports.jaxrs-oauth2-serviceJwt}/services">
<jaxrs:serviceBeans>
   <ref bean="tokenService"/>
</jaxrs:serviceBeans><!-- Sign -->
@@ -382,12 +382,12 @@ ModelEncryptionSupport.decryptAccessToke
</jaxrs:properties>
</jaxrs:server></pre>
</div></div><p>Note that in this case Ehcache, JCache and JPA2 providers will
still persist the complete ServerAccessToken representations - once JOSE
sequence is created it becomes a new tokenId of the current ServerAccessToken,
with the original tokenId becoming a JWT 'jti' claim.</p><p>The main advantage
is that such tokens can be introspected locally at the resource server side,
thus avoiding the remote token validation calls.</p><p>One can configure the
providers (Ehcache and JCache only at the moment) to persist access tokens only
as these newly created JOSE sequences:</p><p> </p><div class="code panel
pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><bean id="oauthProvider"
class="org.apache.cxf.systest.jaxrs.security.oauth2.common.OAuthDataProviderImpl">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><bean id="oauthProvider"
class="org.apache.cxf.systest.jaxrs.security.oauth2.common.OAuthDataProviderImpl">
<property name="useJwtFormatForAccessTokens" value="true"/>
<property name="storeJwtTokenKeyOnly" value="true"/>
</bean></pre>
</div></div><p>Only a JOSE sequence representing a given ServerAccessToken
will be persisted. The providers will recreate ServerAccessToken from this
sequence when the token is needed by the runtime, while requiring much less
storage to keep such tokens. In this case, if it is preferred, one can further
optimize it not to even store these secure string token representations -
however the major downside is that it will be impossible to manage such tokens
from the administration consoles due to no record of such tokens will be
available in the storage.</p><p>Resource server (RS) will need to make a
decision how to validate this JWT token. It can continue validating it remotely
with AccessTokenValidationService or TokenIntrsopectionService (see below for
more info about these services) or if RS has an access to the keys used to
sign/encrypt JWT then it can use a local JWT validation,
example:</p><p> </p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><bean id="jwtTokenValidator"
class="org.apache.cxf.rs.security.oauth2.filters.JwtAccessTokenValidator"/>
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><bean id="jwtTokenValidator"
class="org.apache.cxf.rs.security.oauth2.filters.JwtAccessTokenValidator"/>
<bean id="oAuthFilterLocalValidation"
class="org.apache.cxf.rs.security.oauth2.filters.OAuthRequestFilter">
<property name="tokenValidator" ref="jwtTokenValidator"/>
</bean>
@@ -406,7 +406,7 @@ ModelEncryptionSupport.decryptAccessToke
</jaxrs:properties>
</jaxrs:server></pre>
</div></div><p> </p><p>When to use JWT ? The pros are: might be easier to
align with some newer OAuth2 related specifications, might be possible to avoid
a remote validation call, possible OAuth2 server storage optimization. Cons:
the extra cost of validating (or decrypting), access token value reported to
and used by clients becomes larger. If JWS only is used - care should be taken
to avoid putting some sensitive JWT claims given that JWS payload can be
introspected.</p><p>See <a shape="rect"
href="http://cxf.apache.org/docs/jax-rs-jose.html">JAX-RS JOSE</a> wiki page
for more information on how to sign and encrypt JSON Web Tokens. Specifically,
if you need to create JWT values in your custom providers, then have a look at
<span class="confluence-link"> </span><a shape="rect"
href="http://cxf.apache.org/docs/jax-rs-jose.html#JAX-RSJOSE-JOSEinJAX-RSapplicationcode"><span
class="confluence-link">this section</span></a>: one can delegate to or extend
<strong>JoseJwtConsumer
</strong> or <strong>JoseJwtProducer</strong>. Addtionally
org.apache.cxf.rs.security.oauth2.provider.<strong>OAuthJoseJwtConsumer</strong>
(and <strong>OAuthJoseJwtProducer</strong>) can help in cases where OAuth2
Client secret is used as a key for HMAC based signatures or encryptions, while
<strong>OAuthServerJoseJwtConsumer</strong> (and
<strong>OAuthServerJoseJwtProducer</strong>) can also use OAuth2 Client
certificates.</p><p> </p><h4 id="JAX-RSOAuth2-Customtokens">Custom
tokens</h4><p>If needed, users can use their own custom token types, with the
only restriction that the custom token type implementations have to extend
org.apache.cxf.rs.security.oauth2.common.ServerAccessToken.</p><h4
id="JAX-RSOAuth2-SimpleTokensandAudience">Simple Tokens and
Audience</h4><p>Starting from CXF 2.7.7 an <a shape="rect"
class="external-link"
href="http://tools.ietf.org/html/draft-tschofenig-oauth-audience-00"
rel="nofollow">audience</a> parameter is supported during the client token reque
sts.</p><h3
id="JAX-RSOAuth2-OAuthJSONProvider">OAuthJSONProvider</h3><p>org.apache.cxf.rs.security.oauth2.provider.OAuthJSONProvider
is a JAX-RS MessageBodyWriter which supports returning ClientAccessToken and
OAuthError representations to the client in a JSON format required by OAuth2
spec. It is also a JAX-RS MessageBodyReader that is used by client
OAuthClientUtils (see below) to read the responses from
AccessTokenService.</p><p>Register it as a provider with a JAXRS
AccessTokenService endpoint.</p><p>Alternatively, if you prefer, a custom
MessageBodyWriter implementation can be registered instead.</p><h2
id="JAX-RSOAuth2-AccessTokenValidationService">Access Token Validation
Service</h2><h3
id="JAX-RSOAuth2-AccessTokenValidatorService">AccessTokenValidatorService</h3><p>The
<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/services/AccessTokenValidatorService.ja
va" rel="nofollow">AccessTokenValidatorService</a> is a CXF specific OAuth2
service for accepting the remote access token validation requests.
OAuthRequestFilter needs to be injected with <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/filters/AccessTokenValidatorClient.java"
rel="nofollow">AccessTokenValidatorClient</a> which will ask
AccessTokenValidatorService to return the information relevant to the current
access token, before setting up a security context.</p><h3
id="JAX-RSOAuth2-TokenIntrospectionService">TokenIntrospectionService</h3><p>The
<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/services/TokenIntrospectionService.java"
rel="nofollow">TokenIntrospectionService</a> is a standard OAuth2 service for
accepting the remote access toke
n introspection requests. See <a shape="rect" class="external-link"
href="https://tools.ietf.org/html/rfc7662" rel="nofollow">RFC 7662</a>.
OAuthRequestFilter needs to be injected with <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/filters/AccessTokenIntrospectionClient.java"
rel="nofollow">AccessTokenIntrospectionClient.</a></p><h2
id="JAX-RSOAuth2-TokenRevocationService">TokenRevocationService</h2><p><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/services/TokenRevocationService.java"
rel="nofollow">TokenRevocationService</a> is a simple OAuth2 service
supporting the clients wishing to revoke the access or refresh tokens they own
themselves, please see <a shape="rect" class="external-link"
href="http://tools.ietf.org/html/draft-ietf-oauth-rev
ocation-09" rel="nofollow">OAuth2 Token Revocation Draft</a> for more
information.</p><p>TokenRevocationService and AccessTokenService share the same
code which enforces that the clients have been correctly
authenticated.</p><p>Note, OAuthDataProvider implementations processing a
revocation request should simply ignore the invalid tokens as recommended by
the specification which will let TokenRevocationService return HTTP 200 which
is done to minimize a possible attack surface (specifically for bad clients not
to see if their requests failed or succeeded) and throw the exceptions only if
the token revocation feature is not currently supported.</p><h2
id="JAX-RSOAuth2-DynamicRegistrationService">DynamicRegistrationService</h2><p>This
service is available starting from CXF 3.1.8. It supports the dynamic client
<a shape="rect" class="external-link"
href="https://tools.ietf.org/html/rfc7591" rel="nofollow">registration</a> and
<a shape="rect" class="external-link" href="https://tools.ie
tf.org/html/rfc7592" rel="nofollow">management</a>. At the moment some of the
advanced registration properties are not yet processed and linked to the way
the core OAuth2 services operate but the service will be enhanced as needed
going forward.</p><h2
id="JAX-RSOAuth2-AuthorizationMetadataService">AuthorizationMetadataService</h2><p>This
service is available starting from CXF 3.1.8. It supports OAuth2 <a
shape="rect" class="external-link"
href="https://tools.ietf.org/html/draft-ietf-oauth-discovery-04"
rel="nofollow">server configuration</a> queries at
".well-known/oauth-authorization-server".</p><h2
id="JAX-RSOAuth2-SupportedGrants">Supported Grants</h2><p>The following
subsections briefly describe how the well-known grant types can be supported on
the server side. Please also check the "Client Side Support" section on how to
use the related <a shape="rect" class="external-link"
href="https://github.com/apache/cxf/blob/master/rt/rs/security/oauth-parent/oauth2/src/main/java/org/ap
ache/cxf/rs/security/oauth2/common/AccessTokenGrant.java"
rel="nofollow">AccessTokenGrant</a> implementations to request the access
tokens.</p><h3 id="JAX-RSOAuth2-AuthorizationCode">Authorization Code</h3><p>As
described above, <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/services/AuthorizationCodeGrantService.java"
rel="nofollow">AuthorizationCodeGrantService</a> service and <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/code/AuthorizationCodeDataProvider.java"
rel="nofollow">AuthorizationCodeDataProvider</a> data provider can support a
redirection-based Authorization Code flow.</p><p>The code that the client
receives in the end of the redirection process will need to be exchanged for a
new access token with AccessTokenService. CXF-
based clients can use a helper <a shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/AuthorizationCodeGrant.java">AuthorizationCodeGrant</a>
bean to request a new access token with OAuthClientUtils.</p><h3
id="JAX-RSOAuth2-Implicit">Implicit</h3><p>Implicit grant is supported the same
way Authorization Code grant is except that no code is created, a token is
issued immediately and returned to the client running within a web
browser.</p><p><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/services/ImplicitGrantService.java"
rel="nofollow">ImplicitGrantService</a> service asks <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/
provider/OAuthDataProvider.java" rel="nofollow">OAuthDataProvider</a> data
provider to issue a new token after a user has approved it.</p><p>Note the only
difference is the use of ImplicitGrantService instead of
AuthorizationCodeGrantService.</p><p>Also note that when an Implicit grant
client (running within a browser) replaces the code grant for a new access
token and tries to access the end user's resource, Cross Origin Resource
Sharing (CORS) support will most likely need to be enabled on the end user's
resource server.<br clear="none"> The simplest approach is to register a CXF <a
shape="rect" href="http://cxf.apache.org/docs/jax-rs-cors.html">CORS
filter</a>, right before OAuth2 filter (see on it below).</p><p>Starting from
CXF 2.7.5 it is possible to request ImplicitGrantService to return a registered
Client id to the browser-hosted client. This is recommended so that the client
can verify that the token is meant to be delivered to this client.</p><h3
id="JAX-RSOAuth2-ClientCr
edentials">Client Credentials</h3><p>Register <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/clientcred/ClientCredentialsGrantHandler.java"
rel="nofollow">ClientCredentialsGrantHandler</a> handler with
AccessTokenService for this grant be supported.</p><p>CXF-based clients can use
a helper <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/clientcred/ClientCredentialsGrant.java"
rel="nofollow">ClientCredentialsGrant</a> bean to request a new access token
with OAuthClientUtils.</p><h3
id="JAX-RSOAuth2-ResourceOwnerPasswordCredentials">Resource Owner Password
Credentials</h3><p>Register <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/r
s/security/oauth2/grants/owner/ResourceOwnerGrantHandler.java"
rel="nofollow">ResourceOwnerGrantHandler</a> handler with AccessTokenService
for this grant be supported.</p><p>CXF-based clients can use a helper <a
shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/owner/ResourceOwnerGrant.java">ResourceOwnerGrant</a>
bean to request a new access token with OAuthClientUtils.</p><h3
id="JAX-RSOAuth2-RefreshToken">Refresh Token</h3><p>The client can issue a
refresh token grant if the current access token it owns has expired or been
revoked and the refresh token was issued alongside with the access token which
is now invalid and get the new, 'refreshed' access token. This can allow the
client to avoid seeking a new authorization approval from the end
user.</p><p>Register <a shape="rect" class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/securi
ty/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/refresh/RefreshTokenGrantHandler.java">RefreshTokenGrantHandler</a>
handler with AccessTokenService for this grant be supported. Note this grant
handler is only useful for refreshing the existing access token, so one or more
of the other grant handlers (Authorization Code, Implicit, etc) will also have
to be registered with AccessTokenService.</p><p>CXF-based clients can use a
helper <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/owner/ResourceOwnerGrant.java"
rel="nofollow">RefreshTokenGrant</a> bean to request a new access token with
OAuthClientUtils.</p><h3 id="JAX-RSOAuth2-SAMLandJWTAssertions">SAML and JWT
Assertions</h3><p><a shape="rect" class="external-link"
href="https://tools.ietf.org/html/rfc7522" rel="nofollow">SAML2 assertions</a>
and <a shape="rect" class="external-
link" href="https://tools.ietf.org/html/rfc7523" rel="nofollow">JWT
assertions</a> can be used as token grants.</p><p>JWT assertion grants are
supported in <a shape="rect" class="external-link"
href="https://github.com/apache/cxf/tree/master/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/jwt"
rel="nofollow">this package</a>. <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/JwtBearerAuthHandler.java"
rel="nofollow">JwtBearerAuthHandler</a> can be used as a generic client
authentication filter (where the client authenticated with JWT token as opposed
to with a username:password pair, etc).</p><p>Please also see <a shape="rect"
href="jaxrs-oauth2-assertions.html">JAXRS OAuth2 Assertions</a> section for
more information.</p><p> </p><h3 id="JAX-RSOAuth2-CustomGrants">Custom
Grants</h3><p>If you need to customize
the way the well-known grant requests are handled then consider extending one
of the grant handlers listed in the previous sub-sections.</p><p>Alternatively
create a custom <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/provider/AccessTokenGrantHandler.java"
rel="nofollow">AccessTokenGrantHandler</a> and register it with
AccessTokenService. Additionally, consider providing a related <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/common/AccessTokenGrant.java"
rel="nofollow">AccessTokenGrant</a> implementation for making it easy for the
client code to request a new access token with this custom grant.</p><h2
id="JAX-RSOAuth2-RedirectionFlowFilters">Redirection Flow Filters</h2><p><a
shape="rect" class="external-link" href="https://github.c
om/apache/cxf/blob/master/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AuthorizationRequestFilter.java"
rel="nofollow">AuthorizationRequestFilter</a> implementations can be
registered with AuthorizationCodeGrantService or ImplicitGrantService in order
to pre-process code requests. For example, <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/code/JwtRequestCodeFilter.java"
rel="nofollow">JwtRequestCodeFilter</a> can be used to process JWS-signed or
JWE-encrypted code requests.</p><p><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/provider/AuthorizationCodeResponseFilter.java"
rel="nofollow">AuthorizationCodeResponseFilter</a> implementations can be
registered with AuthorizationCodeService in o
rder to post-process code responses.</p><h2
id="JAX-RSOAuth2-AccessTokenResponseFilters">AccessTokenResponse
Filters</h2><p><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/provider/AccessTokenResponseFilter.java"
rel="nofollow">AccessTokenResponseFilter</a> implementations can be registered
with AccessTokenService in order to post-process access token responses. For
example,  OIDC IdToken can be added to a response with a <a shape="rect"
class="external-link"
href="https://github.com/apache/cxf/blob/master/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/idp/IdTokenResponseFilter.java"
rel="nofollow">IdTokenResponseFilter</a>.</p><h2
id="JAX-RSOAuth2-PreAuthorizedaccesstokens">PreAuthorized access
tokens</h2><p>When working with the flows which require the end users/resource
owners explicitly authorizing clients (for example, as in the ca
se of redirection-based flows), using pre-authorized access tokens is one
option to minimize the need for the end-user intervention. <br clear="none">
OAuthDataProvider is always checked first if the pre-authorized access token
for a given Client exists and if yes then it will be returned immediately,
without starting the authorization process involving the end user (as required
by some flows).</p><p>Consider providing a user interface which will let the
end users/resource owners to pre-authorize specific clients early. Note, a CXF
service for supporting the users pre-authorizing the clients or revoking the
tokens for some of the clients may be introduced in the future.</p><p>Also note
that using a refresh token grant may further help with minimizing the end user
involvement, in cases when the current access token has expired.</p><h2
id="JAX-RSOAuth2-Pre-registeredscopes">Pre-registered scopes</h2><p>Clients can
register custom scopes they will be expected to use and then avoid spec
ifying the scopes when requesting the code grants or access tokens.<br
clear="none"> Alternatively it makes it easier to support so called wild-card
scopes. For example, a client pre-registers a scope "update" and actually uses
an "update-7" scope: Redirection-based services and access token grants can be
configured to do a partial scope match, in this case, validate that "update-7"
starts from "update"</p><h2 id="JAX-RSOAuth2-WritingOAuthDataProvider">Writing
OAuthDataProvider</h2><p>Using CXF OAuth service implementations will help a
lot with setting up an OAuth server. As you can see from the above sections,
these services rely on a custom <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/provider/OAuthDataProvider.java"
rel="nofollow">OAuthDataProvider</a> implementation.</p><p>The main task of <a
shape="rect" class="external-link" href="https://github.com/apach
e/cxf/blob/master/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/OAuthDataProvider.java"
rel="nofollow">OAuthDataProvider</a> is to persist and generate access tokens.
Additionally, as noted above, <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/code/AuthorizationCodeDataProvider.java"
rel="nofollow">AuthorizationCodeDataProvider</a> needs to persist and remove
the code grant registrations. The way it's done is really application-specific.
Consider starting with a basic memory based implementation and then move on to
keeping the data in some DB.</p><p>Finally OAuthDataProvider may need to
convert opaque scope values such as "readCalendar" into a list of <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/common/OAuthPermission.java" rel="nofollow">OAuthPermission</a>s.
AuthorizationCodeGrantService and OAuth2 security filters will depend on it
(assuming scopes are used in the first place). </p><h3
id="JAX-RSOAuth2-DefaultProviders">Default Providers</h3><p>CXF 3.1.7 ships
JPA2 (<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/provider/JPAOAuthDataProvider.java"
rel="nofollow">JPAOAuthDataProvider</a> and <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/code/JPACodeDataProvider.java"
rel="nofollow">JPACodeDataProvider</a>), Ehcache (<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/provider/DefaultEHCacheOAuthDat
aProvider.java" rel="nofollow">DefaultEHCacheOAuthDataProvider</a> and <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/code/DefaultEHCacheCodeDataProvider.java"
rel="nofollow">DefaultEHCacheCodeDataProvider</a>) and JCache (<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/provider/JCacheOAuthDataProvider.java"
rel="nofollow">JCacheOAuthDataProvider</a> and <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/code/JCacheCodeDataProvider.java"
rel="nofollow">JCacheCodeDataProvider</a>) provider implementations which take
care of all the persistence tasks: saving or removing registered clients,
tokens and code grants. The
se providers can be easily customized.</p><p>Custom implementations can also
extend  <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/provider/AbstractOAuthDataProvider.java"
rel="nofollow">AbstractOAuthDataProvider</a> or <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/code/AbstractCodeDataProvider.java"
rel="nofollow">AbstractCodeDataProvider</a>  and only implement their
abstract persistence related methods or further customize some of their
code.</p><h2 id="JAX-RSOAuth2-OAuthServerJAX-RSendpoints">OAuth Server JAX-RS
endpoints</h2><p>With CXF offering OAuth service implementations and a custom
OAuthDataProvider provider in place, it is time to deploy the OAuth2 server.
<br clear="none"> Most likely, you'd want to deploy Acces
sTokenService as an independent JAX-RS endpoint, for example:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><!-- implements OAuthDataProvider -->
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><!-- implements OAuthDataProvider -->
<bean id="oauthProvider" class="oauth.manager.OAuthManager"/>
<bean id="accessTokenService"
class="org.apache.cxf.rs.security.oauth2.services.AccessTokenService">
@@ -420,7 +420,7 @@ ModelEncryptionSupport.decryptAccessToke
</jaxrs:server>
</pre>
</div></div><p>AccessTokenService listens on a relative "/token" path. Given
that jaxrs:server/@adress is "/oauth" and assuming a context name is
"/services", the absolute address of AccessTokenService would be something like
"http://localhost:8080/services/oauth/token".</p><p>If the remote token
validation is supported then have AccessTokenValidatorService added
too:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><!-- implements OAuthDataProvider -->
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><!-- implements OAuthDataProvider -->
<bean id="oauthProvider" class="oauth.manager.OAuthManager"/>
<bean id="accessTokenService"
class="org.apache.cxf.rs.security.oauth2.services.AccessTokenService">
@@ -438,7 +438,7 @@ ModelEncryptionSupport.decryptAccessToke
</jaxrs:server>
</pre>
</div></div><p>The absolute address of AccessTokenValidateService would be
something like
"http://localhost:8080/services/oauth/validate".</p><p>AuthorizationCodeGrantService
is easier to put where the application endpoints are. It can be put alongside
AccessTokenService, but ideally an SSO based authentication solution will be
also be deployed, for the end user to avoid signing in separately several times
(see more in it below). Here is an example of AuthorizationCodeGrantService and
ImplicitGrantService being collocated with the application endpoint:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><bean id="authorizationService"
class="org.apache.cxf.rs.security.oauth2.services.AuthorizationCodeGrantService">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><bean id="authorizationService"
class="org.apache.cxf.rs.security.oauth2.services.AuthorizationCodeGrantService">
<property name="dataProvider" ref="oauthProvider"/>
</bean>
@@ -457,7 +457,7 @@ ModelEncryptionSupport.decryptAccessToke
</jaxrs:server>
</pre>
</div></div><p>AuthorizationCodeGrantService listens on a relative
"/authorize" path so in this case its absolute address will be something like
"http://localhost:8080/services/myapp/authorize". This address and that of
AccessTokenService will be used by third-party
clients.</p><p>ImplictGrantService listens on a relative "/authorize-implicit"
path</p><h3
id="JAX-RSOAuth2-AuthorizationCodeandImplicitServicesonthesamerelativepath">AuthorizationCode
and Implicit Services on the same relative path</h3><p>As has already been
mentioned in the previous section,  AuthorizationCodeGrantService and
ImplictGrantService listen on two different relative paths: "/authorize" and
"/authorize-implicit". Having both services available at different addresses
may not always be preferred though. If preferred, one can 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/services/A
uthorizationService.java" rel="nofollow">AuthorizationService</a> 'container'
service:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><bean id="authorizationService"
class="org.apache.cxf.rs.security.oauth2.services.AuthorizationCodeGrantService">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><bean id="authorizationService"
class="org.apache.cxf.rs.security.oauth2.services.AuthorizationCodeGrantService">
<property name="dataProvider" ref="oauthProvider"/>
</bean>
@@ -484,7 +484,7 @@ ModelEncryptionSupport.decryptAccessToke
</jaxrs:server>
</pre>
</div></div><p>See this <a shape="rect" class="external-link"
href="https://github.com/apache/cxf-fediz/blob/master/services/oidc/src/main/webapp/WEB-INF/applicationContext.xml"
rel="nofollow">application context</a> for another example.</p><h1
id="JAX-RSOAuth2-ThirdPartyClientAuthentication">Third Party Client
Authentication</h1><p>When a client requests a token from Access Token Service,
it needs to get authenticated. Providing its client_id and client secret as
part of Basic Authorization scheme or posting them directly as form parameters
are typical options, however other authentication schemes can easily be
supported if required.</p><p>For example, using client certificates or
assertions like SAML2 Bearer or JWT is all acceptable - the only additional
requirement in this case is that a given security filter processing a specific
authentication scheme maps the client credentials to an actual client_id - CXF
Access Token Service will check a "client_id" property on the current me
ssage context as the last resort. Note that
org.apache.cxf.rs.security.oauth2.provider.ClientIdProvider can be registered
with AccessTokenService to facilitate the mapping between an authenticated
client and its id expected by the data provider if the container or filter
based authentication can not set a "client_id" contextual property.</p><p>If a
Basic authentication scheme is used and neither the container or filter has
authenticated the client AccessTokenService will request a Client from the data
provider and compare the Client's secret against the password found in the
Basic scheme data.
org.apache.cxf.rs.security.oauth2.provider.ClientSecretVerifier is available
starting from CXF 3.0.3 to support Clients saving only password hashes. Its
org.apache.cxf.rs.security.oauth2.provider.ClientSecretHashVerifier (calculates
a SHA-256 password hash and compares it with the Client's secret) or custom
implementations can be registered with AccessTokenService.</p><p>Please see <a
shape="r
ect" href="jaxrs-oauth2-assertions.html">JAXRS OAuth2 Assertions</a> section
for more information on how it may work.</p><h2
id="JAX-RSOAuth2-ClientCertificateAuthentication">Client Certificate
Authentication</h2><p>If a 2-way TLS is used to authenticate a client and
Client has a Base64 encoded representations of its X509Certificates available
in its "applicationCertificates" property then AccessTokenService will do the
additional comparison of these certificates against the ones available in the
current TLS session.</p><p><strong>New</strong>: <a shape="rect"
class="external-link"
href="https://tools.ietf.org/html/draft-campbell-oauth-mtls-01"
rel="nofollow">Mutual TLS Profiles for OAuth2 Clients</a> is completely
supported since CXF 3.1.12. Note some parameters used in this draft may
change.</p><h1 id="JAX-RSOAuth2-UserSessionAuthenticity">User Session
Authenticity</h1><p>Redirection-based Authorization Code and Implicit flows
depend on end users signing in if needed during the in
itial redirection, challenged with the client authorization form and returning
their decision. By default, CXF will enforce the user session authenticity by
keeping the session state in a servlet container's HTTPSession. If the
alternative storage is preferred then you can register a new <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/provider/SessionAuthenticityTokenProvider.java"
rel="nofollow">SessionAuthenticityTokenProvider</a> with either
AuthorizationCodeGrantService or ImplicitGrantService beans.</p><p>CXF ships <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/provider/JoseSessionTokenProvider.java"
rel="nofollow">JoseSessionTokenProvider </a>which uses <a shape="rect"
href="http://cxf.apache.org/docs/jax-rs-jose.html">CXF JOSE</a> to cre
ate a compact JWS and/or JWE sequence capturing all the data which need to be
available when the user returns an authorization form decision and this secure
sequence becomes a session token.</p><h3
id="JAX-RSOAuth2-Keepingthestateinthesession">Keeping the state in the
session</h3><p>Note that <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/provider/SessionAuthenticityTokenProvider.java"
rel="nofollow">SessionAuthenticityTokenProvider</a> has been further updated
in CXF 3.1.0 to support signing and/or encrypting some of the redirection
properties that would otherwise have to be kept as HTML form hidden fields (see
"Authorization Service" section).</p><p>CXF  ships <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/provider/JoseSession
TokenProvider.java" rel="nofollow">JoseSessionTokenProvider </a>which uses <a
shape="rect" href="http://cxf.apache.org/docs/jax-rs-jose.html">CXF JOSE</a>
that can be used as a SessionAuthenticityTokenProvider which JWS-signs and/or
JWE-encrypts the properties and saves the result in the session. The HTML
authorization forms will only have to have an "authenticityToken" property
which the provider will use to match the session signed/encryped data and
decrypt and/or validate the session data.</p><h3
id="JAX-RSOAuth2-MultipleFactorVerification">Multiple Factor
Verification</h3><p>Note that <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/provider/SessionAuthenticityTokenProvider.java"
rel="nofollow">SessionAuthenticityTokenProvider</a> has been updated in CXF
3.0.2 to accept request parameters and a reference to the authenticated user.
This allows for introduci
ng a multiple factor session verification: when the provider created a session
property it can for example sent a message to a user's mobile phone expect the
authorization consent form return the sent value.</p><p>The other minor
enhancement is that RedirectionBasedGrantService will check the authorization
content form for the name of the form property that contains a session
authentication property, using a "session_authenticity_token_param_name"
property name. This allows for the 'rotation' of hidden form properties
containing the actual session authenticity values.</p><h1
id="JAX-RSOAuth2-CustomizingEndUserSubjectinitialization">Customizing End User
Subject initialization</h1><p>By default, redirection based authorization
services will the the current CXF SecurityContext to initialize a subject
representing the authenticated resource owner/end user. If the customization if
needed: custom CXF filter can be used to create UserSubject and set it on the
message or org.apache.cxf.rs.s
ecurity.oauth2.provider.SubjectCreator interface implementation can be
registered with either AuthorizationCodeGrantService or
ImplicitGrantService.</p><h1
id="JAX-RSOAuth2-ProtectingresourceswithOAuthfilters">Protecting resources with
OAuth filters</h1><p><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/filters/OAuthRequestFilter.java"
rel="nofollow">OAuthRequestFilter</a> request handler can be used to protect
the resource server when processing the requests from the third-party clients.
Add it as a jaxrs:provider to the endpoint which deals with the clients
requesting the resources.</p><p>When checking a request like this:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">Address:
http://localhost:8080/services/thirdPartyAccess/calendar
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">Address:
http://localhost:8080/services/thirdPartyAccess/calendar
Http-Method: GET
Headers:
{
@@ -493,7 +493,7 @@ Headers:
}
</pre>
</div></div><p>the filter will do the following:</p><p>1. Retrieve a
ServerAccessToken by delegating to a matching registered <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/provider/AccessTokenValidator.java"
rel="nofollow">AccessTokenValidator</a>. AccessTokenValidator is expected to
check the validity of the incoming token parameters and possibly delegate to
OAuthDataProvider to find the token representation - this is what the filter
will default to if no matching AccessTokenValidator is found and the
Authorization scheme is 'Bearer'.</p><p>2. Check the token has not
expired</p><p>3. AccessToken may have a list of <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/common/OAuthPermission.java"
rel="nofollow">OAuthPermission</a>. For every permiss
ion it will:</p><ul class="alternate"><li>If it has a uri property set then
the current request URI will be checked against it</li><li>If it has an
httpVerb property set then the current HTTP verb will be checked against
it</li></ul><p>If an allPermissionsMatch property is set then the filter will
check that all the token permissions have been met.</p><p>If a requestScopes
property is set then the filter will check that all of the scopes are 'covered'
by one or more token permissions.</p><p>4. Finally, it will create a CXF
SecurityContext using this list of <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/common/OAuthPermission.java"
rel="nofollow">OAuthPermissions</a>, the <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/common/UserSubject.java"
rel="nofollow">UserSubject</a> representing the client or the end user who
authorized the grant used to obtain this token.</p><p>This SecurityContext will
not necessarily be important for some of OAuth2 applications. Most of the
security checks will be done by OAuth2 filters and security filters protecting
the main application path the end users themselves use. Only if you would like
to share the same JAX-RS resource code and access URIs between end users and
clients then it can become handy. More on it below.</p><p>Here is one example
of how OAuthRequestFilter can be configured:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><bean id="oauthProvider"
class="oauth.manager.OAuthManager"/>
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><bean id="oauthProvider"
class="oauth.manager.OAuthManager"/>
<bean id="oauthFiler"
class="org.apache.cxf.rs.security.oauth2.filters.OAuthRequestFilter">
<property name="dataProvider" ref="oauthProvider"/>
</bean>
@@ -511,7 +511,7 @@ Headers:
</jaxrs:server>
</pre>
[... 115 lines stripped ...]