<chapter id="Securing_JAX-RS_and_RESTeasy">
<title>Securing JAX-RS and RESTeasy</title>

<para>

Because Resteasy is deployed as a servlet, you must use standard web.xml constraints to enable authentication and authorization.  
</para>
<para>

Unfortunately, web.xml constraints do not mesh very well with JAX-RS in some situations.  The problem is that web.xml URL pattern matching is very very limited.  URL patterns in web.xml only support simple wildcards, so JAX-RS resources like:
</para>
<para>

<programlisting>/{pathparam1}/foo/bar/{pathparam2} </programlisting>
</para>
<para>

Cannot be mapped as a web.xml URL pattern like:
</para>
<para>

<programlisting>/*/foo/bar/*</programlisting>
</para>
<para>

To get around this problem you will need to use the security annotations defined below on your JAX-RS methods.  You will still need to set up some general security constraint elements in web.xml to turn on authentication.
</para>
<para>


</para>
<para>

Resteasy JAX-RS supports the @RolesAllowed, @PermitAll and @DenyAll annotations on JAX-RS methods.   By default though, Resteasy does not recognize these annotations.  You have to 
configure Resteasy to turn on role-based security by setting a context parameter.  NOTE!!!  Do not turn on this switch if you are using EJBs.  The EJB container will provide this
functionality instead of Resteasy.

</para>
<programlisting>
<![CDATA[
<web-app>
...
   <context-param>
      <param-name>resteasy.role.based.security</param-name>
      <param-value>true</param-value>
   </context-param>
</web-app>]]>
</programlisting>

<para>There is a bit of quirkiness with this approach.   You will have to declare all roles used within the Resteasy JAX-RS war file that you are using in your JAX-RS classes and set up a security constraint that permits all of these roles access to every URL handled by the JAX-RS runtime.  You'll just have to trust that Resteasy JAX-RS authorizes properly.
</para>
<para>

How does Resteasy do authorization?  Well, its really simple.  It just sees if a method is annotated with @RolesAllowed and then just does HttpServletRequest.isUserInRole.  If one of the @RolesAllowed passes, then allow the request, otherwise, a response is sent back with a 401 (Unauthorized) response code.
</para>
<para>

So, here's an example of a modified RESTEasy WAR file.  You'll notice that every role declared is allowed access to every URL controlled by the Resteasy servlet.
</para>
<para>

<programlisting>

&lt;web-app&gt;

   &lt;context-param&gt;
      &lt;param-name>resteasy.role.based.security&lt;/param-name&gt;
      &lt;param-value>true&lt;/param-value&gt;
   &lt;/context-param&gt;

   &lt;listener&gt;
      &lt;listener-class&gt;org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap&lt;/listener-class&gt;
   &lt;/listener&gt;

   &lt;servlet&gt;
      &lt;servlet-name&gt;Resteasy&lt;/servlet-name&gt;
      &lt;servlet-class&gt;org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher&lt;/servlet-class&gt;
   &lt;/servlet&gt;

   &lt;servlet-mapping&gt;
      &lt;servlet-name&gt;Resteasy&lt;/servlet-name&gt;
      &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
   &lt;/servlet-mapping&gt;

   &lt;security-constraint&gt;
      &lt;web-resource-collection&gt;
         &lt;web-resource-name&gt;Resteasy&lt;/web-resource-name&gt;
         &lt;url-pattern&gt;/security&lt;/url-pattern&gt;
      &lt;/web-resource-collection&gt;
       &lt;auth-constraint&gt;
         &lt;role-name&gt;admin&lt;/role-name&gt;
         &lt;role-name&gt;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;Test&lt;/realm-name&gt;
   &lt;/login-config&gt;

   &lt;security-role&gt;
      &lt;role-name&gt;admin&lt;/role-name&gt;
   &lt;/security-role&gt;
   &lt;security-role&gt;
      &lt;role-name&gt;user&lt;/role-name&gt;
   &lt;/security-role&gt;


&lt;/web-app&gt;


</programlisting>
</para>
<para>


</para>
</chapter>
