| <html><head> |
| <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> |
| <title xmlns:d="http://docbook.org/ns/docbook">Chapter 5. 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 II. Remote Object Persistence Quick Start"><link rel="prev" href="ch04.html" title="Chapter 4. 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 5. Adding BASIC Authentication</th><th></th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch04.html">Prev</a> </td><th width="60%" align="center"><a accesskey="u" href="getting-started-rop-part2.html">Part II. Remote Object Persistence Quick Start</a></th><td width="20%" align="right"> </td></tr></table><hr></div><div class="chapter" title="Chapter 5. Adding BASIC Authentication"><div class="titlepage"><div><div><h2 class="title"><a name="d0e198"></a>Chapter 5. 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"><security-constraint> |
| <web-resource-collection> |
| <web-resource-name>CayenneService</web-resource-name> |
| <url-pattern>/cayenne-service</url-pattern> |
| </web-resource-collection> |
| <auth-constraint> |
| <role-name>cayenne-service-user</role-name> |
| </auth-constraint> |
| </security-constraint> |
| |
| <login-config> |
| <auth-method>BASIC</auth-method> |
| <realm-name>Cayenne Realm</realm-name> |
| </login-config> |
| |
| <security-role> |
| <role-name>cayenne-service-user</role-name> |
| </security-role></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"><plugin> |
| <groupId>org.mortbay.jetty</groupId> |
| <artifactId>maven-jetty-plugin</artifactId> |
| <version>6.1.22</version> |
| <!-- adding configuration below: --> |
| <configuration> |
| <userRealms> |
| <userRealm implementation="org.mortbay.jetty.security.HashUserRealm"> |
| <!-- this name must match the realm-name in web.xml --> |
| <name>Cayenne Realm</name> |
| <config>realm.properties</config> |
| </userRealm> |
| </userRealms> |
| </configuration> |
| </plugin> |
| </plugins></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.<init>(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.<init>(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> </td><td width="20%" align="center"><a accesskey="u" href="getting-started-rop-part2.html">Up</a></td><td width="40%" align="right"> </td></tr><tr><td width="40%" align="left" valign="top">Chapter 4. Porting Existing Code to Connect to a Web Service Instead of a Database </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> </td></tr></table></div></body></html> |