cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache CXF Documentation > JAX-RS OAuth2
Date Wed, 25 Apr 2012 17:57:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/2042/9/1/_/styles/combined.css?spaceKey=CXF20DOC&amp;forWysiwyg=true" type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/CXF20DOC/JAX-RS+OAuth2">JAX-RS OAuth2</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~mazzag">Glen Mazza</a>
    </h4>
        <div id="versionComment">
        <b>Comment:</b>
        consumer -&gt; client terminology change<br />
    </div>
        <br/>
                         <h4>Changes (33)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >h1. Introduction <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >CXF 2.6.0 provides an initial implementation of [OAuth 2.0|http://tools.ietf.org/html/draft-ietf-oauth-v2]. See also the [JAX-RS OAuth] page for <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">the</span> information about OAuth 1.0. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-changed-lines" >Authorization Code, Implicit and Client Credentials grants are currently supported with <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">the new</span> <span class="diff-added-words"style="background-color: #dfd;">other</span> grant handlers to be added later. <br></td></tr>
            <tr><td class="diff-unchanged" >Custom grant handlers can be registered. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >OAuth2 is a new protocol which offers a complex yet elegant solution toward helping <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">the</span> end users (resource owners) authorize third-party providers to access their resources. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-changed-lines" >The OAuth2 flow <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">which</span> 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&#39;s photos in order to print them and post to the user or read and possibly update a user&#39;s calendar in order to make a booking. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-changed-lines" >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 <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumer</span> <span class="diff-added-words"style="background-color: #dfd;">client</span> gets back a <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumer</span> <span class="diff-added-words"style="background-color: #dfd;">client</span> 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. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>From then on, the authorization code flow works like this: <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >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. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >Please check the [specification|http://tools.ietf.org/html/draft-ietf-oauth-v2] and the [Wikipedia <span class="diff-changed-words">article|http://en.wikipedia.org/wiki/OAuth<span class="diff-added-chars"style="background-color: #dfd;">#OAuth_</span>2<span class="diff-added-chars"style="background-color: #dfd;">.0</span>]</span> as well as other resources available on the WEB for more information you may need to know about OAuth2. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>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. <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" > <br>OAuth2 server is the core piece of the complete OAuth2-based solution. Typically it contains 2 services for: <br></td></tr>
            <tr><td class="diff-changed-lines" >1. Authorizing request tokens by asking the end users to let <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumers</span> <span class="diff-added-words"style="background-color: #dfd;">clients</span> access some of their resources and returning the <br></td></tr>
            <tr><td class="diff-changed-lines" >grants back to the <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumer</span> <span class="diff-added-words"style="background-color: #dfd;">client</span> (Authorization Service) <br></td></tr>
            <tr><td class="diff-unchanged" >2. Exchanging the token grants for access tokens (Access Token Service) <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >Note that some grants that do not require the redirection-based support, such as SAML2 one, etc, may only require an Access Token Service be operational. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >All of these services rely on the custom [OAuthDataProvider|http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/OAuthDataProvider.java] which persists the access tokens and converts the opaque scope values to the information that can be presented to the users. Additionally, [AuthorizationCodeDataProvider|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/AuthorizationCodeDataProvider.java] is an OAuthDataProvider which can keep <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">the temporarily</span> <span class="diff-added-words"style="background-color: #dfd;">temporary</span> information about the authorization code grants which needs to be removed after the tokens are requested in exchange. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>Writing your own OAuthDataProvider 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. <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >h2. Authorization Service <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >The main responsibility of OAuth2 Authorization Service is to present an end user with a form asking the user to allow or deny the <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumer</span> <span class="diff-added-words"style="background-color: #dfd;">client</span> accessing some of the user resources. CXF offers [AuthorizationCodeGrantService|http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AuthorizationCodeGrantService.java] and [ImplicitGrantService|http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/ImplicitGrantService.java] 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. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>One of the differences between the AuthorizationCode and Implicit flows is that in the latter case the grant is the actual access token which is returned as the URI fragment value. The way the end user is asked to authorize the client request is similar between the two flows. In this section we will assume that the Authorization Code flow is being exercized. <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >{code}  <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >The <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumer</span> <span class="diff-added-words"style="background-color: #dfd;">client</span> 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: <br></td></tr>
            <tr><td class="diff-unchanged" > <br>{code:xml} <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >{code} <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >Note that a &quot;/forms/oauthAuthorize.jsp&quot; 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 <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumer</span> <span class="diff-added-words"style="background-color: #dfd;">client</span> accessing some of this user&#39;s resources. If OAuthAuthorizationData has a list of Permissions set then adding the information about the permissions is needed. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-changed-lines" >Next the user makes a decision and selects a button allowing or denying the <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumer</span> <span class="diff-added-words"style="background-color: #dfd;">client</span> accessing the resources. The form data are submitted to AuthorizationCodeGrantService: <br></td></tr>
            <tr><td class="diff-unchanged" > <br>{code:xml} <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >If a user decision was set to &quot;deny&quot; then the error will be returned to the client. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >Assuming the decision was &quot;allow&quot;, the <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumer</span> <span class="diff-added-words"style="background-color: #dfd;">client</span> has now received back the authorization code grant and is ready to exchange it for a new access token. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>h2. AccessTokenService  <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >The role of AccessTokenService is to exchange a token grant for a new access token which will be used by the <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumer</span> <span class="diff-added-words"style="background-color: #dfd;">client</span> to access the end user&#39;s resources. <br></td></tr>
            <tr><td class="diff-unchanged" >Here is an example request log: <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >{code}  <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >The <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumer</span> <span class="diff-added-words"style="background-color: #dfd;">client</span> will use this access token to access the current user&#39;s resources in order to complete the original user&#39;s request, for example, the request to access a user&#39;s calendar may look like this: <br></td></tr>
            <tr><td class="diff-unchanged" >{code:xml} <br>Address: http://localhost:8080/services/thirdPartyAccess/calendar <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >The main task of OAuthDataProvider is to persist and generate access tokens. Additionally, as noted above, AuthorizationCodeDataProvider needs to persist and remove the code grant registrations. The way it&#39;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. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >Note that OAuthDataProvider supports retrieving [Client|http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/Client.java] instances but it has no methods for creating or removing Clients. The reason for it is that the process of registering third-party <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumers</span> <span class="diff-added-words"style="background-color: #dfd;">clients</span> is very specific to a particular OAuth2 application, so CXF does not offer a registration support service and hence OAuthDataProvider has no Client create/update methods. You will likely need to do something like this: <br></td></tr>
            <tr><td class="diff-unchanged" > <br>{code:java} <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >AccessTokenService listens on a relative &quot;/token&quot; path. Given that jaxrs:server/@adress is &quot;/oauth&quot; and assuming a context name is &quot;/services&quot;, the absolute address of AccessTokenService would be something like &quot;http://localhost:8080/services/oauth/token&quot;.  <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >AuthorizationCodeGrantService is better to put where the main application endpoint is. It can be put alongside AccessTokenService - but the problem is that the end user is expected to authenticate itself with the resource server after it has been redirected by a third-party <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumer</span> <span class="diff-added-words"style="background-color: #dfd;">client</span> to AuthorizationCodeGrantService. That would make it more complex for the OAuth server endpoint to manage both OAuth (third-party <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumer)</span> <span class="diff-added-words"style="background-color: #dfd;">client)</span> and the regular user authentication - that can be done, see more on it below in the Design considerations section, but the simpler option is to simply get AuthorizationCodeGrantService under the control of the security filter enforcing the end user authentication: <br></td></tr>
            <tr><td class="diff-unchanged" > <br>{code:java} <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >{code} <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >AuthorizationCodeGrantService listens on a relative &quot;/authorize&quot; path so in this case its absolute address will be something like &quot;http://localhost:8080/services/myapp/authorize&quot;. This address and that of AccessTokenService will be used by third-party <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumers.</span> <span class="diff-added-words"style="background-color: #dfd;">clients.</span> <br></td></tr>
            <tr><td class="diff-unchanged" > <br>h1. Protecting resources with OAuth filters <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >[OAuthRequestFilter|http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/filters/OAuthRequestFilter.java] 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 <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumers</span> <span class="diff-added-words"style="background-color: #dfd;">clients</span> requesting the resources. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>When checking a request like this: <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >4. Finally, it will create a CXF [SecurityContext|http://svn.apache.org/repos/asf/cxf/trunk/api/src/main/java/org/apache/cxf/security/SecurityContext.java] using this list of [OAuthPermissions|http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/data/OAuthPermission.java], the [UserSubject|http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/UserSubject.java] representing the client or the end user who authorized the grant used to obtain this token. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >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 <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumers</span> <span class="diff-added-words"style="background-color: #dfd;">clients</span> then it can become handy. More on it below. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>h1. How to get the user login name <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >One of the most important issues one need to resolve is how to partition a URI space of the resource server application. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >We have two different parties trying to access it, the end users which access the resource server to get to the resources which they own and 3rd party <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumers</span> <span class="diff-added-words"style="background-color: #dfd;">clients</span> which have been authorized by the end users to access some of their resources. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>In the former case the way the authentication is managed is completely up to the resource server application: basic authentication, two-way TLS, OpenId (more on it below), you name it. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >In the latter case an OAuth filter must enforce that the 3rd party <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumer</span> <span class="diff-added-words"style="background-color: #dfd;">client</span> has been registered using the provided <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumer</span> <span class="diff-added-words"style="background-color: #dfd;">client</span> key and that it has a valid access token which represents the end user&#39;s approval.  It&#39;s kind of the authentication and the authorization check at the same time. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>Letting both parties access the resource server via the same URI(s) complicates the life for the security filters but all the parties are only aware of the single resource server URI which all of them will use. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >Providing different access points to end users and <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumers</span> <span class="diff-added-words"style="background-color: #dfd;">clients</span> may significantly simplify the authentication process - the possible downside is that multiple access points need to be mantained by the resource server. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>Both options are discussed next. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >h3. Sharing the same access path between end users and <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumers</span> <span class="diff-added-words"style="background-color: #dfd;">clients</span> <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-changed-lines" >The first problem which needs to be addressed is how to distinguish end users from third-party <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumers</span> <span class="diff-added-words"style="background-color: #dfd;">clients</span> and get both parties authenticated as required. <br></td></tr>
            <tr><td class="diff-unchanged" >Perhaps the simplest option is to extend a CXF OAuth2 filter (JAX-RS or servlet one), check Authorization header, if it is OAuth2 then delegate to the superclass, alternatively - proceed with authenticating the end users: <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >{code} <br> <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-changed-words">Let<span class="diff-added-chars"style="background-color: #dfd;">&#39;</span>s</span> assume that the 3rd party <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumer</span> <span class="diff-added-words"style="background-color: #dfd;">client</span> has been allowed to read the public user Calendars at &quot;/calendar/\{id}&quot; only, how to make sure that the <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumer</span> <span class="diff-added-words"style="background-color: #dfd;">client</span> won&#39;t try to: <br></td></tr>
            <tr><td class="diff-unchanged" >1. update the calendar available at the same path  <br>2. read the private Calendars available at &quot;/calendar/\{id}/private&quot; <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >As noted above, [OAuthPermission|http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/OAuthPermission.java] has an optional URIs property. Thus one way to solve the problem with the private calendar is to add, say, a uri &quot;/calendar/\{id}&quot; or &quot;/calendar/1&quot; (etc) property to OAuthPermission (representing a scope like &quot;readCalendar&quot;) and the OAuth filter will make sure no subresources beyond &quot;/calendar/\{id}&quot; can be accessed. Note, adding a &quot;\*&quot; at the end of a given URI property, for example, &quot;/a*&quot; will let the <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumer to</span> <span class="diff-added-words"style="background-color: #dfd;">client</span> access &quot;/a&quot;, &quot;/a/b&quot;, etc. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>Solving the problem with preventing the update can be easily solved by adding an httpVerb property to a given OAuthPermission. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >One more option is to rely on the role-based access control and have @RolesAllowed allocated such that only users in roles like <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">&quot;consumer&quot;</span> <span class="diff-added-words"style="background-color: #dfd;">&quot;client&quot;</span> or &quot;enduser&quot; can invoke the getCalendar() method and let only those in the &quot;enduser&quot; role access getPrivateCalendar() and updateCalendar(). OAuthPermission can help here too as described in the section on using OAuth fiters. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-changed-lines" >h3. Providing different access points to end users and <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumers</span> <span class="diff-added-words"style="background-color: #dfd;">clients</span> <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-changed-lines" >Rather than letting both the end users and 3rd party <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumers</span> <span class="diff-added-words"style="background-color: #dfd;">clients</span> use the same URI such as &quot;http://myapp.com/service/calendars/\{id}&quot;, one may want to introduce two URIs, one for end users and one for third-party <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumers,</span> <span class="diff-added-words"style="background-color: #dfd;">clients,</span> for example, &quot;http://myapp.com/service/calendars/\{id}&quot; - for endusers, &quot;http://myapp.com/partners/calendars/\{id}&quot; - for the 3rd party <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumers</span> <span class="diff-added-words"style="background-color: #dfd;">clients</span> and deploy 2 jaxrs endpoints, where one is protected by the security filter checking the end users, and the one - by OAuth filters. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-changed-lines" >Additionally the endpoint managing the 3rd party <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumers</span> <span class="diff-added-words"style="background-color: #dfd;">clients</span> will deploy a resource which will offer a resticted URI space support. For example, if the application will only allow 3rd party <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumers</span> <span class="diff-added-words"style="background-color: #dfd;">clients</span> to read calendars then this resource will only have a method supporting @GET and &quot;/calendar/\{id}&quot;. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>h2. Single Sign On <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >When dealing with authenticating the end users, having an SSO solution in place is very handy. This is because the end user interacts with both the third-party and its resource server web applications and is also redirected from the <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">consumer</span> <span class="diff-added-words"style="background-color: #dfd;">client</span> application to the resource server and back again. OpenID or say a WebBrowser SSO profile can help - CXF may offer some support in this area. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>h1. What Is Next <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <p><span style="font-size:2em;font-weight:bold"> JAX-RS: OAuth2 </span></p>


<div>
<ul>
    <li><a href='#JAX-RSOAuth2-Introduction'>Introduction</a></li>
    <li><a href='#JAX-RSOAuth2-Mavendependencies'>Maven dependencies</a></li>
    <li><a href='#JAX-RSOAuth2-DevelopingOAuth2Servers'>Developing OAuth2 Servers</a></li>
<ul>
    <li><a href='#JAX-RSOAuth2-AuthorizationService'>Authorization Service</a></li>
    <li><a href='#JAX-RSOAuth2-AccessTokenService'>AccessTokenService</a></li>
    <li><a href='#JAX-RSOAuth2-WritingOAuthDataProvider'>Writing OAuthDataProvider</a></li>
    <li><a href='#JAX-RSOAuth2-OAuthServerJAXRSendpoints'>OAuth Server JAX-RS endpoints</a></li>
</ul>
    <li><a href='#JAX-RSOAuth2-ProtectingresourceswithOAuthfilters'>Protecting resources with OAuth filters</a></li>
    <li><a href='#JAX-RSOAuth2-Howtogettheuserloginname'>How to get the user login name</a></li>
    <li><a href='#JAX-RSOAuth2-Clientsidesupport'>Client-side support</a></li>
    <li><a href='#JAX-RSOAuth2-OAuth2withouttheExplicitAuthorization'>OAuth2 without the Explicit Authorization</a></li>
    <li><a href='#JAX-RSOAuth2-OAuthWithoutaBrowser'>OAuth Without a Browser</a></li>
    <li><a href='#JAX-RSOAuth2-Designconsiderations'>Design considerations</a></li>
<ul>
    <li><a href='#JAX-RSOAuth2-ControllingtheAccesstoResourceServer'>Controlling the Access to Resource Server</a></li>
<ul>
    <li><a href='#JAX-RSOAuth2-Sharingthesameaccesspathbetweenendusersandclients'>Sharing the same access path between end users and clients</a></li>
    <li><a href='#JAX-RSOAuth2-Providingdifferentaccesspointstoendusersandclients'>Providing different access points to end users and clients</a></li>
</ul>
    <li><a href='#JAX-RSOAuth2-SingleSignOn'>Single Sign On</a></li>
</ul>
    <li><a href='#JAX-RSOAuth2-WhatIsNext'>What Is Next</a></li>
</ul></div>

<h1><a name="JAX-RSOAuth2-Introduction"></a>Introduction</h1>

<p>CXF 2.6.0 provides an initial implementation of <a href="http://tools.ietf.org/html/draft-ietf-oauth-v2" class="external-link" rel="nofollow">OAuth 2.0</a>. See also the <a href="/confluence/display/CXF20DOC/JAX-RS+OAuth" title="JAX-RS OAuth">JAX&#45;RS OAuth</a> page for information about OAuth 1.0.</p>

<p>Authorization Code, Implicit and Client Credentials grants are currently supported with other grant handlers to be added later.<br/>
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 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/>
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 href="http://tools.ietf.org/html/draft-ietf-oauth-v2" class="external-link" rel="nofollow">specification</a> and the <a href="http://en.wikipedia.org/wiki/OAuth#OAuth_2.0" class="external-link" rel="nofollow">Wikipedia article</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><a name="JAX-RSOAuth2-Mavendependencies"></a>Maven dependencies</h1>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;dependency&gt;</span>
  <span class="code-tag">&lt;groupId&gt;</span>org.apache.cxf<span class="code-tag">&lt;/groupId&gt;</span>
  <span class="code-tag">&lt;artifactId&gt;</span>cxf-rt-rs-security-oauth2<span class="code-tag">&lt;/artifactId&gt;</span>
  <span class="code-tag">&lt;version&gt;</span>2.6.0<span class="code-tag">&lt;/version&gt;</span>
<span class="code-tag">&lt;/dependency&gt;</span>
</pre>
</div></div>

<h1><a name="JAX-RSOAuth2-DevelopingOAuth2Servers"></a>Developing OAuth2 Servers</h1>

<p>OAuth2 server is the core piece of the complete OAuth2-based solution. Typically it contains 2 services for:<br/>
1. Authorizing request tokens by asking the end users to let clients access some of their resources and returning the<br/>
  grants back to the client (Authorization Service)<br/>
2. Exchanging the token grants for access tokens (Access Token Service)</p>

<p>CXF offers several JAX-RS service implementations that can be used to create the OAuth2 servers fast: <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AuthorizationCodeGrantService.java" class="external-link" rel="nofollow">AuthorizationCodeGrantService</a> and <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/ImplicitGrantService.java" class="external-link" rel="nofollow">ImplicitGrantService</a> for managing the redirection-based flows, as well as <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AccessTokenService.java" class="external-link" rel="nofollow">AccessTokenService</a> for exchanging the grants for new tokens.</p>

<p>Note that some grants that do not require the redirection-based support, such as SAML2 one, etc, may only require an Access Token Service be operational.</p>

<p>All of these services rely on the custom <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/OAuthDataProvider.java" class="external-link" 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 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/AuthorizationCodeDataProvider.java" class="external-link" rel="nofollow">AuthorizationCodeDataProvider</a> is an OAuthDataProvider which can keep temporary information about the authorization code grants which needs to be removed after the tokens are requested in exchange.</p>

<p>Writing your own OAuthDataProvider 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>

<h2><a name="JAX-RSOAuth2-AuthorizationService"></a>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 href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AuthorizationCodeGrantService.java" class="external-link" rel="nofollow">AuthorizationCodeGrantService</a> and <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/ImplicitGrantService.java" class="external-link" 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 the AuthorizationCode and Implicit flows is that in the latter case the grant is the actual access token which is returned as the URI fragment value. The way the end user is asked to authorize the client request is similar between the two flows. In this section we will assume that the Authorization Code flow is being exercized.</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" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
Response-Code: 303
Headers: {Location=[http://localhost:8080/services/social/authorize?client_id=123456789&amp;scope=updateCalendar-7&amp;response_type=code&amp;redirect_uri=http%3A//localhost%3A8080/services/reservations/reserve/complete&amp;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" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
Address: http://localhost:8080/services/social/authorize?client_id=123456789&amp;scope=updateCalendar-7&amp;response_type=code&amp;redirect_uri=http%3A//localhost%3A8080/services/reservations/reserve/complete&amp;state=1
Http-Method: GET
Headers: {
Accept=[text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8],
Authorization=[Basic YmFycnlAc29jaWFsLmNvbToxMjM0], 
Cookie=[JSESSIONID=suj2wyl54c4g], 
Referer=[http://localhost:8080/services/forms/reservation.jsp]
...
}
</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" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
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 un-secure HTTP transport.</p>

<p>AuthorizationCodeGrantService will retrieve the information about the <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/Client.java" class="external-link" rel="nofollow">client application</a> to populate an instance of <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/OAuthAuthorizationData.java" class="external-link" rel="nofollow">OAuthAuthorizationData</a> bean and return it. OAuthAuthorizationData contains application name and URI properties, optional list of <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/Permission.java" class="external-link" rel="nofollow">Permission</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. The other properties which are meant to be hidden are clientId, state, redirectUri, proposedScope.</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 href="http://cxf.apache.org/docs/jax-rs-redirection.html#JAX-RSRedirection-WithRequestDispatcherProvider" class="external-link" rel="nofollow">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. Alternatively, registering <a href="http://cxf.apache.org/docs/jax-rs-advanced-xml.html#JAX-RSAdvancedXML-XSLTsupport" class="external-link" rel="nofollow">XSLTJaxbProvider</a> would also be a good option for creating HTML views.  </p>

<p>Assuming RequestDispatcherProvider is used, the following example log shows the initial response from AuthorizationCodeGrantService:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
12-Apr-2012 13:26:21 org.apache.cxf.jaxrs.provider.RequestDispatcherProvider logRedirection
INFO: Setting an instance of <span class="code-quote">"org.apache.cxf.rs.security.oauth2.common.OAuthAuthorizationData"</span> as HttpServletRequest attribute <span class="code-quote">"data"</span> and redirecting the response to <span class="code-quote">"/forms/oauthAuthorize.jsp"</span>.
</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" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
Address: http://localhost:8080/services/social/authorize/decision
Encoding: ISO-8859-1
Http-Method: POST
Content-Type: application/x-www-form-urlencoded
Headers: {
Authorization=[Basic YmFycnlAc29jaWFsLmNvbToxMjM0],
Content-Type=[application/x-www-form-urlencoded],
...
}
--------------------------------------
12-Apr-2012 15:36:29 org.apache.cxf.jaxrs.utils.FormUtils logRequestParametersIfNeeded
INFO: updateCalendar-7_status=allow&amp;readCalendar_status=allow&amp;scope=updateCalendar-7+readCalendar&amp;redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fservices%2Freservations%2Freserve%2Fcomplete&amp;session_authenticity_token=4f0005d9-565f-4309-8ffb-c13c72139ebe&amp;oauthDecision=allow&amp;state=1&amp;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" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
Response-Code: 303
Headers: {
 Location=[http://localhost:8080/services/reservations/reserve/complete?state=1&amp;code=5c993144b910bccd5977131f7d2629ab], 
 Date=[Thu, 12 Apr 2012 14:36:29 GMT], 
 Content-Length=[0]}
</pre>
</div></div>  

<p>which leads to a browser redirecting the user:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
Address: http:<span class="code-comment">//localhost:8080/services/reservations/reserve/complete?state=1&amp;code=5c993144b910bccd5977131f7d2629ab
</span>Http-Method: GET
Headers: {
Accept=[text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8],
Authorization=[Basic YmFycnlAcmVzdGF1cmFudC5jb206NTY3OA==], 
Cookie=[JSESSIONID=1c289vha0cxfe],
}
</pre>
</div></div>

<p>If a user decision was set to "deny" then the error will be returned to the client.</p>

<p>Assuming the decision was "allow", the client has now received back the authorization code grant and is ready to exchange it for a new access token.</p>

<h2><a name="JAX-RSOAuth2-AccessTokenService"></a>AccessTokenService </h2>

<p>The role of AccessTokenService is to exchange a token grant for a new access token which will be used by the client to access the end user's resources. <br/>
Here is an example request log:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
Address: http://localhost:8080/services/oauth/token
Http-Method: POST

Headers: {
Accept=[application/json], 
Authorization=[Basic MTIzNDU2Nzg5Ojk4NzY1NDMyMQ==], 
Content-Type=[application/x-www-form-urlencoded]
}
Payload: 

grant_type=authorization_code&amp;code=5c993144b910bccd5977131f7d2629ab&amp;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)<br/>
plus the redirect URI the authorization grant was returned to which is needed for the additional validation.<br/>
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 href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AccessTokenGrantHandler.java" class="external-link" rel="nofollow">AccessTokenGrantHandler</a> and request to create a <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/ServerAccessToken.java" class="external-link" rel="nofollow">ServerAccessToken</a> which is a server-side representation of the access token.<br/>
The grant handlers, such as <a 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/AuthorizationCodeGrantHandler.java" class="external-link" rel="nofollow">AuthorizationCodeGrantHandler</a> may delegate the creation of the actual access token to data providers, which may use the available utility classes such as <a 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/bearer/BearerAccessToken.java" class="external-link" rel="nofollow">BearerAccessToken</a> shipped with CXF or depend on other 3rd party libraries to create the tokens.</p>

<p>The data providers are also do not strictly required to persist the data such as access tokens, instead the token key may an encrypted bag capturing all the relevant information.</p>

<p>Now that the token has been created, it is mapped by the service to a <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/ClientAccessToken.java" class="external-link" rel="nofollow">client representation</a> and is returned back as a JSON payload:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
Response-Code: 200
Content-Type: application/json
Headers: {
 Cache-Control=[no-store], 
 Pragma=[no-cache], 
 Date=[Thu, 12 Apr 2012 14:36:29 GMT]
}

Payload: 

{<span class="code-quote">"access_token"</span>:<span class="code-quote">"5b5c8e677413277c4bb8b740d522b378"</span>, <span class="code-quote">"token_type"</span>:<span class="code-quote">"bearer"</span>}

</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" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
Address: http://localhost:8080/services/thirdPartyAccess/calendar
Http-Method: GET
Headers: 
{
  Authorization=[Bearer 5b5c8e677413277c4bb8b740d522b378], 
  Accept=[application/xml]
}
</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>

<h2><a name="JAX-RSOAuth2-WritingOAuthDataProvider"></a>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 href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/OAuthDataProvider.java" class="external-link" rel="nofollow">OAuthDataProvider</a> implementation.</p>

<p>The main task of OAuthDataProvider is to persist and generate access tokens. Additionally, as noted above, AuthorizationCodeDataProvider 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>Note that OAuthDataProvider supports retrieving <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/Client.java" class="external-link" rel="nofollow">Client</a> instances but it has no methods for creating or removing Clients. The reason for it is that the process of registering third-party clients is very specific to a particular OAuth2 application, so CXF does not offer a registration support service and hence OAuthDataProvider has no Client create/update methods. You will likely need to do something like this:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class CustomOAuthProvider <span class="code-keyword">implements</span> OAuthDataProvider {
   <span class="code-keyword">public</span> Client registerClient(<span class="code-object">String</span> applicationName, <span class="code-object">String</span> applicationURI, ...) {}
   <span class="code-keyword">public</span> void removeClient(<span class="code-object">String</span> cliendId) {}
   <span class="code-comment">// etc
</span>   <span class="code-comment">// OAuthDataProvider methods
</span>}
</pre>
</div></div>

<p>CustomOAuthProvider will also remove all tokens associated with a given Client in removeClient(String cliendId).</p>


<p>Finally OAuthDataProvider may need to convert opaque scope values such as "readCalendar" into a list of <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/OAuthPermission.java" class="external-link" rel="nofollow">OAuthPermission</a>s. AuthorizationCodeGrantService and OAuth2 security filters will depend on it (assuming scopes are used in the first place). In the former case AuthorizationCodeGrantService will use this list to populate <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/OAuthAuthorizationData.java" class="external-link" rel="nofollow">OAuthAuthorizationData</a> - the reason this bean only sees <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/Permission.java" class="external-link" rel="nofollow">Permission</a>s is that some of the properties OAuthPermission keeps are of no interest to OAuthAuthorizationData handlers.</p>

<h2><a name="JAX-RSOAuth2-OAuthServerJAXRSendpoints"></a>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/>
Most likely, you'd want to deploy AccessTokenService as an independent JAX-RS endpoint, for example:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag"><span class="code-comment">&lt;!-- implements OAuthDataProvider --&gt;</span></span>
<span class="code-tag">&lt;bean id=<span class="code-quote">"oauthProvider"</span> class=<span class="code-quote">"oauth.manager.OAuthManager"</span>/&gt;</span>
     
<span class="code-tag">&lt;bean id=<span class="code-quote">"accessTokenService"</span> class=<span class="code-quote">"org.apache.cxf.rs.security.oauth2.services.AccessTokenService"</span>&gt;</span>
  <span class="code-tag">&lt;property name=<span class="code-quote">"dataProvider"</span> ref=<span class="code-quote">"oauthProvider"</span>/&gt;</span>
<span class="code-tag">&lt;/bean&gt;</span>

<span class="code-tag">&lt;jaxrs:server id=<span class="code-quote">"oauthServer"</span> address=<span class="code-quote">"/oauth"</span>&gt;</span>
   <span class="code-tag">&lt;jaxrs:serviceBeans&gt;</span>
      <span class="code-tag">&lt;ref bean=<span class="code-quote">"accessTokenService"</span>/&gt;</span>
  <span class="code-tag">&lt;/jaxrs:serviceBeans&gt;</span>
<span class="code-tag">&lt;/jaxrs:server&gt;</span>
</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>AuthorizationCodeGrantService is better to put where the main application endpoint is. It can be put alongside AccessTokenService - but the problem is that the end user is expected to authenticate itself with the resource server after it has been redirected by a third-party client to AuthorizationCodeGrantService. That would make it more complex for the OAuth server endpoint to manage both OAuth (third-party client) and the regular user authentication - that can be done, see more on it below in the Design considerations section, but the simpler option is to simply get AuthorizationCodeGrantService under the control of the security filter enforcing the end user authentication:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
&lt;bean id=<span class="code-quote">"authorizationService"</span> class=<span class="code-quote">"org.apache.cxf.rs.security.oauth2.services.AuthorizationCodeGrantService"</span>&gt;
  &lt;property name=<span class="code-quote">"dataProvider"</span> ref=<span class="code-quote">"oauthProvider"</span>/&gt;
&lt;/bean&gt;

&lt;bean id=<span class="code-quote">"myApp"</span> class=<span class="code-quote">"org.myapp.MyApp"</span>&gt;
  &lt;property name=<span class="code-quote">"dataProvider"</span> ref=<span class="code-quote">"oauthProvider"</span>/&gt;
&lt;/bean&gt;

&lt;jaxrs:server id=<span class="code-quote">"oauthServer"</span> address=<span class="code-quote">"/myapp"</span>&gt;
   &lt;jaxrs:serviceBeans&gt;
      &lt;ref bean=<span class="code-quote">"myApp"</span>/&gt;
      &lt;ref bean=<span class="code-quote">"authorizationService"</span>/&gt;
  &lt;/jaxrs:serviceBeans&gt;
&lt;/jaxrs:server&gt;
</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>

<h1><a name="JAX-RSOAuth2-ProtectingresourceswithOAuthfilters"></a>Protecting resources with OAuth filters</h1>

<p><a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/filters/OAuthRequestFilter.java" class="external-link" 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" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
Address: http://localhost:8080/services/thirdPartyAccess/calendar
Http-Method: GET
Headers: 
{
  Authorization=[Bearer 5b5c8e677413277c4bb8b740d522b378], 
  Accept=[application/xml]
}
</pre>
</div></div> 

<p>the filter will do the following:</p>

<p>1. Retrieve a ServerAccessToken by delegating to a matching registered <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AccessTokenValidator.java" class="external-link" 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 href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security2/oauth/data/OAuthPermission.java" class="external-link" rel="nofollow">OAuthPermissions</a>. For every permission it will:</p>
<ul class="alternate" type="square">
	<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>4. Finally, it will create a CXF <a href="http://svn.apache.org/repos/asf/cxf/trunk/api/src/main/java/org/apache/cxf/security/SecurityContext.java" class="external-link" rel="nofollow">SecurityContext</a> using this list of <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/data/OAuthPermission.java" class="external-link" rel="nofollow">OAuthPermissions</a>, the <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/UserSubject.java" class="external-link" 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>

<h1><a name="JAX-RSOAuth2-Howtogettheuserloginname"></a>How to get the user login name</h1>

<p>When one writes a custom server application which needs to participate in OAuth2 flows, the major question which needs to be addressed is<br/>
how one can access a user login name that was used during the end-user authorizing the third-party client. This username will help to uniquely identify the resources that the 3rd party client is now attempting to access. The following code shows one way of how this can be done:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java"> 
@Path(<span class="code-quote">"/userResource"</span>)
<span class="code-keyword">public</span> class ThirdPartyAccessService {

    @Context 
    <span class="code-keyword">private</span> MessageContext mc;
	
    @GET
    <span class="code-keyword">public</span> UserResource getUserResource() {
        OAuthContext oauth = mc.getContent(OAuthContext.class);
        <span class="code-keyword">if</span> (oauth == <span class="code-keyword">null</span> || oauth.getSubject() == <span class="code-keyword">null</span> || oauth.getSubject().getLogin() == <span class="code-keyword">null</span>) {
	   <span class="code-keyword">throw</span> <span class="code-keyword">new</span> WebApplicationException(403);
	}
	<span class="code-object">String</span> userName = oauth.getSubject().getLogin();
	<span class="code-keyword">return</span> findUserResource(userName)
    }

    <span class="code-keyword">private</span> UserResource findUserResource(<span class="code-object">String</span> userName) {
        <span class="code-comment">// find and <span class="code-keyword">return</span> UserResource
</span>    }
}

</pre>
</div></div>

<p>The above shows a fragment of the JAX-RS service managing the access to user resources from authorized 3rd-party clients (see the Design Considerations section for more information).</p>

<p>The injected MessageContext provides an access to <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/OAuthContext.java" class="external-link" rel="nofollow">OAuthContext</a> which has been set by OAuth2 filters described in the previous section. OAuthContext will act as a container of the information which can be useful to the custom application code which do not need to deal with the OAuth2 internals.</p>

<h1><a name="JAX-RSOAuth2-Clientsidesupport"></a>Client-side support</h1>

<p>When developing a third party application which needs to participate in OAuth2 flows one has to write the code that will redirect users to OAuth2 AuthorizationCodeGrantService, interact with AccessTokenService in order to exchange code grants for access tokens as well as correctly build Authorization OAuth2 headers when accessing the end users' resources. JAX-RS makes it straightforward to support the redirection, while <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/OAuthClientUtils.java" class="external-link" rel="nofollow">OAuthClientUtils</a> class makes it possible to encapsulate most of the complexity away from the client application code.   </p>

<p>For example, the following custom code can be used by the third-party application:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class OAuthClientManager {
	
	<span class="code-keyword">private</span> WebClient accessTokenService;
        <span class="code-keyword">private</span> <span class="code-object">String</span> authorizationServiceURI;
        <span class="code-keyword">private</span> Consumer consumer;

        <span class="code-comment">// inject properties, register the client application...
</span>
	<span class="code-keyword">public</span> URI getAuthorizationServiceURI(ReservationRequest request,
			                              URI redirectUri,
			                              /* state */<span class="code-object">String</span> reservationRequestKey) {
	    <span class="code-object">String</span> scope = OAuthConstants.UPDATE_CALENDAR_SCOPE + request.getHour();
	    <span class="code-keyword">return</span> OAuthClientUtils.getAuthorizationURI(authorizationServiceURI, 
	    		                                consumer.getKey(),
	    		                                redirectUri.toString(),
	    		                                reservationRequestKey,
	    		                                scope);
	}
	<span class="code-keyword">public</span> ClientAccessToken getAccessToken(AuthorizationCodeGrant codeGrant) {
	    <span class="code-keyword">try</span> {
	        <span class="code-keyword">return</span> OAuthClientUtils.getAccessToken(accessTokenService, consumer, codeGrant);
	    } <span class="code-keyword">catch</span> (OAuthServiceException ex) {
	        <span class="code-keyword">return</span> <span class="code-keyword">null</span>;
	    }
	}
	
	<span class="code-keyword">public</span> <span class="code-object">String</span> createAuthorizationHeader(ClientAccessToken token) {
		<span class="code-keyword">return</span> OAuthClientUtils.createAuthorizationHeader(consumer, token);
	}
}
</pre>
</div></div>    

<p>The reason such a simple wrapper can be introduced is to minimize the exposure to OAuth2 of the main application code to the bare minimum, this is why<br/>
in this example OAuthServiceExceptions are caught, presumably logged and null values are returned which will indicate to the main code that the request failed. Obviously, OAuthClientUtils can be used directly as well.</p>

<h1><a name="JAX-RSOAuth2-OAuth2withouttheExplicitAuthorization"></a>OAuth2 without the Explicit Authorization</h1>

<p>Client Credentials is one of OAuth2 grants that does not require the explicit authorization and is currently supported by CXF.  </p>

<h1><a name="JAX-RSOAuth2-OAuthWithoutaBrowser"></a>OAuth Without a Browser</h1>

<p>When an end user is accessing the 3rd party application and is authorizing it later on, it's usually expected that the user is relying on a browser. <br/>
However, supporting other types of end users is easy enough. Writing the client code that processes the redirection requests from the 3rd party application and AuthorizationRequestService is simple with JAX-RS and additionally CXF can be configured to do auto-redirects on the client side.</p>

<p>Also note that AuthorizationRequestService can return XML or JSON <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth/src/main/java/org/apache/cxf/rs/security/oauth/data/OAuthAuthorizationData.java" class="external-link" rel="nofollow">OAuthAuthorizationData</a> representations. That makes it easy for a client code to get OAuthAuthorizationData and offer a pop-up window or get the input from the command-line. Authorizing the third-party application might even be automated in this case - which can lead to a complete 3-leg OAuth flow implemented without a human user being involved.</p>

<h1><a name="JAX-RSOAuth2-Designconsiderations"></a>Design considerations</h1>

<p>This section will talk about various design considerations one need to take into account when deploying OAuth-based solutions.</p>

<h2><a name="JAX-RSOAuth2-ControllingtheAccesstoResourceServer"></a>Controlling the Access to Resource Server</h2>

<p>One of the most important issues one need to resolve is how to partition a URI space of the resource server application.</p>

<p>We have two different parties trying to access it, the end users which access the resource server to get to the resources which they own and 3rd party clients which have been authorized by the end users to access some of their resources. </p>

<p>In the former case the way the authentication is managed is completely up to the resource server application: basic authentication, two-way TLS, OpenId (more on it below), you name it.</p>

<p>In the latter case an OAuth filter must enforce that the 3rd party client has been registered using the provided client key and that it has a valid access token which represents the end user's approval.  It's kind of the authentication and the authorization check at the same time.</p>

<p>Letting both parties access the resource server via the same URI(s) complicates the life for the security filters but all the parties are only aware of the single resource server URI which all of them will use.</p>

<p>Providing different access points to end users and clients may significantly simplify the authentication process - the possible downside is that multiple access points need to be mantained by the resource server.</p>

<p>Both options are discussed next.</p>

<h3><a name="JAX-RSOAuth2-Sharingthesameaccesspathbetweenendusersandclients"></a>Sharing the same access path between end users and clients</h3>

<p>The first problem which needs to be addressed is how to distinguish end users from third-party clients and get both parties authenticated as required.<br/>
Perhaps the simplest option is to extend a CXF OAuth2 filter (JAX-RS or servlet one), check Authorization header, if it is OAuth2 then delegate to the superclass, alternatively - proceed with authenticating the end users:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class SecurityFilter <span class="code-keyword">extends</span> org.apache.cxf.rs.security.oauth2.filters.OAuthRequestFilter {
   @Context
   <span class="code-keyword">private</span> HttpHeaders headers;

   <span class="code-keyword">public</span> Response handleRequest(ClassResourceInfo cri, Message message) {
       <span class="code-object">String</span> header = headers.getRequestHeaders().getFirst(<span class="code-quote">"Authorization"</span>);
       <span class="code-keyword">if</span> (header.startsWith(<span class="code-quote">"Bearer "</span>)) {
           <span class="code-keyword">return</span> <span class="code-keyword">super</span>.handleRequest(cri, message);
       } <span class="code-keyword">else</span> {
           <span class="code-comment">// authenticate the end user
</span>       }
   }

} 
</pre>
</div></div>   

<p>The next issue is how to enforce that the end users can only access the resources they've been authorized to access.<br/>
For example, consider the following JAX-RS resource class:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@Path(<span class="code-quote">"calendar"</span>)
<span class="code-keyword">public</span> class CalendarResource {

   @GET
   @Path(<span class="code-quote">"{id}"</span>)
   <span class="code-keyword">public</span> Calendar getPublicCalendar(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">long</span> id) {
       <span class="code-comment">// <span class="code-keyword">return</span> the calendar <span class="code-keyword">for</span> a user identified by 'id'
</span>   }

   @GET
   @Path(<span class="code-quote">"{id}/<span class="code-keyword">private</span>"</span>)
   <span class="code-keyword">public</span> Calendar getPrivateCalendar(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">long</span> id) {
       <span class="code-comment">// <span class="code-keyword">return</span> the calendar <span class="code-keyword">for</span> a user identified by 'id'
</span>   }

   @PUT
   @Path(<span class="code-quote">"{id}"</span>)
   <span class="code-keyword">public</span> void updateCalendar(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">long</span> id, Calendar c) {
       <span class="code-comment">// update the calendar <span class="code-keyword">for</span> a user identified by 'id'
</span>   }
}
</pre>
</div></div>

<p>Let's assume that the 3rd party client has been allowed to read the public user Calendars at "/calendar/{id}" only, how to make sure that the client won't try to:<br/>
1. update the calendar available at the same path <br/>
2. read the private Calendars available at "/calendar/{id}/private"</p>

<p>As noted above, <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/OAuthPermission.java" class="external-link" rel="nofollow">OAuthPermission</a> has an optional URIs property. Thus one way to solve the problem with the private calendar is to add, say, a uri "/calendar/{id}" or "/calendar/1" (etc) property to OAuthPermission (representing a scope like "readCalendar") and the OAuth filter will make sure no subresources beyond "/calendar/{id}" can be accessed. Note, adding a "&#42;" at the end of a given URI property, for example, "/a*" will let the client access "/a", "/a/b", etc.</p>

<p>Solving the problem with preventing the update can be easily solved by adding an httpVerb property to a given OAuthPermission.</p>

<p>One more option is to rely on the role-based access control and have @RolesAllowed allocated such that only users in roles like "client" or "enduser" can invoke the getCalendar() method and let only those in the "enduser" role access getPrivateCalendar() and updateCalendar(). OAuthPermission can help here too as described in the section on using OAuth fiters.</p>

<h3><a name="JAX-RSOAuth2-Providingdifferentaccesspointstoendusersandclients"></a>Providing different access points to end users and clients</h3>

<p>Rather than letting both the end users and 3rd party clients use the same URI such as "http://myapp.com/service/calendars/{id}", one may want to introduce two URIs, one for end users and one for third-party clients, for example, "http://myapp.com/service/calendars/{id}" - for endusers, "http://myapp.com/partners/calendars/{id}" - for the 3rd party clients and deploy 2 jaxrs endpoints, where one is protected by the security filter checking the end users, and the one - by OAuth filters. </p>

<p>Additionally the endpoint managing the 3rd party clients will deploy a resource which will offer a resticted URI space support. For example, if the application will only allow 3rd party clients to read calendars then this resource will only have a method supporting @GET and "/calendar/{id}". </p>

<h2><a name="JAX-RSOAuth2-SingleSignOn"></a>Single Sign On</h2>

<p>When dealing with authenticating the end users, having an SSO solution in place is very handy. This is because the end user interacts with both the third-party and its resource server web applications and is also redirected from the client application to the resource server and back again. OpenID or say a WebBrowser SSO profile can help - CXF may offer some support in this area. </p>

<h1><a name="JAX-RSOAuth2-WhatIsNext"></a>What Is Next</h1>

<p>Fine tuning the current OAuth 2.0 implementation will be continued and the feedback from the implementers will be welcomed.<br/>
OAuth 2.0 grants based on SAML2 or JWT assertions, OAuth 2.0 extensions - are all of interest to CXF.</p>

    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action" class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/CXF20DOC/JAX-RS+OAuth2">View Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=27843869&revisedVersion=6&originalVersion=5">View Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/CXF20DOC/JAX-RS+OAuth2?showComments=true&amp;showCommentArea=true#addcomment">Add Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message