cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
Subject svn commit: r910128 - in /websites/production/cxf/content: cache/docs.pageCache docs/jax-rs-oauth2.html
Date Tue, 27 May 2014 16:46:48 GMT
Author: buildbot
Date: Tue May 27 16:46:48 2014
New Revision: 910128

Production update by buildbot for cxf


Modified: websites/production/cxf/content/cache/docs.pageCache
Binary files - no diff available.

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 May 27 16:46:48 2014
@@ -118,11 +118,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
-div.rbtoc1400604383351 {padding: 0px;}
-div.rbtoc1400604383351 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1400604383351 li {margin-left: 0px;padding-left: 0px;}
+div.rbtoc1401209181900 {padding: 0px;}
+div.rbtoc1401209181900 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1401209181900 li {margin-left: 0px;padding-left: 0px;}
-/*]]>*/</style></p><div class="toc-macro rbtoc1400604383351">
+/*]]>*/</style></p><div class="toc-macro rbtoc1401209181900">
 <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
 <ul class="toc-indentation"><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>
@@ -153,11 +153,13 @@ div.rbtoc1400604383351 li {margin-left: 
 </div></div><h1 id="JAX-RSOAuth2-ClientRegistration">Client Registration</h1><p>Client
Registration is typically done out of band (OAuth2 experts are also finalizing the dynamic
client registration).<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"
bean for the currently supported properties. <br clear="none"> Note CXF may offer an
abstract client registration service in the future to minimize the effort to get the custom
registration service created from scratch.</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 2 services for:<br clear="none"> 1. Authorizing request
tokens by asking the en
 d 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>CXF offers several
JAX-RS service implementations that can be used to create the OAuth2 servers fast: <a shape="rect"
class="external-link" href="">AuthorizationCodeGrantService</a>
and <a shape="rect" class="external-link" href="">ImplicitGrantService</a>
for managing the redirection-based flows, as well as <a shape="rect" class="external-link"
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
shape="rect" class="external-link" href="">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="">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 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="
 services/">AuthorizationCodeGrantService</a> and
<a shape="rect" class="external-link" href="">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 pdl" style="border-width: 1px;"><div class="codeContent panelContent
 <script class="theme: Default; brush: xml; gutter: false" type="syntaxhighlighter"><![CDATA[Response-Code:
-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]}
+Headers: {Location=[http://localhost:8080/services/social/authorize?client_id=123456789&amp;scope=updateCalendar-7&amp;response_type=code

+Date=[Thu, 12 Apr 2012 12:26:21 GMT], Content-Length=[0]}
 </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">
-<script class="theme: Default; brush: xml; gutter: false" type="syntaxhighlighter"><![CDATA[Address:
+<script class="theme: Default; brush: xml; gutter: false" type="syntaxhighlighter"><![CDATA[Address:
 Http-Method: GET
 Headers: {
@@ -173,7 +175,8 @@ WARNING: Unsecure HTTP, Transport Layer 
 </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 shape="rect" class="external-link" href="">client
application</a> to populate an instance of <a shape="rect" class="external-link"
bean and return it. OAuthAuthorizationData contains application name and URI properties, optional
list of <a shape="rect" class="external-link" href="">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 OAuthAu
 thorizationData 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="">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 shape="rect" href="
 support">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 pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
 <script class="theme: Default; brush: xml; gutter: false" type="syntaxhighlighter"><![CDATA[12-Apr-2012
13:26:21 org.apache.cxf.jaxrs.provider.RequestDispatcherProvider logRedirection
-INFO: Setting an instance of &quot;;
as HttpServletRequest attribute &quot;data&quot; and redirecting the response to &quot;/forms/oauthAuthorize.jsp&quot;.
+INFO: Setting an instance of &quot;;
as HttpServletRequest 
+attribute &quot;data&quot; and redirecting the response to &quot;/forms/oauthAuthorize.jsp&quot;.
 </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">
 <script class="theme: Default; brush: xml; gutter: false" type="syntaxhighlighter"><![CDATA[Address:
@@ -187,12 +190,15 @@ Content-Type=[application/x-www-form-url
 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
+INFO: updateCalendar-7_status=allow&amp;readCalendar_status=allow&amp;scope=updateCalendar-7+readCalendar
 </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">
 <script class="theme: Default; brush: xml; gutter: false" type="syntaxhighlighter"><![CDATA[Response-Code:
 Headers: {
- Location=[http://localhost:8080/services/reservations/reserve/complete?state=1&amp;code=5c993144b910bccd5977131f7d2629ab],

+ Location=[http://localhost:8080/services/reservations/reserve/complete?state=1
  Date=[Thu, 12 Apr 2012 14:36:29 GMT], 
@@ -220,7 +226,8 @@ Content-Type=[application/x-www-form-url
 </div></div><p>This request contains a client_id and client_secret (Authorization
header), the grant_type, the grant value (code)<br clear="none"> plus the redirect URI
the authorization grant was returned to which is needed for the additional validation.<br
clear="none"> 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="">AccessTokenGrantHandler</a>
and request to create a <a shape="rect" class="external-link" href="
 ommon/">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="">AuthorizationCodeGrantHandler</a>
may delegate the creation of the actual access token to data providers, which may create Bearer
or MAC 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>Now that the token has been created, it is
mapped by the service to a <a shape="rect" class="external-link" href="
 main/java/org/apache/cxf/rs/security/oauth2/common/">client 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">
 <script class="theme: Default; brush: xml; gutter: false" type="syntaxhighlighter"><![CDATA[Response-Code:
@@ -306,7 +313,8 @@ Headers: {
-{&quot;access_token&quot;:&quot;5b5c8e677413277c4bb8b740d522b378&quot;, &quot;token_type&quot;:&quot;mac&quot;,
&quot;mac_key&quot;=&quot;1234568&quot;, &quot;mac_algorithm&quot;=&quot;hmac-sha-1&quot;}
+{&quot;access_token&quot;:&quot;5b5c8e677413277c4bb8b740d522b378&quot;, &quot;token_type&quot;:&quot;mac&quot;,
 </div></div><p>Note that 'access_token' is the MAC key identifier.</p><p><a
shape="rect" class="external-link" href="">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="">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">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">
 <script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[String
requestURI = &quot;http://localhost:8080/calendar&quot;;

View raw message