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 Tue Sep 12 19:09:41 2017 @@ -32,8 +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/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(); @@ -118,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.rbtoc1497545226730 {padding: 0px;} -div.rbtoc1497545226730 ul {list-style: disc;margin-left: 0px;} -div.rbtoc1497545226730 li {margin-left: 0px;padding-left: 0px;} +div.rbtoc1505242951945 {padding: 0px;} +div.rbtoc1505242951945 ul {list-style: disc;margin-left: 0px;} +div.rbtoc1505242951945 li {margin-left: 0px;padding-left: 0px;} -/*]]>*/</style></p><div class="toc-macro rbtoc1497545226730"> +/*]]>*/</style></p><div class="toc-macro rbtoc1505242951945"> <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> @@ -155,20 +156,20 @@ div.rbtoc1497545226730 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: xml; gutter: false; theme: Default" style="font-size:12px;"><dependency> +<pre class="brush: bash; gutter: false; theme: Confluence" 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: xml; gutter: false; theme: Default" style="font-size:12px;">Response-Code: 303 +<pre class="brush: bash; gutter: false; theme: Confluence" 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: xml; gutter: false; theme: Default" style="font-size:12px;">Address: http://localhost:8080/services/social/authorize?client_id=123456789&scope=updateCalendar-7&response_type=code +<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 &redirect_uri=http%3A//localhost%3A8080/services/reservations/reserve/complete&state=1 Http-Method: GET Headers: { @@ -180,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: xml; gutter: false; theme: Default" style="font-size:12px;">12-Apr-2012 13:26:21 org.apache.cxf.rs.security.oauth2.services.AbstractOAuthService checkTransportSecurity +<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 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: xml; gutter: false; theme: Default" style="font-size:12px;">12-Apr-2012 13:26:21 org.apache.cxf.jaxrs.provider.RequestDispatcherProvider logRedirection +<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 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: xml; gutter: false; theme: Default" style="font-size:12px;">Address: http://localhost:8080/services/social/authorize/decision +<pre class="brush: bash; gutter: false; theme: Confluence" 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 @@ -205,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: xml; gutter: false; theme: Default" style="font-size:12px;">Response-Code: 303 +<pre class="brush: bash; gutter: false; theme: Confluence" style="font-size:12px;">Response-Code: 303 Headers: { Location=[http://localhost:8080/services/reservations/reserve/complete?state=1 &code=5c993144b910bccd5977131f7d2629ab], @@ -213,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: java; gutter: false; theme: Default" style="font-size:12px;">Address: http://localhost:8080/services/reservations/reserve/complete?state=1&code=5c993144b910bccd5977131f7d2629ab +<pre class="brush: bash; gutter: false; theme: Confluence" 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], @@ -226,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: xml; gutter: false; theme: Default" style="font-size:12px;">Address: http://localhost:8080/services/oauth/token +<pre class="brush: bash; gutter: false; theme: Confluence" style="font-size:12px;">Address: http://localhost:8080/services/oauth/token Http-Method: POST Headers: { @@ -240,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: xml; gutter: false; theme: Default" style="font-size:12px;">Response-Code: 200 +<pre class="brush: bash; gutter: false; theme: Confluence" style="font-size:12px;">Response-Code: 200 Content-Type: application/json Headers: { Cache-Control=[no-store], @@ -254,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: xml; gutter: false; theme: Default" style="font-size:12px;">Address: http://localhost:8080/services/thirdPartyAccess/calendar +<pre class="brush: bash; gutter: false; theme: Confluence" style="font-size:12px;">Address: http://localhost:8080/services/thirdPartyAccess/calendar Http-Method: GET Headers: { @@ -263,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: java; gutter: false; theme: Default" style="font-size:12px;">import org.apache.cxf.rs.security.oauth2.common.AccessTokenRegistration; +<pre class="brush: bash; gutter: false; theme: Confluence" 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; @@ -288,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: java; gutter: false; theme: Default" style="font-size:12px;">import org.apache.cxf.rs.security.oauth2.common.AccessTokenRegistration; +<pre class="brush: bash; gutter: false; theme: Confluence" 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; @@ -313,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: xml; gutter: false; theme: Default" style="font-size:12px;">Response-Code: 200 +<pre class="brush: bash; gutter: false; theme: Confluence" style="font-size:12px;">Response-Code: 200 Content-Type: application/json Headers: { Cache-Control=[no-store], @@ -327,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: java; gutter: false; theme: Default" style="font-size:12px;">String requestURI = "http://localhost:8080/calendar"; +<pre class="brush: bash; gutter: false; theme: Confluence" style="font-size:12px;">String requestURI = "http://localhost:8080/calendar"; WebClient wc = WebClient.create(requestURI); // represents client registration @@ -342,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: xml; gutter: false; theme: Default" style="font-size:12px;">GET /calendar HTTP/1.1 +<pre class="brush: bash; gutter: false; theme: Confluence" style="font-size:12px;">GET /calendar HTTP/1.1 Host: localhost Accept: application/xml Authorization: MAC id="5b5c8e677413277c4bb8b740d522b378", @@ -351,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: java; gutter: false; theme: Default" style="font-size:12px;">SecretKey key = CryptoUtils.getSecretKey(); +<pre class="brush: bash; gutter: false; theme: Confluence" style="font-size:12px;">SecretKey key = CryptoUtils.getSecretKey(); // create a new token, encrypt its state and return @@ -367,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: java; gutter: false; theme: Default" style="font-size:12px;"><bean id="oauthProvider" class="org.apache.cxf.rs.security.oauth2.grants.code.DefaultEHCacheCodeDataProvider"> +<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"> <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: java; gutter: false; theme: Default" style="font-size:12px;"><jaxrs:server id="oauthServer1" address="https://localhost:${testutil.ports.jaxrs-oauth2-serviceJwt}/services"> +<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"> <jaxrs:serviceBeans>    <ref bean="tokenService"/> </jaxrs:serviceBeans><!-- Sign --> @@ -381,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: java; gutter: false; theme: Default" style="font-size:12px;"><bean id="oauthProvider" class="org.apache.cxf.systest.jaxrs.security.oauth2.common.OAuthDataProviderImpl"> +<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"> <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: java; gutter: false; theme: Default" style="font-size:12px;"><bean id="jwtTokenValidator" class="org.apache.cxf.rs.security.oauth2.filters.JwtAccessTokenValidator"/> +<pre class="brush: bash; gutter: false; theme: Confluence" 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> @@ -405,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: xml; gutter: false; theme: Default" style="font-size:12px;"><!-- implements OAuthDataProvider --> +<pre class="brush: bash; gutter: false; theme: Confluence" 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"> @@ -419,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: xml; gutter: false; theme: Default" style="font-size:12px;"><!-- implements OAuthDataProvider --> +<pre class="brush: bash; gutter: false; theme: Confluence" 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"> @@ -437,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: xml; gutter: false; theme: Default" style="font-size:12px;"><bean id="authorizationService" class="org.apache.cxf.rs.security.oauth2.services.AuthorizationCodeGrantService"> +<pre class="brush: bash; gutter: false; theme: Confluence" style="font-size:12px;"><bean id="authorizationService" class="org.apache.cxf.rs.security.oauth2.services.AuthorizationCodeGrantService"> <property name="dataProvider" ref="oauthProvider"/> </bean> @@ -456,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: xml; gutter: false; theme: Default" style="font-size:12px;"><bean id="authorizationService" class="org.apache.cxf.rs.security.oauth2.services.AuthorizationCodeGrantService"> +<pre class="brush: bash; gutter: false; theme: Confluence" style="font-size:12px;"><bean id="authorizationService" class="org.apache.cxf.rs.security.oauth2.services.AuthorizationCodeGrantService"> <property name="dataProvider" ref="oauthProvider"/> </bean> @@ -483,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: xml; gutter: false; theme: Default" style="font-size:12px;">Address: http://localhost:8080/services/thirdPartyAccess/calendar +<pre class="brush: bash; gutter: false; theme: Confluence" style="font-size:12px;">Address: http://localhost:8080/services/thirdPartyAccess/calendar Http-Method: GET Headers: { @@ -492,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: xml; gutter: false; theme: Default" style="font-size:12px;"><bean id="oauthProvider" class="oauth.manager.OAuthManager"/> +<pre class="brush: bash; gutter: false; theme: Confluence" 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> @@ -510,7 +511,7 @@ Headers: </jaxrs:server> </pre>
[... 115 lines stripped ...]