blob: 1f0a0514dbf73d2a5c4cc1f816c0321a9347f42b [file] [log] [blame]
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title xmlns:d="http://docbook.org/ns/docbook">Chapter&nbsp;5.&nbsp;Adding BASIC Authentication</title><link rel="stylesheet" type="text/css" href="css/cayenne-doc.css"><meta xmlns:d="http://docbook.org/ns/docbook" name="keywords" content="Cayenne 3.1 documentation"><meta xmlns:d="http://docbook.org/ns/docbook" name="description" content="User documentation for Apache Cayenne version 3.1"><link rel="home" href="index.html" title="Getting Started with Cayenne ROP (Remote Object Persistence)"><link rel="up" href="getting-started-rop-part2.html" title="Part&nbsp;II.&nbsp;Remote Object Persistence Quick Start"><link rel="prev" href="ch04.html" title="Chapter&nbsp;4.&nbsp;Porting Existing Code to Connect to a Web Service Instead of a Database"><script xmlns:d="http://docbook.org/ns/docbook" type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-7036673-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div xmlns:d="http://docbook.org/ns/docbook" class="navheader"><table width="100%" summary="Navigation header"><tr><th class="versioninfo">v.3.1 (3.1)</th><th align="center">Chapter&nbsp;5.&nbsp;Adding BASIC Authentication</th><th></th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch04.html">Prev</a>&nbsp;</td><th width="60%" align="center"><a accesskey="u" href="getting-started-rop-part2.html">Part&nbsp;II.&nbsp;Remote Object Persistence Quick Start</a></th><td width="20%" align="right">&nbsp;</td></tr></table><hr></div><div class="chapter" title="Chapter&nbsp;5.&nbsp;Adding BASIC Authentication"><div class="titlepage"><div><div><h2 class="title"><a name="d0e198"></a>Chapter&nbsp;5.&nbsp;Adding BASIC Authentication</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="ch05.html#securing-rop-server-app">Securing ROP Server Application</a></span></dt><dt><span class="section"><a href="ch05.html#configuring-jetty">Configuring Jetty for BASIC Authentication</a></span></dt><dt><span class="section"><a href="ch05.html#running-client">Running Client with Basic Authentication</a></span></dt></dl></div><p>You probably don't want everybody in the world to connect to your service and access (and
update!) arbitrary data in the database. The first step in securing Cayenne service is
implementing client authentication. The easiest way to do it is to delegate the
authentication task to the web container that is running the service. HessianConnection used
in the previous chapter supports BASIC authentication on the client side, so we'll
demonstrate how to set it up here.</p><div class="section" title="Securing ROP Server Application"><div class="titlepage"><div><div><h2 class="title"><a name="securing-rop-server-app"></a>Securing ROP Server Application</h2></div></div></div><p>Open web.xml file in the server project and setup security constraints with BASIC
authentication for the ROP service:</p><pre class="programlisting">&lt;security-constraint&gt;
&lt;web-resource-collection&gt;
&lt;web-resource-name&gt;CayenneService&lt;/web-resource-name&gt;
&lt;url-pattern&gt;/cayenne-service&lt;/url-pattern&gt;
&lt;/web-resource-collection&gt;
&lt;auth-constraint&gt;
&lt;role-name&gt;cayenne-service-user&lt;/role-name&gt;
&lt;/auth-constraint&gt;
&lt;/security-constraint&gt;
&lt;login-config&gt;
&lt;auth-method&gt;BASIC&lt;/auth-method&gt;
&lt;realm-name&gt;Cayenne Realm&lt;/realm-name&gt;
&lt;/login-config&gt;
&lt;security-role&gt;
&lt;role-name&gt;cayenne-service-user&lt;/role-name&gt;
&lt;/security-role&gt;</pre></div><div class="section" title="Configuring Jetty for BASIC Authentication"><div class="titlepage"><div><div><h2 class="title"><a name="configuring-jetty"></a>Configuring Jetty for BASIC Authentication</h2></div></div></div><p>
</p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>These instructions are specific to Jetty 6. Other
containers (and versions of Jetty) will have different mechansims to achieve
the same thing.</p></div><p>
</p><p>Open pom.xml in the server project and configure a "userRealm" for the Jetty
plugin:</p><pre class="programlisting">&lt;plugin&gt;
&lt;groupId&gt;org.mortbay.jetty&lt;/groupId&gt;
&lt;artifactId&gt;maven-jetty-plugin&lt;/artifactId&gt;
&lt;version&gt;6.1.22&lt;/version&gt;
&lt;!-- adding configuration below: --&gt;
&lt;configuration&gt;
&lt;userRealms&gt;
&lt;userRealm implementation="org.mortbay.jetty.security.HashUserRealm"&gt;
&lt;!-- this name must match the realm-name in web.xml --&gt;
&lt;name&gt;Cayenne Realm&lt;/name&gt;
&lt;config&gt;realm.properties&lt;/config&gt;
&lt;/userRealm&gt;
&lt;/userRealms&gt;
&lt;/configuration&gt;
&lt;/plugin&gt;
&lt;/plugins&gt;</pre><p>Now create a new file called {["realm.properties"}} <span class="italic">at the
root of the server project</span> and put user login/password in there:</p><pre class="programlisting">cayenne-user: secret,cayenne-service-user</pre><p>.</p><p>Now let's stop the server and start it again. Everything should start as before, but
if you go to <span class="italic">http://localhost:8080/tutorial/cayenne-service</span>, your browser should pop
up authentication dialog. Enter "<span class="italic">cayenne-user/secret</span>"
for user name / password, and you should see "<span class="italic">Hessian Requires
POST</span>" message. So the server is now secured.</p></div><div class="section" title="Running Client with Basic Authentication"><div class="titlepage"><div><div><h2 class="title"><a name="running-client"></a>Running Client with Basic Authentication</h2></div></div></div><p>If you run the client without any changes, you'll get the following error:</p><pre class="programlisting">org.apache.cayenne.remote.hessian.HessianConnection connect
INFO: Connecting to [http:<span xmlns="http://www.w3.org/1999/xhtml" class="hl-comment">//localhost:8080/tutorial/cayenne-service] - dedicated session.</span>
org.apache.cayenne.remote.hessian.HessianConnection connect
INFO: Error establishing remote session. URL - http:<span xmlns="http://www.w3.org/1999/xhtml" class="hl-comment">//localhost:8080/tutorial/cayenne-service; </span>
CAUSE - cannot retry due to server authentication, in streaming mode
java.net.HttpRetryException: cannot retry due to server authentication, in streaming mode
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:<span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">1257</span>)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:<span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">379</span>)
at com.caucho.hessian.client.HessianProxy.invoke(HessianProxy.java:<span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">168</span>)
at $Proxy0.establishSession(Unknown Source)
at org.apache.cayenne.remote.hessian.HessianConnection.connect(HessianConnection.java:<span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">210</span>)
at org.apache.cayenne.remote.hessian.HessianConnection.getServerEventBridge(HessianConnection.java:<span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">114</span>)
at org.apache.cayenne.remote.ClientChannel.setupRemoteChannelListener(ClientChannel.java:<span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">337</span>)
at org.apache.cayenne.remote.ClientChannel.&lt;init&gt;(ClientChannel.java:<span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">108</span>)
at org.example.cayenne.Main.main(Main.java:<span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">25</span>)
Exception in thread <span xmlns="http://www.w3.org/1999/xhtml" class="hl-string">"main"</span> org.apache.cayenne.CayenneRuntimeException: [v.3.1M3 Sep <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">19</span> <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">2011</span> <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">07</span>:<span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">12</span>:<span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">41</span>]
Error establishing remote session. URL - http:<span xmlns="http://www.w3.org/1999/xhtml" class="hl-comment">//localhost:8080/tutorial/cayenne-service; </span>
CAUSE - cannot retry due to server authentication, in streaming mode
at org.apache.cayenne.remote.hessian.HessianConnection.connect(HessianConnection.java:<span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">229</span>)
at org.apache.cayenne.remote.hessian.HessianConnection.getServerEventBridge(HessianConnection.java:<span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">114</span>)
at org.apache.cayenne.remote.ClientChannel.setupRemoteChannelListener(ClientChannel.java:<span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">337</span>)
at org.apache.cayenne.remote.ClientChannel.&lt;init&gt;(ClientChannel.java:<span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">108</span>)
at org.example.cayenne.Main.main(Main.java:<span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">25</span>)
Caused by: java.net.HttpRetryException: cannot retry due to server authentication, in streaming mode
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:<span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">1257</span>)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:<span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">379</span>)
at com.caucho.hessian.client.HessianProxy.invoke(HessianProxy.java:<span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">168</span>)
at $Proxy0.establishSession(Unknown Source)
at org.apache.cayenne.remote.hessian.HessianConnection.connect(HessianConnection.java:<span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">210</span>)
... <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">4</span> more</pre><p>Which is exactly what you'd expect, as the client is not authenticating itself. So
change the line in Main.java where we obtained an ROP connection to this:</p><pre class="programlisting">ClientConnection connection = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword">new</span> HessianConnection(
<span xmlns="http://www.w3.org/1999/xhtml" class="hl-string">"http://localhost:8080/tutorial/cayenne-service"</span>,
<span xmlns="http://www.w3.org/1999/xhtml" class="hl-string">"cayenne-user"</span>, <span xmlns="http://www.w3.org/1999/xhtml" class="hl-string">"secret"</span>, null);</pre><p>Try running again, and everything should work as before. Obviously in production
environment, in addition to authentication you'll need to use HTTPS to access the server
to prevent third-party evesdropping on your password and data.</p><p>Congratulations, you are done with the ROP tutorial!</p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch04.html">Prev</a>&nbsp;</td><td width="20%" align="center"><a accesskey="u" href="getting-started-rop-part2.html">Up</a></td><td width="40%" align="right">&nbsp;</td></tr><tr><td width="40%" align="left" valign="top">Chapter&nbsp;4.&nbsp;Porting Existing Code to Connect to a Web Service Instead of a Database&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">&nbsp;</td></tr></table></div></body></html>