A simple JAX-RS security context example in GlassFish

When creating a REST api with Java EE 6 and JAX-RS there comes the time when you start thinking about security. In our case we were trying to set up HTTP Basic Auth for the REST api to identify users and keep them from deleting other peoples stuff. It took me a while to understand the different aspects of configuring HTTP Basic Auth when using GlassFish:

  1. Use SecurityContext in your Java code to access the authentication information.
  2. To enable HTTP Basic Auth add a <security-constraint> section to your web.xml
  3. Map user roles to GlassFish groups by creating a sun-web.xml
  4. Configure a FileRealm / JDBCRealm in GlassFish to store user passwords

I will detail the steps with a simple deleteRating() example and xml snippets.

The REST bean

First, let me show you the current deleteRating() implementation:

import javax.ws.rs.DELETE;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;

public class RestBean {

    public Response deleteRating( @PathParam("id") int id ) {
        // code here: delete the rating, no matter what


Right, no security whatsoever. We need to change that!

Security annotations in the Java Code

To access the authentication information we have to add the @Context:

import javax.ws.rs.core.Context;
import javax.ws.rs.core.SecurityContext;

public Response deleteRating( @PathParam("id") int id, @Context SecurityContext context ) {
    String username = context.getUserPrincipal().getName();
    // code here: check if he is the owner of the rating
    // code here: deny the request or
    // code here: delete the rating

Using the SecurityContext we can get the authenticated username and start the authorization. So much for the easy part. On to xml configuration hell!

Security constrains in the web.xml

The SecurityContext remains useless until we add a <security-constraint> section to the web.xml. Eric Warriner has written up a tomcat example which leads to something like this:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>your service name</display-name>
    <servlet-name>Jersey REST Service</servlet-name>
    <!-- to use JSR 250 Role Based Authentication and annotations
         like @RolesAllowed uncomment the next init-param section -->
    <servlet-name>Jersey REST Service</servlet-name>

  <!-- which resources should be protected -->
      <!-- be specific about the urls and methods here -->
      <description>has to be a USER</description>

  <!-- which realm to use for basic auth -->

This would work in tomcat if a USERS role was defined in the tomcat-users.xml. For GlassFish we are not done yet…

Role mapping in the sun-web.xml

GlassFish uses principals and groups of a realm that have to be mapped to role names for the application.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-web-app PUBLIC '-//Sun Microsystems, Inc.//DTD
Application Server 9.0 Servlet 2.5//EN'

We are nearly done. Only one step left!

Setting up a GlassFish FileRealm

Open the admin console and navigate to Configuration -> Security -> Realms. Create a new security realm:

Name your_realm_name (use the one from your web.xml)
Class Name com.sun.enterprise.security.auth.realm.file.FileRealm
JAAS Context fileRealm (yep, a magic string)
Key File /path/to/users_and_passwords.xml

You can then add users to the realm which can be authenticated with HTTP Basic Auth as defined in the web.xml.

For a dynamic web application you may prefer to use the JDBCRealm, which is what we are going to set up next for nt2od.

, , , , , ,

About Jörn Dreyer

learned in a bank, studied business informatics, took the red pill and went down the rabbit hole of software engineering, working on my Ph.D.