Author: buildbot
Date: Fri Jun 5 10:47:01 2015
New Revision: 953895
Log:
Production update by buildbot for cxf
Modified:
websites/production/cxf/content/cache/docs.pageCache
websites/production/cxf/content/docs/jax-rs-oauth2.html
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 Fri Jun 5 10:47:01
2015
@@ -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 type="text/css">/*<![CDATA[*/
-div.rbtoc1430923637640 {padding: 0px;}
-div.rbtoc1430923637640 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1430923637640 li {margin-left: 0px;padding-left: 0px;}
+div.rbtoc1433501218341 {padding: 0px;}
+div.rbtoc1433501218341 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1433501218341 li {margin-left: 0px;padding-left: 0px;}
-/*]]>*/</style></p><div class="toc-macro rbtoc1430923637640">
+/*]]>*/</style></p><div class="toc-macro rbtoc1433501218341">
<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSOAuth2-JAX-RS:OAuth2">JAX-RS: OAuth2</a></li><li><a shape="rect"
href="#JAX-RSOAuth2-Introduction">Introduction</a></li><li><a shape="rect"
href="#JAX-RSOAuth2-Mavendependencies">Maven dependencies</a></li><li><a
shape="rect" href="#JAX-RSOAuth2-ClientRegistration">Client
Registration</a></li><li><a shape="rect"
href="#JAX-RSOAuth2-DevelopingOAuth2Servers">Developing OAuth2 Servers</a>
<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSOAuth2-AuthorizationService">Authorization Service</a>
<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSOAuth2-HowtocreateAuthorizationView">How to create Authorization
View</a></li><li><a shape="rect"
href="#JAX-RSOAuth2-EndUserNameinAuthorizationForm">EndUser Name in
Authorization Form</a></li><li><a shape="rect"
href="#JAX-RSOAuth2-PublicClients(Devices)">Public Clients (Devices)</a>
@@ -144,7 +144,7 @@ div.rbtoc1430923637640 li {margin-left:
</li><li><a shape="rect"
href="#JAX-RSOAuth2-CustomizingEndUserSubjectinitialization">Customizing End
User Subject initialization</a></li><li><a shape="rect"
href="#JAX-RSOAuth2-ProtectingresourceswithOAuthfilters">Protecting resources
with OAuth filters</a>
<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSOAuth2-OAuth2tokensandSOAPendpoints">OAuth2 tokens and SOAP
endpoints</a></li></ul>
</li><li><a shape="rect" href="#JAX-RSOAuth2-Howtogettheuserloginname">How to
get the user login name</a></li><li><a shape="rect"
href="#JAX-RSOAuth2-Client-sidesupport">Client-side support</a>
-<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSOAuth2-OAuth2clientfilters">OAuth2 client filters</a></li></ul>
+<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSOAuth2-AdvancedOAuth2clientapplications">Advanced OAuth2 client
applications</a></li><li><a shape="rect"
href="#JAX-RSOAuth2-OAuth2clientapplicationswithcode-grantfilters">OAuth2
client applications with code-grant filters</a></li><li><a shape="rect"
href="#JAX-RSOAuth2-OAuth2clientauthenticatorsfornon-dynamicclients">OAuth2
client authenticators for non-dynamic clients</a></li></ul>
</li><li><a shape="rect"
href="#JAX-RSOAuth2-OAuth2withouttheExplicitAuthorization">OAuth2 without the
Explicit Authorization</a></li><li><a shape="rect"
href="#JAX-RSOAuth2-OAuthWithoutaBrowser">OAuth Without a
Browser</a></li><li><a shape="rect"
href="#JAX-RSOAuth2-Reportingerrordetails">Reporting error
details</a></li><li><a shape="rect" href="#JAX-RSOAuth2-OAuth2andJOSE">OAuth2
and JOSE</a></li><li><a shape="rect" href="#JAX-RSOAuth2-OAuth2andOIDC">OAuth2
and OIDC</a></li><li><a shape="rect"
href="#JAX-RSOAuth2-Designconsiderations">Design considerations</a>
<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSOAuth2-ControllingtheAccesstoResourceServer">Controlling the
Access to Resource Server</a>
<ul class="toc-indentation"><li><a shape="rect"
href="#JAX-RSOAuth2-Sharingthesameaccesspathbetweenendusersandclients">Sharing
the same access path between end users and clients</a></li><li><a shape="rect"
href="#JAX-RSOAuth2-Providingdifferentaccesspointstoendusersandclients">Providing
different access points to end users and clients</a></li></ul>
@@ -515,7 +515,7 @@ public class ThirdPartyAccessService {
}
}
]]></script>
-</div></div><p>org.apache.cxf.rs.security.oauth2.provider.OAuthContextProvider
will have to be registered as jaxrs:provider for it to work.</p><h1
id="JAX-RSOAuth2-Client-sidesupport">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 shape="rect"
class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/OAuthClientUtils.java">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 c
ode can be used by the third-party application:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+</div></div><p>org.apache.cxf.rs.security.oauth2.provider.OAuthContextProvider
will have to be registered as jaxrs:provider for it to work.</p><h1
id="JAX-RSOAuth2-Client-sidesupport">Client-side support</h1><p>When developing
a third party application which needs to participate in OAuth2 flows one has to
deal with redirecting users to OAuth2 AuthorizationCodeGrantService,
interacting with AccessTokenService in order to exchange code grants for access
tokens as well as correctly building Authorization OAuth2 headers when
accessing the end users' resources.</p><h2
id="JAX-RSOAuth2-AdvancedOAuth2clientapplications">Advanced OAuth2 client
applications</h2><p>In a number of cases an OAuth2 client application
supporting the code flow needs to have an OAuth2-specific code written
directly. Such clients qualify as advanced given that writing such a code
requires thel understanding of OAuth2 specifics. That said,</p><p>JAX-RS makes
it straightforward to support the redirection, while <a sha
pe="rect" class="external-link"
href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/OAuthClientUtils.java">OAuthClientUtils</a>
class makes it possible to encapsulate most of the complexity away from the
client application code, so ultimately the code required to support is
typically not that complex at all, while at the same it offers the most
flexibility.</p><p>For example, the following custom code can be used by the
third-party application:</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[public class OAuthClientManager {
private WebClient accessTokenService;
@@ -595,7 +595,103 @@ try {
]]></script>
-</div></div><p>The client code directly dealing with OAuth2 specifics can be
the most flelxible option: the client which has both access and refresh tokens
can check the current access token expiry time and if it is known to have
expiried then it can proactively</p><p>refresh the tokens, avoiding doing a
futile HTTP request that is bound to return 401. Or/and indeed it can take care
of JAX-RS NotAuthorizedException (401) and refresh the tokens. Sophisticated
clients might want to check which scopes have been approved for a given access
token and dynamically decide if a given HTTP service call can be made or not.
Clients can also proactively revoke the tokens using a token revocation
mechanism.</p><h2 id="JAX-RSOAuth2-OAuth2clientfilters">OAuth2 client
filters</h2><p>Not all clients that may need to access an OAuth2-protected
application server can be modified. Futhermore, not all OAuth2 clients can
participate in advanced flows such as an authorization code flow and need to be
initi
alized with access and refresh tokens.</p><p>CXF HTTPConduit HttpAuthSupplier
supporting access and refresh tokens is shipped starting from CXF 3.0.5
.</p><p>org.apache.cxf.rs.security.oauth2.client.BearerAuthSupplier supports
creating HTTP Authorization header from bearer access tokens, refreshing them
proactively or in response to 401 failures and recreating HTTP Authorization
from the refreshed token.</p><p>It is not possible to refresh a token from a
JAX-RS ClientRequestFilter because such a filter does not handle HTTP responses
so it can not detect 401 (returned by a server if the access token has
expired), while HTTPConduit HttpAuthSupplier gets a chance to react to 401 and
retry.</p><p>Here is a configuration example:</p><p> </p><div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+</div></div><p>The client code directly dealing with OAuth2 specifics can be
the most flelxible option: the client which has both access and refresh tokens
can check the current access token expiry time and if it is known to have
expiried then it can proactively</p><p>refresh the tokens, avoiding doing a
futile HTTP request that is bound to return 401. Or/and indeed it can take care
of JAX-RS NotAuthorizedException (401) and refresh the tokens. Sophisticated
clients might want to check which scopes have been approved for a given access
token and dynamically decide if a given HTTP service call can be made or not.
Clients can also proactively revoke the tokens using a token revocation
mechanism.</p><h2
id="JAX-RSOAuth2-OAuth2clientapplicationswithcode-grantfilters">OAuth2 client
applications with code-grant filters</h2><p>The code in the previous section
shows the client application code directly supporting OAuth2 dynamics
(redirection, the access token acquisition). Starting from CXF
3.0.6 a simpler option is possible with the help of ClientCodeRequestFilter.
This filter manages the initial redirection, exchanging code grants for tokens,
persisting the request state, and then making the token and the state available
to the application code, for example, the following code does not deal itself
with teh redirection or interacting with OAuth2 servers:</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[import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.cxf.rs.security.oauth2.client.ClientTokenContext;
+
+@Path("reserve")
+public class ReservationService {
+
+private WebClient socialService;
+private WebClient restaurantService;
+
+@GET
+@Path("table")
+@Produces("text/html")
+public Response reserve(@Context ClientTokenContext context) {
+ // Check if token is available
+ if (context.getToken() == null) {
+ return redirectToFailureHandler(NO_CODE_GRANT);
+ }
+ // Prepare Authorization header
+ socialService.authorization(context.getToken());
+
+ // Get the state that was captured by the filter before redirecting the
user to OAuth2 server
+ ReservationRequest request = context.getState(ReservationRequest.class);
+
+ // Work with the service on behalf of a user
+ Calendar c = null;
+ try {
+ c = socialService.get(Calendar.class);
+ } catch (RuntimeException ex) {
+ return redirectToFailureHandler(CALENDAR_ACCESS_PROBLEM);
+ }
+
+ CalendarEntry entry = c.getEntry(request.getHour());
+ if (entry.getEventDescription() == null ||
entry.getEventDescription().trim().isEmpty()) {
+ String address = restaurantService.post(new
Form().param("name", request.getReserveName())
+ .param("phone",
request.getContactPhone())
+ .param("hour",
Integer.toString(request.getHour())),
+ String.class);
+ if (address == null) {
+ return redirectToFailureHandler(NO_RESERVATION);
+ }
+
+ // update the user's calendar
+ Response response = socialService.form(new
Form().param("hour", Integer.toString(request.getHour()))
+ .param("description",
"Table reserved at " + address));
+ boolean calendarUpdated = response.getStatus() == 200 ||
response.getStatus() == 204;
+
+ return Response.ok(new ReservationConfirmation(address,
request.getHour(), calendarUpdated))
+ .build();
+ } else {
+ return redirectToFailureHandler(CALENDAR_BUSY);
+ }
+ }
+}
+
+]]></script>
+</div></div><p> </p><p>The filter is configured as
follows:</p><p> </p><p> </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[<beans>
+
+<jaxrs:server id="reservationsServer"
address="/reservations">
+ <jaxrs:serviceBeans>
+ <ref bean="restaurantReserveService"/>
+ </jaxrs:serviceBeans>
+ <jaxrs:providers>
+ <!-- other providers -->
+
+ <bean
class="oauth2.thirdparty.ClientTokenContextProviderImpl"/>
+ <bean
class="org.apache.cxf.rs.security.oauth2.client.ClientCodeRequestFilter">
+ <property name="authorizationServiceUri"
value="http://localhost:8080/services/authorize"/>
+ <property name="accessTokenServiceClient"
ref="atServiceClient"/>
+ <property name="startUri"
value="reserve/table"/>
+ <property name="clientCodeStateManager"
ref="codeManager"/>
+ <property name="consumer"
ref="consumer"/>
+ </bean>
+ </jaxrs:providers>
+ </jaxrs:server>
+ <bean id="codeManager"
class="oauth2.thirdparty.ClientCodeStateManagerImpl"/>
+
+ <!-- the consumer pre-registered with OAuth2 servers -->
+ <bean id="consumer"
class="org.apache.cxf.rs.security.oauth2.client.Consumer">
+ <property name="key" value="123456789"/>
+ <property name="secret" value="987654321"/>
+ </bean>
+
+ <!-- WebClient for communicating with OAuth2 AccessTokenService -->
+ <jaxrs-client:client id="atServiceClient"
serviceClass="org.apache.cxf.jaxrs.client.WebClient"
+
address="http://localhost:8080/services/oauth2Token/token">
+ <jaxrs-client:headers>
+ <entry key="Accept"
value="application/json"/>
+ </jaxrs-client:headers>
+ </jaxrs-client:client>
+
+</beans>
+
+
+]]></script>
+</div></div><p> ClientCodeRequestFilter redirects to
'authorizationServiceUri' when a 'startUri' is matched.</p><p>In the above
example the filter uses a custom 'clientCodeStateManager'
(org.apache.cxf.rs.security.oauth2.client.ClientCodeStateManager
implementation) for keeping the original request state for it to be available
later on to the applicationc code - this is optional and is only needed if the
redirection request depends on the request parameters (example, Oauth2 scope
values are dynamic such as updateCalendar-7 where '7' is the hour) . By
default, CXF ships some state managers out of the box, at the moment these are
MemoryClientCodeStateManager and JoseClientCodeStateManager implementations,
the latter signs and/or encrypts the request state and saves it in the HTTP
session.</p><h2
id="JAX-RSOAuth2-OAuth2clientauthenticatorsfornon-dynamicclients">OAuth2 client
authenticators for non-dynamic clients</h2><p>Not all clients that may need to
access an OAuth2-protected a
pplication server can be modified. Furthermore, not all OAuth2 clients can
participate in advanced flows such as an authorization code flow and need to be
initialized with access and refresh tokens.</p><p>CXF HTTPConduit
HttpAuthSupplier supporting access and refresh tokens is shipped starting from
CXF 3.0.5 .</p><p>org.apache.cxf.rs.security.oauth2.client.BearerAuthSupplier
supports creating HTTP Authorization header from bearer access tokens,
refreshing them proactively or in response to 401 failures and recreating HTTP
Authorization from the refreshed token.</p><p>It is not possible to refresh a
token from a JAX-RS ClientRequestFilter because such a filter does not handle
HTTP responses so it can not detect 401 (returned by a server if the access
token has expired), while HTTPConduit HttpAuthSupplier gets a chance to react
to 401 and retry.</p><p>Here is a configuration example:</p><p> </p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelCo
ntent pdl">
<script class="theme: Default; brush: xml; gutter: false"
type="syntaxhighlighter"><![CDATA[<beans>
<bean id="consumer"
class="org.apache.cxf.rs.security.oauth2.client.Consumer">
<property name="clientId" value="1"/>