Security Interceptor for custom authorization

Not being satisfied with Nic's security solution (Securing Stripes With ACLs), I've created an interceptor that poses less restrictions on a security solution. Its main characteristics:
    (lightbulb) Allows a SecurityManager full decision rights
    (lightbulb) Provides a JSP tag to check if an action will be allowed
    (lightbulb) Plays nice with annotations like @DontBind and @DontValidate
    (lightbulb) Doesn't break when auto-included via the configuration property Extension.Packages

Use standards to your advantage

The security interceptor only protects events on action beans. It happily works together with both the J2EE container and custom solutions, which you can use to authenticate users and protect non-Stripes resources.

To use this interceptor, you will need to do the following:

  1. Download the StripesStuff library; it contains the plugin. There is also a subversion repository in case you need/want it.
  2. Update web.xml to tell the Stripes filter to use it, and specify which security manager to use
  3. Annotate your action beans

Configuring the interceptor in web.xml

The update to web.xml looks something like this:

Excerpt from web.xml
 
<filter> 
<display-name>Stripes Filter</display-name> 
<filter-name>StripesFilter</filter-name> 
<filter-class>net.sourceforge.stripes.controller.StripesFilter</filter-class> 
<init-param> 
<param-name>Extension.Packages</param-name> 
<param-value>org.stripesstuff.plugin.security</param-value> 
</init-param> 
<init-param> 
<param-name>SecurityManager.Class</param-name> 
<param-value>org.stripesstuff.plugin.security.J2EESecurityManager</param-value> 
</init-param> 
</filter> 

The provided example adds the security interceptor, and configures it to use the example J2EE security manager. If you omit this parameter, the interceptor will do nothing.

The security manager

Now you can start using your security manager. How this works depends on the security manager. For example, the security manager provided in the example uses the J2EE annotations @DenyAll, @PermitAll and @RolesAllowed to determine if access is allowed, just like you'd secure method calls to EJB's. It works in any J2EE compliant application server (tested with JBoss 4.2.2GA). The newest version also works with Tomcat and TopLink/Hibernate/... (tested with Tomcat 5.5.26 and Hibernate's EJB3 implementation). The latter is possible because the .jar file contains the security annotations as well.

You can also implement your own security manager, for example to implement authorizations that depend on data (instance based authorization). To do so, you must:

  1. implement the interface org.stripesstuff.plugin.security.SecurityManager to make security decisions,
  2. optionally implement the interface org.stripesstuff.plugin.security.SecurityHandler to decide what to do when authorization fails, and
  3. name your security manager as SecurityManager.Class in the Stripes Filter.

On how to setup security authorization/authentication for org.stripesstuff.plugin.security.J2EESecurityManager, see the Servlet spec 2.4 and your servlet container documentation.

Using the security manager in JSP's

Finally, you can use the supplied JSP tags to only show content on your page when an action is (or is not) allowed according to the security manager:

Example JSP
 
<%@ page contentType="text/html;charset=UTF-8" language="java" %> 
<%@ taglib prefix="stripes" uri="http://stripes.sourceforge.net/stripes.tld"%> 
<%-- The following definition works for Stripes 1.5 --%> 
<%@ prefix="security" taglib uri="http://www.stripes-stuff.org/security.tld" %> 
<%-- The following definition works for Stripes 1.4 (it's now commented out) --%> 
<%--@ prefix="security" taglib uri="http://stripes.sourceforge.net/security.tld" --%> 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html> 
<head><title>Security example</title></head> 
<body> 
<h1>Stripes Security Example</h1> 

<stripes:form action="/examples/quickstart/Calculator.action">

<security:allowed> 
This content is shown if the default event on the action bean "actionBean" is allowed. 
</security:allowed> 

<stripes:useActionBean var="myBean" beanclass="my.package.SomeClass"> 
<security:allowed bean="myBean" event="doSomething"> 
This content is shown if the event "doSomething" on the action bean "myBean" is allowed. 
</security:allowed> 

<stripes:useActionBean var="myBean" beanclass="my.package.SomeClass"> 
<security:notAllowed bean="myBean"> 
This content is shown if the default event on the action bean "myBean" is NOT allowed. 
Thanks to Fred Daoud, who noted that this would be easier than the (now deprecated) negate="true" attribute 
on the allowed tag. 
</security:notAllowed> 

</stripes:form> 
</body> 
</html> 

Oscar