Using a Glassfish 4 JDBCRealm for basic user authorization

Glassfish offers a built-in security mechanism called Realms to secure your web application. In this tutorial, setting up your own JDBC Realm will be covered. This consists of the following steps:

  1. Preparing the database
  2. Configuring a JDBC resource in Glassfish
  3. Configuring a JDBC Realm in Glassfish
  4. Configuring your application

Prerequisites

  • MySQL database
  • Glassfish 4
  • Netbeans 8

Confirm that above are up and running before we start. I also recommend use of a SQL client.

Make sure you are in a Java EE project. I will be starting off with a stock Maven Web Application, called HelloSecurity. It is merely a hello-world where users need to sign in.


1 : Preparing the database

First off, you have to make sure that your database has the right tables for holding your user accounts. You can either use JPA entities or an SQL script to acquire this. You'll have to make 2 entities: one for the user, and one for the user group. Name them anything you want; just make sure their tables are NOT called 'User' and 'Group', since those are reserved SQL keywords.

@Entity
@Table(name = "HelloUser")
public class User implements Serializable 
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String userName;

    private String password;

    @ManyToMany(mappedBy = "users")
    private List<Group> groups;

    // getters, setters, no-arg constructor
}

@Entity
@Table(name = "HelloGroup")
public class Group implements Serializable
{
    @Id
    private String groupName;

    @ManyToMany
    @JoinTable(name="USER_GROUP",
    joinColumns = @JoinColumn(name = "groupName", 
        referencedColumnName = "groupName"), 
    inverseJoinColumns = @JoinColumn(name = "userName", 
        referencedColumnName = "userName"))
    private List<User> users;

    // getters, setters, no-arg constructor
}

To generate the tables, write some code which persists something to the database. (This is JPA default)
Make sure the tables are generated, as well as a join table. Take note of the name of this join table (USER_GROUP).

Secondly, add some users to your database. In the groups table, add a row with group name 'regulars'.

In the users table, add a user with name 'steve' and password 'f148389d080cfe85952998a8a367e2f7eaf35f2d72d2599a5b0412fe4094d65c'. This is the SHA-256 hashed version of 'steve'.

Lastly add a record to your join table with values 'regulars' and 'steve'.


2. Configuring a JDBC Resource in Glassfish

Start your glassfish server and find your way to the admin panel, which is usually at localhost:4848.

Next, you should create a JDBC connection pool for your database. You can find the JDBC resources at Resources>JDBC.

Create a JDBC connection pool with the following settings:

Within 'additional properties', add the following properties.
(of course, change the values to your database credentials!)

URL jdbc:mysql://localhost:3306/hellosecurity
user root
password root

Performance-wise, you can choose to set the 'Initial and minimum pool size' to 0, so your Glassfish will eat up less of your machine's resources. Rethink this when deploying to a production environment!

Lastly, create a JDBC resource with the following settings:

Thats it for configuring the JDBC resource!


3. Configuring a JDBC Realm in Glassfish

To configure your security realm, go to Configuration> server-config>Security>Realms.

Add a new realm, and give a name to it. For this tutorial, call it security_realm. For 'Class Name', use com.sun.enterprise.security.auth.realm.jdbc.JDBCRealm.

A form should pop up for this Realm's properties.
Fill in as follows:

JAAS Context jdbcRealm
JNDI security_resource
User Table HELLOUSER
Password Column PASSWORD
Group Table USER_GROUP
Goup Table Username Column USERNAME
Goup Name Column GROUPNAME
Password Encryption Algorithm AES
Digest Algorithm SHA-256
Charset UTF-8

Check and make sure the table and column names you filled in are the same as in the Database; Glassfish will not give error messages if these are wrong.

We're almost done here. Lastly, go to the 'Security' page in Glassfish, and make sure the following property is checked:

Default Principal to Role mapping : Enabled


4: Configuring your application

The last step is to configure your project for using the Realm. In your web.xml you should set some properties.
If you don't have a web.xml, you can generate it from New>Standard Deployment Descriptor.

Add the following snippet:

<login-config>
        <auth-method>BASIC</auth-method>
        <realm-name>security_realm</realm-name>
</login-config>

For the sake of simplicity, we'll be using the BASIC authorization method, which is a standard login form within the browser. If you want to make your own login forms, you can use the method FORM. We won't cover this for now.

Also, you have to add security constraints. Security constraints make sure only certain users can acces certain pages. For now, lock every page (/*)behind the regular_user role that we created. We do this by adding the following snippet:

<security-constraint>
        <web-resource-collection>
            <web-resource-name>Secure Pages</web-resource-name>
            <description/>
            <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>regular_role</role-name>
        </auth-constraint>
</security-constraint> 

Take note of the role-name, regular_user. We will need it in the next step.

Open your glassfish deployment descriptor. It is called sun-web.xml or glassfish-web.xml and should be in your WEB-INF folder. If not, (in NetBeans 8) right-click this folder and go to New> Glassfish descriptor.

In this descriptor, roles within your application are mapped to certain groups in your database. Add the following snippet:

<security-role-mapping>
    <role-name>regular_role</role-name>
    <group-name>regulars</group-name>
</security-role-mapping>

And make sure the group-name is exactly the same as in your database.


That's it!

Go ahead and test it out. Run your project, and the website should ask you to sign in. Fill in 'steve' and 'steve' for both username and password, and have fun!

You can find the source code of this tutorial on my github.


A note about security

Think thoroughly about securing your (web) applications.

While Realms might be able to secure a your application to a certain extent, I don't agree with the act of leaving the responsibility blindly with a container, such as Glassfish.

Realms are okay for basic user authorization. To ensure a truly secure application, take more actions!