Author: buildbot Date: Thu Nov 13 16:47:07 2014 New Revision: 929080 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 Thu Nov 13 16:47:07 2014 @@ -118,14 +118,14 @@ 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.rbtoc1415382419537 {padding: 0px;} -div.rbtoc1415382419537 ul {list-style: disc;margin-left: 0px;} -div.rbtoc1415382419537 li {margin-left: 0px;padding-left: 0px;} +div.rbtoc1415897192618 {padding: 0px;} +div.rbtoc1415897192618 ul {list-style: disc;margin-left: 0px;} +div.rbtoc1415897192618 li {margin-left: 0px;padding-left: 0px;} -/*]]>*/</style></p><div class="toc-macro rbtoc1415382419537"> +/*]]>*/</style></p><div class="toc-macro rbtoc1415897192618"> <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-EndUserNameinAuthorizationForm">EndUser Name in Authorization Form</a></li><li><a shape="rect" href="#JAX-RSOAuth2-PublicClients(Devices)">Public Clients (Devices)</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> <ul class="toc-indentation"><li><a shape="rect" href="#JAX-RSOAuth2-OOBResponse">OOB Response</a></li><li><a shape="rect" href="#JAX-RSOAuth2-SecurecodeacquisitionwithredirectURI">Secure code acquisition with redirect URI</a></li></ul> </li></ul> </li><li><a shape="rect" href="#JAX-RSOAuth2-AccessTokenService">AccessTokenService</a> @@ -177,7 +177,7 @@ Referer=[http://localhost:8080/services/ <script class="theme: Default; brush: xml; gutter: false" type="syntaxhighlighter"><![CDATA[12-Apr-2012 13:26:21 org.apache.cxf.rs.security.oauth2.services.AbstractOAuthService checkTransportSecurity WARNING: Unsecure HTTP, Transport Layer Security is recommended ]]></script> -</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="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">client application</a> to populate an instance of <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/common/OAuthAuthorizationData.java">OAuthAuthorizationData</a> bean and return it. OAuthAuthorizationData contains application name and URI properties, optional list of <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/common/Permission.java">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="http://cxf.apache.org/docs/jax-rs-redirection.html#JAX-RSRedirection-WithRequestDispatcherProvider">RequestDispatcherProvider</a> to set the OAuthAuthorizationData bean as an HttpServletRequest attribute and redirect the response to a view handler (can be JSP or some other servlet) to actually build the form and return it to the user. Alternatively, registering <a shape="rect" href="http://cxf.apache.org/docs/jax-rs-advanced-xml.html#JAX-RSAdvancedXML-XSLT 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"> +</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="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">client application</a> to populate an instance of <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/common/OAuthAuthorizationData.java">OAuthAuthorizationData</a> bean and return it. OAuthAuthorizationData contains application name and URI properties, optional list of <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/common/Permission.java">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="http://cxf.apache.org/docs/jax-rs-redirection.html#JAX-RSRedirection-WithRequestDispatcherProvider">RequestDispatcherProvider</a> to set the OAuthAuthorizationData bean as an HttpServletRequest attribute and redirect the response to a view handler (can be JSP or some other servlet) to actually build the form and return it to the user. See the section below on other alternatives on how a view can be created.</p><p>Assuming RequestDispatcherProvider is used, the following example log shows the initial response from AuthorizationCodeGrantService:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> <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 "org.apache.cxf.rs.security.oauth2.common.OAuthAuthorizationData" as HttpServletRequest attribute "data" and redirecting the response to "/forms/oauthAuthorize.jsp". @@ -215,7 +215,7 @@ Authorization=[Basic YmFycnlAcmVzdGF1cmF Cookie=[JSESSIONID=1c289vha0cxfe], } ]]></script> -</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><h3 id="JAX-RSOAuth2-EndUserNameinAuthorizationForm">EndUser Name in Authorization Form</h3><p>You may want to display a resource owner/end user name in the authorization form this user will be facing, you can get org.apache.cxf.rs.security.oauth2.provider.ResourceOwnerNameProvider registered with either AuthorizationCodeGrantService or ImplicitGrantService.<br clear="none"> org.apache.cxf.rs.security.oauth2.provider.DefaultResourceOwnerNameProvider, if registered, will return an actual login name, the custom implementations may choose to return a complete user name instead, etc.</p><h3 id="JAX-RSOAuth2-PublicClients(Devices)">Public Clients (Devices)</h3><p>CXF 2.7.7 provides an initial support for public clients (such as various mobile devices).</p><p>Client can be 'public' if it has been registered as a public client with no client secret the service itself has a "canSupportPublicClients" property enabled. The same property will also have to be enabled on AccessTokenService (described in the next section) for a public client without a secret be able to exchange a code grant for an access token.</p><h4 id="JAX-RSOAuth2-OOBResponse">OOB Response</h4><p>If a public client has not registered a redirect URI with the Authorization service then the authorization code can be returned out-of-band (OOB), see <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/common/OOBAuthorizationResponse.java">OOBAuthorizationResponse</a> bean. By default, it is returned directly to the end user, unless a custom <a shape="rect" class="external-link" href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oa uth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/OOBResponseDeliverer.java">OOBResponseDeliverer</a> is registered with AuthorizationCodeGrantService which may deliver it to the client via some custom back channel.</p><p>Having OOB responses supported is useful when a public client (typically a device which can not keep the client secrets and where no redirect URI is supported) needs to get a code grant. What will happen is that a device owner will send a request to Authorization Service which may look like this:</p><div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent"> +</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><h3 id="JAX-RSOAuth2-HowtocreateAuthorizationView">How to create Authorization View</h3><p>Typically one can use RequestDispatcherProvider to redirect to a view handler like JSP. Overriding RedirectionBasedService.startAuthorization by delegating to the superclass and then converting the Response to HTML or writing a custom MessageBodyWriter that will do the conversion are other two options.</p><p>Yet another option is to register <a shape="rect" href="http://cxf.apache.org/docs/jax-rs-advanced-xml.html#JAX-RSAdvancedXML-XSLTsupport">XSLTJaxbProvider</a> which would convert OAuthAuthorizationData to HTML or JAXBProvider set with a reference to an XSLT stylesheet.</p><h3 id="JAX-RSOAuth2-EndUserNameinAuthorizationForm">EndUser Name in Authorization Form</h3><p>You may want to display a resource owner/end user name in the authorization form this user will be facing, you can get org.apache.cxf.rs.security.oauth2.provider.ResourceOwnerNameProvider registered with either AuthorizationCodeGrantService or ImplicitGrantService.<br clear="none"> org.apache.cxf.rs.security.oauth2.provider.DefaultResourceOwnerNameProvider, if registered, will return an actual login name, the custom implementations may choose to return a complete user name instead, etc.</p><h3 id="JAX-RSOAuth2-PublicClients(Devices)">Public Clients (Devices)</h3><p>CXF 2.7.7 provides an initial support for public clients (such as various mobile devices).</p><p>Client can be 'public' if it has been registered as a public client with no client secret the service itself has a "canSupportPublicClients" property enabled. The same property will also have to be enabled on AccessTokenService (described in the next section) for a public client without a secret b e able to exchange a code grant for an access token.</p><h4 id="JAX-RSOAuth2-OOBResponse">OOB Response</h4><p>If a public client has not registered a redirect URI with the Authorization service then the authorization code can be returned out-of-band (OOB), see <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/common/OOBAuthorizationResponse.java">OOBAuthorizationResponse</a> bean. By default, it is returned directly to the end user, unless a custom <a shape="rect" class="external-link" href="http://svn.apache.org/repos/asf/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/OOBResponseDeliverer.java">OOBResponseDeliverer</a> is registered with AuthorizationCodeGrantService which may deliver it to the client via some custom back channel.</p><p>Having OOB responses supported is useful when a public client (typically a device which can not keep the client secrets and where no redirect URI is supported) needs to get a code grant. What will happen is that a device owner will send a request to Authorization Service which may look like this:</p><div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent"> <pre>GET http://localhost:8080/services/social/authorize?client_id=mobileClient&response_type=code </pre> @@ -424,7 +424,7 @@ Headers: Accept=[application/xml] } ]]></script> -</div></div><p>the filter will do the following:</p><p>1. Retrieve a ServerAccessToken by delegating to a matching registered <a shape="rect" class="external-link" href="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">AccessTokenValidator</a>. AccessTokenValidator is expected to check the validity of the incoming token parameters and possibly delegate to OAuthDataProvider to find the token representation - this is what the filter will default to if no matching AccessTokenValidator is found and the Authorization scheme is 'Bearer'.</p><p>2. Check the token has not expired</p><p>3. AccessToken may have a list of <a shape="rect" class="external-link" href="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">OAuthPermissions</a>. For every permission it will:</p><ul class="alte rnate"><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 shape="rect" class="external-link" href="http://svn.apache.org/repos/asf/cxf/trunk/api/src/main/java/org/apache/cxf/security/SecurityContext.java">SecurityContext</a> using this list of <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/data/OAuthPermission.java">OAuthPermissions</a>, the <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/common/UserSubject.java">UserSubject</a> representing the client or the end user who authorized the grant used to obtain this token.</p><p>This SecurityContext will not necessaril y be important for some of OAuth2 applications. Most of the security checks will be done by OAuth2 filters and security filters protecting the main application path the end users themselves use. Only if you would like to share the same JAX-RS resource code and access URIs between end users and clients then it can become handy. More on it below.</p><p>Here is one example of how OAuthRequestFilter can be configured:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> +</div></div><p>the filter will do the following:</p><p>1. Retrieve a ServerAccessToken by delegating to a matching registered <a shape="rect" class="external-link" href="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">AccessTokenValidator</a>. AccessTokenValidator is expected to check the validity of the incoming token parameters and possibly delegate to OAuthDataProvider to find the token representation - this is what the filter will default to if no matching AccessTokenValidator is found and the Authorization scheme is 'Bearer'.</p><p>2. Check the token has not expired</p><p>3. AccessToken may have a list of <a shape="rect" class="external-link" href="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">OAuthPermissions</a>. For every permission it will:</p><ul class="alte rnate"><li>If it has a uri property set then the current request URI will be checked against it</li><li>If it has an httpVerb property set then the current HTTP verb will be checked against it</li></ul><p>If an allPermissionsMatch property is set then the filter will check that all the token permissions have been met.</p><p>If a requestScopes property is set then the filter will check that all of the scopes are 'covered' by one or more token permissions.</p><p>4. Finally, it will create a CXF <a shape="rect" class="external-link" href="http://svn.apache.org/repos/asf/cxf/trunk/api/src/main/java/org/apache/cxf/security/SecurityContext.java">SecurityContext</a> using this list of <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/data/OAuthPermission.java">OAuthPermissions</a>, the <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/common/UserSubject.java">UserSubject</a> representing the client or the end user who authorized the grant used to obtain this token.</p><p>This SecurityContext will not necessarily be important for some of OAuth2 applications. Most of the security checks will be done by OAuth2 filters and security filters protecting the main application path the end users themselves use. Only if you would like to share the same JAX-RS resource code and access URIs between end users and clients then it can become handy. More on it below.</p><p>Here is one example of how OAuthRequestFilter can be configured:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> <script class="theme: Default; brush: xml; gutter: false" type="syntaxhighlighter"><![CDATA[<bean id="oauthProvider" class="oauth.manager.OAuthManager"/> <bean id="oauthFiler" class="org.apache.cxf.rs.security.oauth2.filters.OAuthRequestFilter"> <property name="dataProvider" ref="oauthProvider"/>