|  | <?xml version="1.0"?> | 
|  | <!-- | 
|  |  | 
|  | Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved. | 
|  |  | 
|  | This program and the accompanying materials are made available under the | 
|  | terms of the Eclipse Public License v. 2.0, which is available at | 
|  | http://www.eclipse.org/legal/epl-2.0. | 
|  |  | 
|  | This Source Code may also be made available under the following Secondary | 
|  | Licenses when the conditions for such availability set forth in the | 
|  | Eclipse Public License v. 2.0 are satisfied: GNU General Public License, | 
|  | version 2 with the GNU Classpath Exception, which is available at | 
|  | https://www.gnu.org/software/classpath/license.html. | 
|  |  | 
|  | SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 | 
|  |  | 
|  | --> | 
|  |  | 
|  | <!DOCTYPE chapter [<!ENTITY % ents SYSTEM "jersey.ent" > %ents; | 
|  | <!ENTITY jersey.github.oauth1.twitter.client.example.link "<link xlink:href='&jersey.github.examples.uri;/oauth-client-twitter'>OAuth 1 Twitter Client Example</link>"> | 
|  | <!ENTITY jersey.github.oauth2.google.client.example.link "<link xlink:href='&jersey.github.examples.uri;/oauth2-client-google-webapp'>OAuth 2 Google Client Web Application Example</link>"> | 
|  | <!ENTITY oauth1.spec.link "<link xlink:href='http://tools.ietf.org/html/rfc5849'>OAuth 1.0 specification</link>"> | 
|  | <!ENTITY oauth2.spec.link "<link xlink:href='http://tools.ietf.org/html/rfc6749'>OAuth 2.0 specification</link>"> | 
|  | ]> | 
|  | <chapter xmlns="http://docbook.org/ns/docbook" | 
|  | version="5.0" | 
|  | xml:lang="en" | 
|  | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | 
|  | xmlns:xlink="http://www.w3.org/1999/xlink" | 
|  | xsi:schemaLocation="http://docbook.org/ns/docbook http://docbook.org/xml/5.0/xsd/docbook.xsd | 
|  | http://www.w3.org/1999/xlink http://www.w3.org/1999/xlink.xsd" | 
|  | xml:id="security"> | 
|  | <title>Security</title> | 
|  |  | 
|  | <section> | 
|  | <title>Securing server</title> | 
|  | <section> | 
|  | <title>SecurityContext</title> | 
|  | <para> | 
|  | Security information of a request is available by injecting a JAX-RS &jaxrs.core.SecurityContext; instance | 
|  | using &jaxrs.core.Context; | 
|  | annotation. The injected security context instance provides the equivalent of the functionality available on | 
|  | &jee9.servlet.HttpServletRequest; API. | 
|  | The injected security context depends on the actual Jersey application deployment. For example, for a | 
|  | Jersey application deployed in a Servlet container, the Jersey &lit.jaxrs.core.SecurityContext; will | 
|  | encapsulate information from a security context retrieved from the Servlet request. | 
|  | In case of a Jersey application deployed on a Grizzly server, | 
|  | the &lit.jaxrs.core.SecurityContext; will return information retrieved from the Grizzly request. | 
|  | </para> | 
|  |  | 
|  | <para> | 
|  | &lit.jaxrs.core.SecurityContext; can be used in conjunction with sub-resource locators to return different | 
|  | resources based on the specific roles a user principal is included in. For example, a sub-resource locator could | 
|  | return a different resource if a user is a preferred customer: | 
|  |  | 
|  | <example> | 
|  | <title>Using &lit.jaxrs.core.SecurityContext; for a Resource Selection</title> | 
|  | <programlisting language="java" linenumbering="numbered"><![CDATA[@Path("basket") | 
|  | public ShoppingBasketResource get(@Context SecurityContext sc) { | 
|  | if (sc.isUserInRole("PreferredCustomer") { | 
|  | return new PreferredCustomerShoppingBasketResource(); | 
|  | } else { | 
|  | return new ShoppingBasketResource(); | 
|  | } | 
|  | }]]></programlisting> | 
|  | </example> | 
|  | </para> | 
|  |  | 
|  | <para> | 
|  | &lit.jaxrs.core.SecurityContext; is inherently request-scoped, yet can be also injected into fields of singleton | 
|  | resources and JAX-RS providers. In such case the proxy of the request-scoped &lit.jaxrs.core.SecurityContext; | 
|  | will be injected. | 
|  |  | 
|  | <example> | 
|  | <title>Injecting &lit.jaxrs.core.SecurityContext; into a singleton resource</title> | 
|  | <programlisting language="java" linenumbering="numbered"><![CDATA[@Path("resource") | 
|  | @Singleton | 
|  | public static class MyResource { | 
|  | // Jersey will inject proxy of Security Context | 
|  | @Context | 
|  | SecurityContext securityContext; | 
|  |  | 
|  | @GET | 
|  | public String getUserPrincipal() { | 
|  | return securityContext.getUserPrincipal().getName(); | 
|  | } | 
|  | }]]></programlisting> | 
|  | </example> | 
|  | </para> | 
|  |  | 
|  | <section> | 
|  | <title>Initializing Security Context with Servlets</title> | 
|  | <para> | 
|  | As described above, the &lit.jaxrs.core.SecurityContext; by default (if not overwritten by | 
|  | a request filter) only exposes security information from the underlying container. | 
|  | In the case you deploy a Jersey application in a Servlet container, you need to configure the | 
|  | Servlet container security aspects (<literal><security-constraint></literal>, | 
|  | <literal><auth-constraint></literal> and user to roles mappings) | 
|  | in order to be able to secure requests via calls to to the JAX-RS &lit.jaxrs.core.SecurityContext;. | 
|  | </para> | 
|  | </section> | 
|  |  | 
|  | <section> | 
|  | <title>Using Security Context in Container Request Filters</title> | 
|  | <para> | 
|  | The &lit.jaxrs.core.SecurityContext; can be directly retrieved from &jaxrs.ContainerRequestContext; via | 
|  | <literal>getSecurityContext()</literal> method. You can also replace the default | 
|  | &lit.jaxrs.core.SecurityContext; in a request context with a custom one using the | 
|  | <literal>setSecurityContext(SecurityContext)</literal> method. If you set a custom | 
|  | &lit.jaxrs.core.SecurityContext; instance in your &jaxrs.container.ContainerRequestFilter;, | 
|  | this security context instance will be used for injection into JAX-RS resource class fields. | 
|  | This way you can implement a custom authentication filter that may setup your own | 
|  | &lit.jaxrs.core.SecurityContext; to be used. To ensure the early execution of your custom | 
|  | authentication request filter, set the filter priority to <literal>AUTHENTICATION</literal> | 
|  | using constants from &jaxrs.Priorities;. An early execution of you authentication filter will ensure that | 
|  | all other filters, resources, resource methods and sub-resource locators will execute with your custom | 
|  | &lit.jaxrs.core.SecurityContext; instance. | 
|  | </para> | 
|  | </section> | 
|  | </section> | 
|  |  | 
|  | <section> | 
|  | <title>Authorization - securing resources</title> | 
|  | <section> | 
|  | <title>Security resources with <literal>web.xml</literal></title> | 
|  | <para> | 
|  | In cases where a Jersey application is deployed in a Servlet container you can rely only on | 
|  | the standard Java/Jakarta EE Web application security mechanisms offered by the Servlet container and | 
|  | configurable via application's <literal>web.xml</literal> descriptor. | 
|  | You need to define the <literal><security-constraint></literal> elements in the | 
|  | <literal>web.xml</literal> and assign roles which are able to access these resources. You can also | 
|  | define HTTP methods that are allowed to be executed. See the following example. | 
|  |  | 
|  | <example> | 
|  | <title>Securing resources using <literal>web.xml</literal> | 
|  | </title> | 
|  | <programlisting language="xml" linenumbering="numbered"><![CDATA[<security-constraint> | 
|  | <web-resource-collection> | 
|  | <url-pattern>/rest/admin/*</url-pattern> | 
|  | </web-resource-collection> | 
|  | <auth-constraint> | 
|  | <role-name>admin</role-name> | 
|  | </auth-constraint> | 
|  | </security-constraint> | 
|  | <security-constraint> | 
|  | <web-resource-collection> | 
|  | <url-pattern>/rest/orders/*</url-pattern> | 
|  | </web-resource-collection> | 
|  | <auth-constraint> | 
|  | <role-name>customer</role-name> | 
|  | </auth-constraint> | 
|  | </security-constraint> | 
|  | <login-config> | 
|  | <auth-method>BASIC</auth-method> | 
|  | <realm-name>my-default-realm</realm-name> | 
|  | </login-config>]]></programlisting> | 
|  | </example> | 
|  |  | 
|  | The example secures two kinds of URI namespaces using the HTTP Basic Authentication. | 
|  | <literal>rest/admin/*</literal> will be accessible only for user group "admin" and | 
|  | <literal>rest/orders/*</literal> will be accessible for "customer" user group. This security configuration | 
|  | does not use JAX-RS or Jersey features at all as it is enforced by the Servlet container even before | 
|  | a request reaches the Jersey application. Keeping these security constrains up to date with your | 
|  | JAX-RS application might not be easy as whenever you change the &jaxrs.Path; annotations on your resource | 
|  | classes you may need to update also the <literal>web.xml</literal> | 
|  | security configurations to reflect the changed JAX-RS resource paths. Therefore Jersey offers a | 
|  | <link linkend="annotation-based-security">more flexible solution</link> | 
|  | based on placing standard Java/Jakarta EE security annotations directly on JAX-RS resource classes and methods. | 
|  | </para> | 
|  | </section> | 
|  |  | 
|  | <section xml:id="annotation-based-security"> | 
|  | <title>Securing JAX-RS resources with standard <literal>jakarta.annotation.security</literal> annotations</title> | 
|  |  | 
|  | <para> | 
|  | With Jersey you can define the access to resources based on the user group using annotations. You | 
|  | can, for example, define that only a user group "admin" can execute specific resource method. To do that you | 
|  | firstly need to register &jersey.server.RolesAllowedDynamicFeature; as a provider. The following example | 
|  | shows how to register the feature if your deployment is based on a &jersey.server.ResourceConfig;. | 
|  |  | 
|  | <example> | 
|  | <title>Registering RolesAllowedDynamicFeature using ResourceConfig</title> | 
|  | <programlisting language="java" linenumbering="numbered">final ResourceConfig resourceConfig = new ResourceConfig(MyResource.class); | 
|  | resourceConfig.register(RolesAllowedDynamicFeature.class); | 
|  | </programlisting> | 
|  | </example> | 
|  |  | 
|  | Alternatively, typically when deploying your application to a Servlet container, you can implement your JAX-RS | 
|  | &jaxrs.core.Application; subclass by extending from the Jersey &lit.jersey.server.ResourceConfig; and | 
|  | registering the &lit.jersey.server.RolesAllowedDynamicFeature; in the constructor: | 
|  |  | 
|  | <example> | 
|  | <title>Registering RolesAllowedDynamicFeature by extending ResourceConfig</title> | 
|  | <programlisting language="java" linenumbering="numbered">public class MyApplication extends ResourceConfig { | 
|  | public MyApplication() { | 
|  | super(MyResource.class); | 
|  | register(RolesAllowedDynamicFeature.class); | 
|  | } | 
|  | }</programlisting> | 
|  | </example> | 
|  | </para> | 
|  | <para> | 
|  | Once the feature is registered, you can use annotations from package | 
|  | <literal>jakarta.annotation.security</literal> defined by JSR-250. See the following example. | 
|  |  | 
|  | <example> | 
|  | <title>Applying <literal>jakarta.annotation.security</literal> to JAX-RS resource methods.</title> | 
|  | <programlisting language="java" linenumbering="numbered"><![CDATA[@Path("/") | 
|  | @PermitAll | 
|  | public class Resource { | 
|  | @RolesAllowed("user") | 
|  | @GET | 
|  | public String get() { return "GET"; } | 
|  |  | 
|  | @RolesAllowed("admin") | 
|  | @POST | 
|  | public String post(String content) { return content; } | 
|  |  | 
|  | @Path("sub") | 
|  | public SubResource getSubResource() { | 
|  | return new SubResource(); | 
|  | } | 
|  | }]]></programlisting> | 
|  | </example> | 
|  |  | 
|  | The resource class <literal>Resource</literal> defined in the example is annotated with a | 
|  | &jee9.annotations.PermitAll; annotation. This means that all methods in the class which do not | 
|  | override this | 
|  | annotation will be permitted for all user groups (no restrictions are defined). In our example, the | 
|  | annotation will only apply to the <literal>getSubResource()</literal> method as it is the only method | 
|  | that does not override the annotation by defining custom role-based security settings using the | 
|  | &jee9.annotations.RolesAllowed; annotation. | 
|  | &lit.jee9.annotations.RolesAllowed; annotations present on the other methods define a role or a set of | 
|  | roles that are allowed to execute a particular method. | 
|  | </para> | 
|  | <para> | 
|  | These Java/Jakarta EE security annotations are processed internally in the request filter registered using | 
|  | the Jersey &lit.jersey.server.RolesAllowedDynamicFeature;. The roles defined in the annotations are | 
|  | tested against current roles set in the &lit.jaxrs.core.SecurityContext; using | 
|  | the &lit.jaxrs.core.SecurityContext;<literal>.isUserInRole(String role)</literal> method. In case the caller | 
|  | is not in the role specified by the annotation, the HTTP <literal>403 (Forbidden)</literal> | 
|  | error response is returned. | 
|  | </para> | 
|  | </section> | 
|  | </section> | 
|  | </section> | 
|  |  | 
|  | <section> | 
|  | <title>Client Security</title> | 
|  | <para> | 
|  | For details about client security please see the <link linkend="client">Client chapter</link>. Jersey | 
|  | client allows to define parameters of SSL communication using <literal>HTTPS</literal> protocol. | 
|  | You can also use jersey built-in authentication filters which perform <emphasis>HTTP Basic Authentication</emphasis> | 
|  | or <emphasis>HTTP Digest Authentication</emphasis>. See the client chapter for more details. | 
|  | </para> | 
|  | </section> | 
|  |  | 
|  | <section> | 
|  | <title>OAuth Support</title> | 
|  | <para> | 
|  | OAuth is a specification that defines secure authentication model on behalf of another user. | 
|  | Two versions of OAuth exists at the moment - <emphasis>OAuth 1</emphasis> defined by &oauth1.spec.link; and | 
|  | <emphasis>OAuth 2</emphasis> defined by &oauth2.spec.link;. | 
|  | OAuth 2 is the latest version and it is not backward compatible with | 
|  | OAuth 1 specification. OAuth in general is widely used in popular social Web sites in order to grant access | 
|  | to a user account and associated resources for a third party consumer (application). The consumer then usually | 
|  | uses RESTful Web Services to access the user data. | 
|  | The following example describes a use case of the OAuth (similar for OAuth 1 and OAuth 2). The example is simple | 
|  | and probably obvious for many developers but introduces terms that are used in this | 
|  | documentation as well as in Jersey OAuth API documentation. | 
|  | </para> | 
|  | <para> | 
|  | Three parties act in an OAuth scenario. | 
|  | </para> | 
|  | <mediaobject> | 
|  | <imageobject> | 
|  | <imagedata fileref="images/oauth-parties.png" format="PNG" width="80%" scalefit="1" align="center"/> | 
|  | </imageobject> | 
|  | </mediaobject> | 
|  |  | 
|  | <para> | 
|  | The first party represents a user, in our case Adam, | 
|  | who is called in the OAuth terminology a <emphasis>Resource Owner</emphasis>. Adam has an account on | 
|  | Twitter. Twitter represents the second party. This party is called a | 
|  | <emphasis>Service Provider</emphasis>. Twitter offers a web interface | 
|  | that Adam uses to create new tweets, read tweets of others etc. Now, Adam uses our new web site, | 
|  | HelloWorldWeb, which is a very simple web site that says <literal>Hello World</literal> but it additionally | 
|  | displays the last tweet of the logged in user. | 
|  | To do so, our web site needs to have access to the Twitter account of Adam. Our web site is a 3rd party | 
|  | application that wants to connect to Twitter and get Adam's tweets. In OAuth, such party is called | 
|  | <emphasis>Consumer</emphasis>. | 
|  | Our Consumer would like to use Twitter's RESTful APIs to get some data associated with Adam's Twitter account. | 
|  | In order to solve this situation Adam could directly give his Twitter password to the HelloWorldWeb. | 
|  | This would however be rather unsafe, especially if we do not know much about the authors of the application. | 
|  | If Adam would give his password to HelloWorldWeb, he would have to deal with the associated security risks. | 
|  | First of all, Adam would have to fully trust HelloWorldWeb | 
|  | that it will not misuse the full access to his Twitter account. Next, if Adam would change his password, | 
|  | he would need to remember to give the new password also to the HelloWorldWeb application. | 
|  | And at last, if Adam would like to revoke the HelloWorldWeb's access to his Twitter account, | 
|  | he would need to change his password again. The OAuth protocol has been devised to address all these challenges. | 
|  | </para> | 
|  |  | 
|  | <para> | 
|  | With OAuth, a resource owner (Adam) grants an access to a consumer (HelloWorldWeb) without giving it | 
|  | his password. This access grant is achieved by a procedure called | 
|  | <emphasis>authorization flow</emphasis>. Authorization flow is out of the scope of this | 
|  | documentation and its description can be found in the OAuth specification linked above. | 
|  | The result of the authorization flow is an <emphasis>Access Token</emphasis> which is later | 
|  | used by the consumer to authenticate against the service provider. | 
|  | While this brief description applies to both OAuth 1 and 2, note that there are some differences in details | 
|  | between these two specifications. | 
|  | </para> | 
|  |  | 
|  | <para> | 
|  | Jersey OAuth is currently supported for the following use cases and OAuth versions: | 
|  |  | 
|  | <itemizedlist> | 
|  | <listitem> | 
|  | <para> | 
|  | OAuth 1: Client (consumer) and server (service provider) | 
|  | </para> | 
|  | </listitem> | 
|  | <listitem> | 
|  | <para> | 
|  | OAuth 2: Client (consumer) | 
|  | </para> | 
|  | </listitem> | 
|  | </itemizedlist> | 
|  |  | 
|  | With client and server support there are two supported scenarios: | 
|  |  | 
|  | <itemizedlist> | 
|  | <listitem> | 
|  | <para> | 
|  | Authorization flow | 
|  | </para> | 
|  | </listitem> | 
|  | <listitem> | 
|  | <para> | 
|  | Authentication with Access Token (support for authenticated requests) | 
|  | </para> | 
|  | </listitem> | 
|  | </itemizedlist> | 
|  | </para> | 
|  |  | 
|  | <section> | 
|  | <title>OAuth 1</title> | 
|  | <para> | 
|  | OAuth 1 protocol is based on message signatures that are calculated using specific | 
|  | signature methods. Signatures are quite complex and therefore are implemented in a separate | 
|  | module. The OAuth 1 Jersey modules are (<literal>groupId:artifactId:description</literal>): | 
|  | <itemizedlist> | 
|  | <listitem> | 
|  | <para> | 
|  | <literal>org.glassfish.jersey.security:oauth1-client</literal>: provides client | 
|  | OAuth 1 support for authorization flow and authentication | 
|  | </para> | 
|  | </listitem> | 
|  | <listitem> | 
|  | <para> | 
|  | <literal>org.glassfish.jersey.security:oauth1-server</literal>: provides server | 
|  | OAuth 1 support for authorization flow, SPI for token management including authentication | 
|  | filter. | 
|  | </para> | 
|  | </listitem> | 
|  | <listitem> | 
|  | <para> | 
|  | <literal>org.glassfish.jersey.security:oauth1-signature</literal> | 
|  | : provides support for OAuth1 request signatures. This module is a dependency of previous two | 
|  | modules and as such it will be implicitly included in your maven project. | 
|  | The module can be used as a standalone module but this will not be needed in most of the use cases. | 
|  | You would do that if you wanted to implement your own OAuth support and would not want to deal with | 
|  | implementing the complex signature algorithms. | 
|  | </para> | 
|  | </listitem> | 
|  | </itemizedlist> | 
|  | </para> | 
|  |  | 
|  | <section> | 
|  | <title>Server</title> | 
|  |  | 
|  | <para> | 
|  | To add support for OAuth into your server-side application, add the following dependency to your<literal> | 
|  | pom.xml</literal>: | 
|  | <programlisting language="xml"><dependency> | 
|  | <groupId>org.glassfish.jersey.security</groupId> | 
|  | <artifactId>oauth1-server</artifactId> | 
|  | <version>&version;</version> | 
|  | </dependency></programlisting> | 
|  | Again, there is no need to add a direct dependency to the signature module, it will be transitively included. | 
|  | </para> | 
|  | <para> | 
|  | Let's now briefly go over the most important server Jersey OAuth APIs and SPIs: | 
|  | <itemizedlist> | 
|  | <listitem> | 
|  | <para>&jersey.server.oauth1.OAuth1ServerFeature;: The feature which enables the | 
|  | OAuth 1 support on the server and registers &lit.jersey.server.oauth1.OAuth1Provider; | 
|  | explained in the following point. | 
|  | </para> | 
|  | </listitem> | 
|  | <listitem> | 
|  | <para> | 
|  | &jersey.server.oauth1.OAuth1Provider;: Implementation of this SPI must be | 
|  | registered to the server runtime as a standard provider. The implementation will be used | 
|  | to create request and access token, get consumer by consumer key, etc. You can either | 
|  | implement your provider or use the default implementation provided by Jersey by | 
|  | &jersey.server.oauth1.DefaultOAuth1Provider;. | 
|  | </para> | 
|  | </listitem> | 
|  | <listitem> | 
|  | <para> | 
|  | &jersey.server.oauth1.OAuth1ServerProperties;: properties that can be used | 
|  | to configure the OAuth 1 support. | 
|  | </para> | 
|  | </listitem> | 
|  | <listitem> | 
|  | <para> | 
|  | &jersey.server.oauth1.OAuth1Consumer;, &jersey.server.oauth1.OAuth1Token;: classes | 
|  | that contain consumer key, request and access tokens. You need to | 
|  | implement them only if you also implement the interface | 
|  | &lit.jersey.server.oauth1.OAuth1Provider;. | 
|  | </para> | 
|  | </listitem> | 
|  | </itemizedlist> | 
|  | </para> | 
|  |  | 
|  | <para> | 
|  | First step in enabling Jersey OAuth 1 support is to register a | 
|  | &lit.jersey.server.oauth1.OAuth1ServerFeature; instance | 
|  | initialized with an instance of &lit.jersey.server.oauth1.OAuth1Provider;. Additionally, you may | 
|  | configure the <emphasis>Request Token URI</emphasis> and <emphasis>Access Token URI</emphasis> - | 
|  | the endpoints accessible on the OAuth server that issue Request and Access Tokens. These endpoints | 
|  | are defined in the OAuth 1 specification and are contacted as part of the OAuth authorization flow. | 
|  | </para> | 
|  | <para> | 
|  | Next, when a client initiates the OAuth authorization flow, the provided implementation of | 
|  | &lit.jersey.server.oauth1.OAuth1Provider; will be invoked as to create new tokens, | 
|  | get tokens and finally to store the issued Access Token. If a consumer already has a valid Access Token | 
|  | and makes Authenticated Requests (with OAuth 1 Authorization information in the HTTP header), | 
|  | the provider will be invoked to provide the &lit.jersey.server.oauth1.OAuth1Token; for the | 
|  | Access Token information in the header. | 
|  | </para> | 
|  |  | 
|  | </section> | 
|  | <section xml:id="oauth1-client"> | 
|  | <title>Client</title> | 
|  | <note> | 
|  | <para> | 
|  | OAuth client support in Jersey is almost identical for OAuth 1 and OAuth 2. As such, this chapter | 
|  | provides useful information even for users that use OAuth 2 client support. | 
|  | </para> | 
|  | </note> | 
|  | <para> | 
|  | To add support for OAuth into your Jersey client application, add the following dependency to your | 
|  | <literal>pom.xml</literal>: | 
|  |  | 
|  | <programlisting language="xml"><dependency> | 
|  | <groupId>org.glassfish.jersey.security</groupId> | 
|  | <artifactId>oauth1-client</artifactId> | 
|  | <version>&version;</version> | 
|  | </dependency></programlisting> | 
|  |  | 
|  | As mentioned earlier, there is no need to add a direct dependency to the signature module, | 
|  | it will be transitively included. | 
|  | </para> | 
|  |  | 
|  | <para> | 
|  | OAuth 1 client support initially started as a code migration from Jersey 1.x. | 
|  | During the migration however the API of was significantly revised. | 
|  | The high level difference compared to Jersey 1.x OAuth client API is that the authorization flow | 
|  | is no longer part of a client OAuth filter. Authorization flow is now a standalone utility | 
|  | and can be used without a support for subsequent authenticated requests. | 
|  | The support for authenticated requests stays in the | 
|  | &lit.jaxrs.client.ClientRequestFilter; but is not part of a public API | 
|  | anymore and is registered by a Jersey OAuth &jaxrs.core.Feature;. | 
|  | </para> | 
|  |  | 
|  | <para> | 
|  | The most important parts of the Jersey client OAuth API and SPI are explained here: | 
|  |  | 
|  | <itemizedlist> | 
|  | <listitem> | 
|  | <para> | 
|  | &jersey.client.oauth1.OAuth1ClientSupport;: The main class which contains builder | 
|  | methods to build features that enable the OAuth 1 support. Start with this class every time | 
|  | you need to add any OAuth 1 support to the Jersey Client (build an Authorization flow | 
|  | or initialize client to perform authenticated requests). The class contains a | 
|  | static method that returns an instance of &jersey.client.oauth1.OAuth1Builder; and also | 
|  | the class defines request properties to influence behaviour of the authenticated | 
|  | request support. | 
|  | </para> | 
|  | </listitem> | 
|  |  | 
|  | <listitem> | 
|  | <para> | 
|  | &jersey.client.oauth1.OAuth1AuthorizationFlow;: API that allows to perform the | 
|  | Authorization flow against service provider. Implementation of this interface is a | 
|  | class that is used as a standalone utility and is not part of the JAX-RS client. In | 
|  | other words, this is not a feature that should be registered into the client. | 
|  | </para> | 
|  | </listitem> | 
|  |  | 
|  | <listitem> | 
|  | <para> | 
|  | &jersey.client.oauth1.AccessToken;, &jersey.client.oauth1.ConsumerCredentials;: | 
|  | Interfaces that define Access Token classes and Consumer Credentials. Interfaces contain | 
|  | getters for public keys and secret keys of token and credentials. | 
|  | </para> | 
|  | </listitem> | 
|  | </itemizedlist> | 
|  |  | 
|  | An example of how Jersey OAuth 1 client API is used was in | 
|  | the &jersey.github.oauth1.twitter.client.example.link; but for now it's temporally removed from examples. | 
|  | The following code snippets are extracted from the | 
|  | example and explain how to use the Jersey OAuth client API. | 
|  | </para> | 
|  | <para> | 
|  | Before we start with any interaction with Twitter, we need to register our application | 
|  | on Twitter. See the example <literal>README.TXT</literal> file for the instructions. | 
|  | As a result of the registration, we get the consumer credentials that identify our application. | 
|  | Consumer credentials consist of <literal>consumer key</literal> and <literal>consumer secret</literal>. | 
|  | </para> | 
|  | <para> | 
|  | As a first step in our code, we need to perform the authorization flow, where the user grants us an access to | 
|  | his/her Twitter client. | 
|  | </para> | 
|  | <para> | 
|  | <example> | 
|  | <title>Build the authorization flow utility</title> | 
|  |  | 
|  | <programlisting language="java" linenumbering="numbered"><![CDATA[ConsumerCredentials consumerCredentials = new ConsumerCredentials( | 
|  | "a846d84e68421b321a32d, "f13aed84190bc"); | 
|  | OAuth1AuthorizationFlow authFlow = OAuth1ClientSupport.builder(consumerCredentials) | 
|  | .authorizationFlow( | 
|  | "http://api.twitter.com/oauth/request_token", | 
|  | "http://api.twitter.com/oauth/access_token", | 
|  | "http://api.twitter.com/oauth/authorize") | 
|  | .build();]]></programlisting> | 
|  | </example> | 
|  | </para> | 
|  | <para> | 
|  | Here we have built a &lit.jersey.client.oauth1.OAuth1AuthorizationFlow; utility component representing the | 
|  | OAuth 1 authorization flow, using &lit.jersey.client.oauth1.OAuth1ClientSupport; and | 
|  | &lit.jersey.client.oauth1.OAuth1Builder; API. The static <literal>builder</literal> method accepts | 
|  | mandatory parameter with &lit.jersey.client.oauth1.ConsumerCredentials;. These | 
|  | are credentials earlier issued by Twitter for our application. | 
|  | We have specified the Twitter OAuth endpoints where Request Token, Access Token will be retrieved and | 
|  | Authorization URI to which we will redirect the user in order to grant user's consent. | 
|  | Twitter will present an HTML page on this URI and it will ask the user whether he/she would like us | 
|  | to access his/her account. | 
|  | </para> | 
|  | <para> | 
|  | Now we can proceed with the OAuth authorization flow. | 
|  |  | 
|  | <example> | 
|  | <title>Perform the OAuth Authorization Flow</title> | 
|  |  | 
|  | <programlisting language="java" linenumbering="numbered"><![CDATA[String authorizationUri = authFlow.start(); | 
|  | // here we must direct the user to authorization uri to approve | 
|  | // our application. The result will be verifier code (String). | 
|  | AccessToken accessToken = authFlow.finish(verifier);]]></programlisting> | 
|  | </example> | 
|  |  | 
|  | In the first line, we start the authorization flow. The method internally makes a request to the | 
|  | <literal>http://api.twitter.com/oauth/request_token</literal> URL | 
|  | and retrieves a Request Token. Details of this request can be found in the OAuth 1 specification. | 
|  | It then constructs a URI to which we must redirect the user. The URI is based on Twitter's | 
|  | authorization URI (<literal>http://api.twitter.com/oauth/authorize</literal>) and contains | 
|  | a Request Token as a query parameter. In the Twitter example, we have a simple console application therefore | 
|  | we print the URL to the console and ask the user to open the URL in a browser to approve the authorization | 
|  | of our application. | 
|  | Then the user gets a verifier and enters it back to the console. However, if our application would be a | 
|  | web application, we would need to return a redirection response to the user in order to redirect the user | 
|  | automatically to the <literal>authorizationUri</literal>. <!--For more information about server deployment, | 
|  | check our &jersey.github.oauth2.google.client.example.link;, where the client is part of the | 
|  | web application (the client API for OAuth 2 is similar to OAuth 1).--> | 
|  | </para> | 
|  |  | 
|  | <para> | 
|  | Once we have a verifier, we invoke the method <literal>finish()</literal> | 
|  | on our &lit.jersey.client.oauth1.OAuth1AuthorizationFlow; instance, which internally | 
|  | sends a request to an access token service URI (<literal>http://api.twitter.com/oauth/access_token</literal>) | 
|  | and exchanges the supplied verifier for a new valid Access Token. | 
|  | At this point the authorization flow is finished and we can start using the retrieved | 
|  | &lit.jersey.client.oauth1.AccessToken; to make authenticated requests. | 
|  | We can now create an instance of an OAuth 1 client &jaxrs.core.Feature; using | 
|  | &lit.jersey.client.oauth1.OAuth1ClientSupport; and pass it our <literal>accessToken</literal>. | 
|  | Another way is to use <literal>authFlow</literal> that already contains the information about access token | 
|  | to create the feature instance for us: | 
|  |  | 
|  | <example> | 
|  | <title>Authenticated requests</title> | 
|  |  | 
|  | <programlisting language="java" linenumbering="numbered"><![CDATA[Feature feature = authFlow.getOAuth1Feature(); | 
|  | Client client = ClientBuilder.newBuilder() | 
|  | .register(feature) | 
|  | .build();]]></programlisting> | 
|  | </example> | 
|  |  | 
|  | Once the feature is configured in the JAX-RS &jaxrs.client.Client; (or &jaxrs.client.WebTarget;), | 
|  | all requests invoked from such &lit.jaxrs.client.Client; (or &lit.jaxrs.client.WebTarget;) instance | 
|  | will automatically include an OAuth Authorization HTTP header (that contains also the OAuth signature). | 
|  | </para> | 
|  |  | 
|  | <para> | 
|  | Note that if you already have a valid Access Token (for example stored in the database for each of your users), | 
|  | then you can skip the authorization flow steps and directly create the OAuth &lit.jaxrs.core.Feature; | 
|  | configured to use your Access Token. | 
|  |  | 
|  | <example> | 
|  | <title>Build feature from Access Token</title> | 
|  |  | 
|  | <programlisting language="java" linenumbering="numbered"><![CDATA[AccessToken storedToken = ...; | 
|  | Feature filterFeature = OAuth1ClientSupport.builder(consumerCredentials) | 
|  | .feature() | 
|  | .accessToken(storedToken) | 
|  | .build();]]></programlisting> | 
|  | </example> | 
|  |  | 
|  | Here, the <literal>storedToken</literal> represents an &jersey.client.oauth1.AccessToken; that your client | 
|  | application keeps stored e.g. in a database. | 
|  | </para> | 
|  |  | 
|  | <para> | 
|  | Note that the OAuth feature builder API does not require the access token to be set. | 
|  | The reason for it is that you might want to build a feature which would register the internal Jersey | 
|  | OAuth &lit.jaxrs.client.ClientRequestFilter; and other related providers but which would not | 
|  | initialize the OAuth providers with a single fixed &jersey.client.oauth1.AccessToken; instance. | 
|  | In such case you would need to specify a token for every single request in the request properties. | 
|  | Key names and API documentation of these properties can be found in | 
|  | &lit.jersey.client.oauth1.OAuth1ClientSupport;. | 
|  | Using this approach, you can have a single, OAuth enabled instance of a JAX-RS &lit.jaxrs.client.Client; | 
|  | (or &jaxrs.client.WebTarget;) and use it to make authenticated requests on behalf of multiple users. | 
|  | Note that you can use the aforementioned request properties even if the feature has been initialized | 
|  | with an &lit.jersey.client.oauth1.AccessToken; to override the default access token information for | 
|  | particular requests, even though it is probably not a common use case. | 
|  | </para> | 
|  |  | 
|  | <para> | 
|  | The following code shows how to set an access token on a single request using the Jersey OAuth properties. | 
|  |  | 
|  | <example> | 
|  | <title>Specifying Access Token on a Request.</title> | 
|  | <programlisting language="java" linenumbering="numbered"><![CDATA[Response resp = | 
|  | client.target("http://my-serviceprovider.org/rest/foo/bar") | 
|  | .request() | 
|  | .property(OAuth1ClientSupport.OAUTH_PROPERTY_ACCESS_TOKEN, storedToken) | 
|  | .get();]]></programlisting> | 
|  | </example> | 
|  |  | 
|  | &lit.jersey.client.oauth1.OAuth1AuthorizationFlow; internally uses | 
|  | a &lit.jaxrs.client.Client; instance to communicate with the OAuth server. For this a | 
|  | new client instance is automatically created by default. You can supply your instance of | 
|  | a &lit.jaxrs.client.Client; to be used for the authorization flow requests (for performance | 
|  | and/or resource management reasons) using &jersey.client.oauth1.OAuth1Builder; methods. | 
|  | </para> | 
|  |  | 
|  | <section xml:id="oauth1-client-signatures"> | 
|  | <title>Public/Private Keys for RSA-SHA1 signature method</title> | 
|  |  | 
|  | <para> | 
|  | Follow the steps below in case the outgoing requests sent from client to server have to be signed with | 
|  | RSA-SHA1 signature method instead of the default one (HMAC-SHA1). | 
|  | </para> | 
|  |  | 
|  | <example> | 
|  | <title>Creating Public/Private RSA-SHA1 keys</title> | 
|  | <programlisting language="bash" linenumbering="numbered"><![CDATA[$ # Create the private key. | 
|  | $ openssl genrsa -out private.key 2048 | 
|  | $ # Convert the key into PKCS8 format. | 
|  | $ openssl pkcs8 -topk8 -in private.key -nocrypt | 
|  | $ # Extract the public key. | 
|  | $ openssl rsa -in private.key -pubout]]></programlisting> | 
|  | </example> | 
|  |  | 
|  | <para> | 
|  | The output of the second command can be used as a consumer secret to sign the outgoing request: | 
|  | <literal>new ConsumerCredentials("consumer-key", CONSUMER_PRIVATE_KEY)</literal>. Public key obtained from | 
|  | the third command can be then used on the service provider to verify the signed data. | 
|  | </para> | 
|  | <para> | 
|  | For more advanced cases (i.e. other formats of keys) a custom <literal>OAuth1SignatureMethod</literal> | 
|  | should be implemented and used. | 
|  | </para> | 
|  | </section> | 
|  | </section> | 
|  | </section> | 
|  |  | 
|  | <section> | 
|  | <title>OAuth 2 Support</title> | 
|  | <para>At the moment Jersey supports OAuth 2 only on the client side.</para> | 
|  |  | 
|  | <section> | 
|  | <title>Client</title> | 
|  | <note> | 
|  | <para> | 
|  | Note: It is suggested to read the section <xref linkend="oauth1-client"/> | 
|  | before this section. Support for OAuth on the client is very similar for both | 
|  | OAuth 1 and OAuth 2 and general principles are valid for both OAuth versions as such. | 
|  | </para> | 
|  | </note> | 
|  | <note> | 
|  | <para> | 
|  | OAuth 2 support is in a &jersey.common.Beta; state and as such the API is subject | 
|  | to change. | 
|  | </para> | 
|  | </note> | 
|  | <para> | 
|  | To add support for Jersey OAuth 2 Client API into your application, add the following dependency | 
|  | to your <literal>pom.xml</literal>: | 
|  |  | 
|  | <programlisting language="xml"><dependency> | 
|  | <groupId>org.glassfish.jersey.security</groupId> | 
|  | <artifactId>oauth2-client</artifactId> | 
|  | <version>&version;</version> | 
|  | </dependency></programlisting> | 
|  | </para> | 
|  |  | 
|  | <para> | 
|  | OAuth 2, in contrast with OAuth 1, is not a strictly defined protocol, rather a framework. | 
|  | OAuth 2 specification defines many extension points and it is up to service providers to | 
|  | implement these details and document these implementations for the service consumers. | 
|  | Additionally, OAuth 2 defines more than one authorization flow. | 
|  | The authorization flow similar to the flow from OAuth 1 is called | 
|  | the <emphasis>Authorization Code Grant Flow</emphasis>. | 
|  | This is the flow currently supported by Jersey (Jersey currently does not support other flows). | 
|  | Please refer to the &oauth2.spec.link; for more details about authorization flows. | 
|  | Another significant change compared to OAuth 1 is that OAuth 2 is not based on signatures and | 
|  | secret keys and therefore for most of the communication SSL needs to be used | 
|  | (i.e. the requests must be made through HTTPS). This means that all OAuth 2 endpoint URIs must use | 
|  | the <literal>https</literal> scheme. | 
|  | </para> | 
|  |  | 
|  | <para> | 
|  | Due to the fact that OAuth 2 does not define a strict protocol, it is not possible to provide a | 
|  | single, universal pre-configured tool interoperable with all providers. | 
|  | Jersey OAuth 2 APIs allows a lot of extensibility via parameters sent in each requests. Jersey | 
|  | currently provides two pre-configured authorization flow providers - for Google and Facebook. | 
|  | </para> | 
|  |  | 
|  | <para> | 
|  | The most important entry points of Jersey client OAuth 2 API and SPI are explained below: | 
|  |  | 
|  | <itemizedlist> | 
|  | <listitem> | 
|  | <para> | 
|  | &jersey.client.oauth2.OAuth2ClientSupport;: The main class which contains builder | 
|  | methods to build features that enable the OAuth 2 support. Start with this class every time | 
|  | you need to add any OAuth 2 support to the Jersey Client (build an Authorization flow | 
|  | or initialize client to perform authenticated requests). The class contains also | 
|  | methods to get authorization flow utilities adjusted for Facebook or Google. | 
|  | </para> | 
|  | </listitem> | 
|  |  | 
|  | <listitem> | 
|  | <para> | 
|  | &jersey.client.oauth2.OAuth2CodeGrantFlow;: API that allows to perform the | 
|  | authorization flow defined as Authorization Code Grant Flow in the OAuth 2 specification. | 
|  | Implementation of this interface is a | 
|  | class that is used as a standalone utility and is not part of the JAX-RS client. In | 
|  | other words, this is not a feature that should be registered into the client. | 
|  | </para> | 
|  | </listitem> | 
|  |  | 
|  | <listitem> | 
|  | <para> | 
|  | &jersey.client.oauth2.ClientIdentifier;: Identifier of the client issued by the Service | 
|  | Provider for the client. Similar to &jersey.client.oauth1.ConsumerCredentials; | 
|  | from OAuth 1 client support. | 
|  | </para> | 
|  | </listitem> | 
|  |  | 
|  | <listitem> | 
|  | <para> | 
|  | &jersey.client.oauth2.OAuth2Parameters;: Defines parameters that are used in requests | 
|  | during the authorization flow. These parameters can be used to override some of the | 
|  | parameters used in different authorization phases. | 
|  | </para> | 
|  | </listitem> | 
|  |  | 
|  | <listitem> | 
|  | <para> | 
|  | &jersey.client.oauth2.TokenResult;: | 
|  | Contains result of the authorization flow. One of the result values is the Access | 
|  | Token. It can additionally contain the expiration time of the Access Token and | 
|  | Refresh Token that can be used to get new Access Token. | 
|  | </para> | 
|  | </listitem> | 
|  | </itemizedlist> | 
|  | </para> | 
|  |  | 
|  | <para> | 
|  | The principle of performing the authorization flow with Jersey is similar to OAuth 1. | 
|  | Check the &jersey.github.oauth1.twitter.client.example.link; which utilizes Jersey client | 
|  | support for OAuth 2 to get Google Tasks of the user. The application is a web application | 
|  | that uses redirection to forward the user to the authorization URI. | 
|  | </para> | 
|  |  | 
|  | <para> | 
|  | The following code is an example of how to build and use OAuth 2 authorization flow. | 
|  |  | 
|  | <example> | 
|  | <title>Building OAuth 2 Authorization Flow.</title> | 
|  | <programlisting language="java" linenumbering="numbered"><![CDATA[OAuth2CodeGrantFlow.Builder builder = | 
|  | OAuth2ClientSupport.authorizationCodeGrantFlowBuilder(clientId, | 
|  | "https://example.com/oauth/authorization", | 
|  | "https://example.com/oauth/token"); | 
|  | OAuth2CodeGrantFlow flow = builder | 
|  | .property(OAuth2CodeGrantFlow.Phase.AUTHORIZATION, "readOnly", "true") | 
|  | .scope("contact") | 
|  | .build(); | 
|  | String authorizationUri = flow.start(); | 
|  |  | 
|  | // Here we must redirect the user to the authorizationUri | 
|  | // and let the user approve an access for our app. | 
|  |  | 
|  | ... | 
|  |  | 
|  | // We must handle redirection back to our web resource | 
|  | // and extract code and state from the request | 
|  | final TokenResult result = flow.finish(code, state); | 
|  | System.out.println("Access Token: " + result.get);]]></programlisting> | 
|  | </example> | 
|  |  | 
|  | In the code above we create an &lit.jersey.client.oauth2.OAuth2CodeGrantFlow; from an | 
|  | authorization URI and an access token URI. We have additionally set a | 
|  | <literal>readOnly</literal> parameter to <literal>true</literal> and assigned the parameter | 
|  | to the authorization phase. This is the way, how you can extend the standard flow with | 
|  | additional service provider-specific parameters. In this case, the <literal>readOnly=true</literal> | 
|  | parameter will be added as a query parameter to the authorization uri returned from the method | 
|  | <literal>flow.start()</literal>. | 
|  | If we would specify <literal>ACCESS_TOKEN_REQUEST</literal> as a phase, then the parameter | 
|  | would have been added to the request when <literal>flow.finish()</literal> | 
|  | is invoked. See javadocs for more information. The parameter <literal>readOnly</literal> | 
|  | is not part of the OAuth 2 specification and is used in the example | 
|  | for demonstration of how to configure the flow for needs of specific service providers (in this | 
|  | case, the <literal>readOnly</literal> | 
|  | param would be described in the service provider's documentation). | 
|  | </para> | 
|  | <para> | 
|  | Between the calls to <literal>flow.start()</literal> and <literal>flow.finish()</literal>, a user | 
|  | must be redirected to the authorization URI. This means that the code will not be executed in | 
|  | a single method and the finish part will be invoked as a handler of redirect request back to our web from | 
|  | authorization URI. <!--Check the &jersey.github.oauth2.google.client.example.link; for more details on | 
|  | this approach.--> | 
|  | </para> | 
|  | </section> | 
|  | </section> | 
|  | </section> | 
|  | </chapter> |