Table of Contents
Security information is available by injecting a SecurityContext instance using @Context
annotation, that provides essentially the equivalent of the functionality available on
HttpServletRequest
API. The injected security context depends on the actual Jersey application deployment. For example, if a
Jersey application is deployed in a Servlet container, the Jersey SecurityContext
will return
information of the security context retrieved from Servlet request. For Jersey applications
deployed on a Grizzly server, the SecurityContext
will return information retrieved from the
Grizzly request.
SecurityContext
can be used in conjunction with sub-resource locators to return different
resources if the user principle is included in a certain role. For example, a sub-resource locator could return
a different resource if a user is a preferred customer:
Example 14.1. Accessing SecurityContext
@Path("basket") public ShoppingBasketResource get(@Context SecurityContext sc) { if (sc.isUserInRole("PreferredCustomer") { return new PreferredCustomerShoppingBasketResource(); } else { return new ShoppingBasketResource(); } }
SecurityContext
can be injected also to singleton resources and
providers as a class field. In such case the proxy of the request-scoped SecurityContext
will be injected.
Example 14.2. Injecting SecurityContext
into a singleton resource
@Path("resource") @Singleton public static class MyResource { @Context // Jersey will inject proxy of Security Context SecurityContext securityContext; @GET public String getUserPrincipal() { return securityContext.getUserPrincipal().getName(); } }
As described above, the SecurityContext
by default (if not overwritten by filters)
only offers information from an underlying container. In the case you deploy a Jersey application
in a Servlet container, you need to setup the <security-constraint>
,
<auth-constraint>
and user to roles mappings in order to pass correct information
to the SecurityContext
.
The SecurityContext
can be retrieved also from ContainerRequestContext via
getSecurityContext()
method. You can also set the SecurityContext
into
the request using method setSecurityContext(SecurityContext)
. If you set a
new SecurityContext
in the ContainerRequestFilter into the
ContainerRequestContext
, then this security context will be used for injections in resource
classes (wrapped into the proxy). This way you can implement a custom authentication filter that
may setup your own SecurityContext
to be used. To ensure the early execution of your custom
authentication request filter, set the filter priority to AUTHENTICATION
using
constants from Priorities. An early execution of you authentication filter will ensure that all
other filters, resources, resource methods and sub-resource locators will execute with your custom
SecurityContext
instance.
In cases where a Jersey application is deployed in a Servlet container you can rely only on
the standard Java EE Web application security mechanisms offered by the Servlet container and
configurable via application's web.xml
descriptor.
You need to define the <security-constraint>
elements in the
web.xml
and assign roles which are able to access these resources. You can also
define HTTP methods that are allowed to be executed. See the following example.
Example 14.3. Injecting SecurityContext
into singletons
<security-constraint> <web-resource-collection> <url-pattern>/rest/admin/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>admin</role-name> </auth-constraint> </security-constraint> <security-constraint> <web-resource-collection> <url-pattern>/rest/orders/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>customer</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>BASIC</auth-method> <realm-name>my-defaul-realm</realm-name> </login-config>
The example secures two kinds of URI namespaces using the HTTP Basic Authentication.
rest/admin/*
will be accessible only for user group "admin" and
rest/orders/*
will be accessible for "customer" user group. This security configuration
does not use JAX-RS or Jersey features at all as it is enforced by the Servlet container even before
a request reaches the Jersey application. Keeping this security constrains up to date with your JAX-RS
application might not be easy as whenever you change the @Path annotations on your resource classes
you may need to update also the web.xml
security configurations to reflect the changed
JAX-RS resource paths. Therefore Jersey offers a
more flexible solution based on placing standard Java EE
security annotations directly on JAX-RS resource classes and methods.
With Jersey you can define the access to resources based on the user group using annotations. You can for example define that only a user group "admin" can execute specific resource method. To do that you firstly need to register RolesAllowedDynamicFeature as a provider. The following example shows how to register the feature if your deployment is based on a ResourceConfig.
Example 14.4. Registering RolesAllowedDynamicFeature using ResourceConfig
final ResourceConfig resourceConfig = new ResourceConfig(MyResource.class); resourceConfig.register(RolesAllowedDynamicFeature.class);
Then you can use annotations from package javax.annotation.security
defined by JSR-250.
See the following example.
Example 14.5. Injecting SecurityContext
into singletons
@Path("/") @PermitAll public class Resource { @RolesAllowed("user") @GET public String get() { return "GET"; } @RolesAllowed("admin") @POST public String post(String content) { return content; } @Path("sub") public SubResource getSubResource() { return new SubResource(); } }
The resource class Resource
defined in the example is annotated with a
@PermitAll annotation. This means that all methods in the class which do not this
annotation will be permitted for all user groups (no restrictions are defined). In our example, the
annotation will only apply to the getSubResource()
method as it is the only method
that does not override the annotation by defining custom role-based security settings using the
@RolesAllowed annotation.
@RolesAllowed
annotation present on other methods defines a role or a set of roles
that are allowed to execute a particular method.
These Java EE security annotations are processed internally in the request filter registered using the
Jersey RolesAllowedDynamicFeature
. The roles defined in the annotations are tested against
current roles set in the SecurityContext
using
the SecurityContext
.isUserInRole(String role)
method. In case the caller
is not in the role specified by the annotation, the HTTP 404
error response is returned.
For details about client security please see the Client chapter. Jersey
client allows to define parameters of SSL communication using HTTPS
protocol.
You can also use jersey built-in authentication filter which performs HTTP Basic Authentication.
See the client chapter for more details.