Chapter 33. Securing JAX-RS and RESTeasy
Because RESTEasy is deployed as a Servlet, you must use standard
web.xml
constraints to enable authentication and authorization.
Unfortunately,
web.xml
constraints have limited compatibility with JAX-RS because of the limited URL pattern matching available in web.xml
. URL patterns in web.xml
support only simple wildcards, so JAX-RS resources like the following:
/{pathparam1}/foo/bar/{pathparam2}
Cannot be mapped as a
web.xml
URL pattern such as:
/*/foo/bar/*
To work around this problem, use the following security annotations on your JAX-RS methods. You must also set up some general security constraint elements in
web.xml
to enable authentication.
RESTEasy JAX-RS supports the
@RolesAllowed
, @PermitAll
and @DenyAll
annotations on JAX-RS methods. By default, RESTEasy does not recognize these annotations. You must configure RESTEasy to enable role-based security by setting a context parameter, like so:
Note
Do not enable this if you are using EJBs. The EJB container will provide this function instead of RESTEasy.
<web-app> ... <context-param> <context-name>resteasy.role.based.security</context-name> <context-value>true</context-value> </context-param> </web-app>
With this approach, you must declare all roles used within both the RESTEasy JAX-RS
WAR
file, and in your JAX-RS classes, and establish a security constraint that lets these roles access every URL handled by the JAX-RS runtime, assuming that RESTEasy authorizes correctly.
RESTEasy authorization checks if a method is annotated with
@RolesAllowed
and then performs HttpServletRequest.isUserInRole
. If one of the the @RolesAllowed
passes, the request is allowed. If not, a response is returned with a 401
(Unauthorized) response code.
The following is an example of a modified RESTEasy WAR file. Note that every role declared is allowed access to every URL controlled by the RESTEasy Servlet.
<web-app> <context-param> <context-name>resteasy.role.based.security</context-name> <context-value>true</context-value> </context-param> <listener> <listener-class>org.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class> </listener> <servlet> <servlet-name>Resteasy</servlet-name> <servlet-class>org.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class> </servlet> <servlet-mapping> <servlet-name>Resteasy</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> <security-constraint> <web-resource-collection> <web-resource-name>Resteasy</web-resource-name> <url-pattern>/security</url-pattern> </web-resource-collection> <auth-constraint> <role-name>admin</role-name> <role-name>user</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>BASIC</auth-method> <realm-name>Test</realm-name> </login-config> <security-role> <role-name>admin</role-name> </security-role> <security-role> <role-name>user</role-name> </security-role> </web-app>