<?xml version="1.0" encoding="UTF-8"?>
<!--<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
                         "http://www.docbook.org/xml/4.4/docbookx.dtd">-->
<chapter id="Authentication">
    <title>Authentication</title>
    <para>Since Resteasy runs within a servlet container you can use most (all?) mechanism available in your servlet container for authentication.  Basic and Digest
    authentication are probably the easiest to set up and fit nicely into REST's stateless principle.  Form security can be used, but requires passing
    the session's cookie value with each request.  We have done some preliminary work on OAuth and also plan to work on OpenID and SAML integration in the future.</para>
    <section>
    	<title>OAuth core 1.0a</title>
    	<para>
    		RESTEasy has preliminary support for <ulink url="http://oauth.net/core/1.0a">OAuth core 1.0a</ulink>.
    		This includes support for authenticating with OAuth (as described by the <ulink url="http://oauth.net/core/1.0a#rfc.section.6">spec section 6</ulink>)
    		and OAuth authentication for protected resources (as described by the <ulink url="http://oauth.net/core/1.0a#rfc.section.7">spec section 7</ulink>).
    	</para>
    	<important>
    		<para>
    			This API is deprecated and will be removed in subsequent versions of Resteasy unless there is an outcry from the community.
                We're focusing on OAuth 2.0 protocols.  Please see our <link linkend='oauth2'>OAuth 2.0 Work</link>.
    		</para>
    	</important>
    	<section>
    		<title>Authenticating with OAuth 1.0a</title>
    		<para>
				OAuth authentication is the process in which Users grant access to their Protected Resources without sharing their credentials with the Consumer.
			</para>
			<para>
				OAuth Authentication is done in three steps:
			</para>
			<orderedlist>
				<listitem>
					<para>
						The Consumer obtains an unauthorized Request Token. This part is handled by RESTEasy.
					</para>
				</listitem>
				<listitem>
					<para>
					The User authorizes the Request Token. This part is <emphasis>not handled by RESTEasy</emphasis> because it requires a user interface where the User
					logs in and authorizes or denies the Request Token. This cannot be implemented automatically as it needs to be integrated with your User login process
					and user interface.
					</para>
				</listitem>
				<listitem>
					<para>
					The Consumer exchanges the Request Token for an Access Token. This part is handled by RESTEasy. 
					</para>
				</listitem>
			</orderedlist>
			<para>
				In order for RESTEasy to provide the two URL endpoints where the Client will request unauthorized Request Tokens and exchange authorized Request Tokens
				for Access Tokens, you need to enable the OAuthServlet in your web.xml:
			</para>
			<programlisting language="xml">
				<![CDATA[
<!-- The OAuth Servlet handles token exchange -->
<servlet>
  <servlet-name>OAuth</servlet-name>
  <servlet-class>org.jboss.RESTEasy.auth.oauth.OAuthServlet</servlet-class>
</servlet>

<!-- This will be the base for the token exchange endpoint URL -->
<servlet-mapping>
  <servlet-name>OAuth</servlet-name>
  <url-pattern>/oauth/*</url-pattern>
</servlet-mapping>
				]]>
			</programlisting>
			<para>
				The following configuration options are available using <code>&lt;context-param&gt; elements</code>:
			</para>
			<table>
				<caption>OAuth 1.0a Servlet options</caption>
				<thead>
					<tr>
						<th>Option Name</th>
						<th>Default</th>
						<th>Description</th>
					</tr>
				</thead>
				<tbody>
					<tr>
						<td>oauth.provider.provider-class</td>
						<td>*Required*</td>
						<td>Defines the fully-qualified class name of your OAuthProvider implementation</td>
					</tr>
					<tr>
						<td>oauth.provider.tokens.request</td>
						<td>/requestToken</td>
						<td>This defines the endpoint URL for requesting unauthorized Request Tokens</td>
					</tr>
					<tr>
						<td>oauth.provider.tokens.access</td>
						<td>/accessToken</td>
						<td>This defines the endpoint URL for exchanging authorized Request Tokens for Access Tokens</td>
					</tr>
				</tbody>
			</table>
		</section>
    	<section>
    		<title>Accessing protected resources</title>
    		<para>
				After successfully receiving the Access Token and Token Secret, the Consumer is able to access the Protected Resources on behalf of the User.
			</para>
			<para>
				RESTEasy supports OAuth authentication for protected resources using a servlet filter which should be mapped in your web.xml for all
				protected resources:
			</para>
			<programlisting language="xml">
				<![CDATA[
<!-- The OAuth Filter handles authentication for protected resources -->
<filter>
  <filter-name>OAuth Filter</filter-name>
  <filter-class>org.jboss.RESTEasy.auth.oauth.OAuthFilter</filter-class>
</filter>
	
<!-- This defines the URLs which should require OAuth authentication for your protected resources -->
<filter-mapping>
  <filter-name>OAuth Filter</filter-name>
  <url-pattern>/rest/*</url-pattern>
</filter-mapping>
				]]>
			</programlisting>
			<para>
				The following configuration options are available using <code>&lt;context-param&gt; elements</code>:
			</para>
			<table>
				<caption>OAuth Filter options</caption>
				<thead>
					<tr>
						<th>Option Name</th>
						<th>Default</th>
						<th>Description</th>
					</tr>
				</thead>
				<tbody>
					<tr>
						<td>oauth.provider.provider-class</td>
						<td>*Required*</td>
						<td>Defines the fully-qualified class name of your OAuthProvider implementation</td>
					</tr>
				</tbody>
			</table>
			<para>
				Once authenticated, the OAuth Servlet Filter will set your request's Principal and Roles, which can then be
				accessed using the JAX-RS SecurityContext. You can also protect your resources using Roles as described in the section "Securing JAX-RS and RESTEasy".
			</para>
		</section>
		<section>
			<title>Implementing an OAuthProvider</title>
			<para>
				In order for RESTEasy to implement OAuth it needs you to provide an instance of <code>OAuthProvider</code> which
				will provide access to the list of Consumer, Request and Access Tokens. Because one size doesn’t fit all we cannot
				know if you wish to store your Tokens and Consumer credentials in a configuration file, in memory, or on persistent storage.
			</para>
			<para>
				All you need to do is implement the <code>OAuthProvider</code> interface:
			</para>
			<programlisting>
<![CDATA[
public interface OAuthProvider {
	String getRealm();

	OAuthConsumer getConsumer(String consumerKey)throws OAuthException;
	OAuthToken getRequestToken(String consumerKey, String requestToken) throws OAuthException;
	OAuthToken getAccessToken(String consumerKey, String accessToken) throws OAuthException;
	
	OAuthToken makeRequestToken(String consumerKey, String callback) throws OAuthException;
	OAuthToken makeAccessToken(String consumerKey, String requestToken, String verifier) throws OAuthException;

	String authoriseRequestToken(String consumerKey, String requestToken) throws OAuthException;

	void checkTimestamp(OAuthToken token, long timestamp) throws OAuthException;
}
]]>
			</programlisting>
			<para>
				If a Consumer Key, or Token doesn’t exist, or if the timestamp is not valid,
				simply throw an <code>OAuthException</code>.
			</para>
			<para>
				The rest of the interfaces used in <code>OAuthProvider</code> are:
			</para>
			<programlisting>
<![CDATA[
public interface OAuthConsumer {
	String getKey();
	String getSecret();
}

public interface OAuthToken {
	OAuthConsumer getConsumer();
	String getToken();
	String getSecret();
	Principal getPrincipal();
	Set<String> getRoles();
}
]]>
			</programlisting>
	    </section>
	</section>
</chapter>
