Resin 4.0 Security
With Resin 4.0’s WebBeans support, we can finally modularize and cleanup features like security, JMS, clustering and remoting. Since the WebBeans-style XML configuration selects a component based on package and classname, our XML configuration for security exactly matches our classes. For example, <sec:IfNetwork> is com.caucho.security.IfNetwork. Our JavaDoc can even serve as XML documentation and as Emil’s post shows, we can enable Eclipse to display those tags automatically.
JavaDoc is available for com.caucho.security, as well as documentation for Resin 4.0 security.
Since examples make configuration clearer, I’ve put together three typical security configurations:
- IP address protection: restricting admin pages to the local network
- Hiding pages from all browsers, like WEB-INF
- HTTP basic authentication for quick and dirty password protection
IP address protection
If I want to restrict /resin-admin to the local network, I can use an <sec:Allow> tag with a <sec:IfNetwork> tag to only allow my IP ranges. The configuration looks like the following:
<web-app xmlns="http://caucho.com/ns/resin"
xmlns:sec="urn:java:com.caucho.security">
<sec:Allow url-pattern="/admin/*">
<sec:IfNetwork>
<sec:value>127.0.0.1</sec:value>
<sec:value>192.168.0.0/16</sec:value>
</sec:IfNetwork>
</sec:Allow>
</web-app>
The xmlns:sec namespace points to com.caucho.security, the Resin package containing security configuration. Allow and IfNetwork are classes in the package.
After matching the url-pattern, <sec:Allow> checks all the predicates it contains, like <sec:IfNetwork>, and if all match it allows the request. (Otherwise, processing goes into a default-fail mode.)
Hiding URLs
Some URLs are meant to be hidden, like WEB-INF or META-INF or some configuration directories in PHP. I can use a <sec:Deny> tag to forbid access to any set of URLs.
<web-app xmlns="http://caucho.com/ns/resin"
xmlns:sec="urn:java:com.caucho.security">
<Deny>
<sec:url-pattern>/hidden/*</sec:url-pattern>
<sec:url-pattern>*.hidden<sec:url-pattern>
</Deny>
</web-app>
I’ve used two url-patterns to illustrate that <sec:Allow> and <sec:Deny> can match multiple URLs at once. You can even add http-method to restrict the methods that you’re protecting.
Resin’s security processing follows a first-match algorithm. The first <sec:Allow> allows the request, or if <sec:Deny> matches first, it denies the request. If the url-pattern and http-method match, but the predicates fail, Resin goes into default-fail mode for <sec:Allow> or default-allow mode for <sec:Deny>. If no other rules match, Resin will take the default.
HTTP Basic Authentication
If you want a simple login authorization for a quick and dirty project, you can use HTTP basic authentication and an XmlAuthenticator. Resin’s login is split into a Login class and an Authenticator. The Login is responsible for managing the HTTP security protocol: basic authentication, or password authentication, or multi-request protocols like digest. The Authenticator is responsible for checking passwords.
In this case, I’m using <sec:BasicLogin> because want skip writing extra JSP or PHP pages, and the <sec:XmlAuthenticator because I’m skipping the database for now.
<web-app xmlns="http://caucho.com/ns/resin"
xmlns:sec="urn:java:com.caucho.security">
<sec:Allow url-pattern="/secure/*">
<sec:IfRole name="*"/>
</sec:Allow>
<sec:BasicLogin/>
<sec:XmlAuthenticator>
<sec:user name="harry" password="uTOZTGaB6pooMDvqvl2Lbg==" group="user"/>
</sec:XmlAuthenticator>
</web-app>
As with all the WebBeans-style configuration, com.caucho.security.XmlAuthenticator is the actual class you’re configuring, so the JavaDoc itself can provide documentation.
The password is an MD5 hash of “harry:resin:quidditch” to secure the configuration file itself. The easiest way to generate it is with a trivial PHP script:
<?php
echo base64_encode(md5("harry:resin:quidditch", true)) . "\n";
Conclusions
I’m very happy with the new syntax and style of configuration. It lets us clean up our configuration by putting it into modules. Since all our security configuration is in xmlns:sec, it’s easier to scan the configuration file, and easier to find all the security capabilities, because they’re all in the com.caucho.security JavaDoc.
