TutorialsJoint

Form based Login Authentication in JavaEE7 with Wildfly and MySql

March 22, 2015

Learn to use Form based authentication in Java EE 7 with, Wildfly 8 and Mysql database. This is a kind of JAAS authentication provided in Java EE applications to ease the developer work.


Tools Used: Eclipse JavaEE – Juno, Wildfly 8.1.0, MYSQL

In this Tutorial we will be creating an Authentication and authorization module for JavaEE application. We will be doing FORM based authentication. Following is Index for the series up to now.

Series Index:

In the begenning we are presenting an overview of what we are going to do here. We have a web application backed by EJB+JPA, however this tutorial is not related to that, you can work it independently in your Web Application. We are working with MYSQL as DBMS software and using Wildfly Datasource to interact with it(To know how to create mysql datasource with wildfly follow this tutorial: MySql Datasource creation in Wildfly 8). Now we will perform Form based authentication using the database table at the backend. We will proceed in following steps:

  1. Create a security domain in Wildfly.
  2. Create security constraints in web.xml and configure it to use security domain.
  3. Create Login and Error Pages.

Creating Security Domain for Authorization and Authentication

We have already mentioned that we will be using a datasource created in earlier part of this series, once you have a datasource you can proceed to further steps. So now we are going to create a Security Domain. This can be done either using the text editor and editing the configuration file or by using the Administrator panel of wildfly. I am going to proceed in first way, by editing the configuration file.

We are using Wildfly 8.1 final, and running it in standalone mode, thus we have configuration file located on the path:
[wildfly-root]/standalone/configuration/standalone.xml
Open this file and search for the subsystem called “jboss:domain:security:x.y”(x.y) is the version number. This subsystem holds the security domains created in the system. Here we are going to create a new domain by the name of “school”, as in the example application we have been creating til now we are using the school scenario.

Use following code to create a new security-domain under this subsystem.

<security-domain name="school" cache-type="default">
<authentication>
<login-module code="Database" flag="required">
<module-option name="dsJndiName" value="java:jboss/datasources/school"/>
<module-option name="rolesQuery" value="SELECT role, 'Roles' FROM users WHERE username=?"/>
<module-option name="hashAlgorithm" value="MD5"/>
<module-option name="hashEncoding" value="hex"/>
<module-option name="principalsQuery" value="SELECT password from users WHERE username=?"/>
</login-module>
</authentication>
<authorization>
<policy-module code="Database" flag="required">
<module-option name="dsJndiName" value="java:jboss/datasources/school"/>
<module-option name="rolesQuery" value="SELECT role, 'Roles' FROM users WHERE username=?"/>
<module-option name="hashAlgorithm" value="MD5"/>
<module-option name="hashEncoding" value="hex"/>
<module-option name="principalsQuery" value="SELECT password from users WHERE username=?"/>
</policy-module>
</authorization>
</security-domain>

the database table we are using here is simple, following code is the result of “SHOW CREATE TABLE [table-name]” query for the table we are using.

CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(20) NOT NULL,
`password` tinytext NOT NULL,
`role` varchar(15) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `usrname` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1

NOTE: The little problem to know here is that we are focusing on both Authentication and Authorization both modules. When we are working with security. Most of the tutorials on internet only focus on Authentication part and in result user faces problem even after everything is alright. So just out of precaution that everything should proceed all right we are taking in account both Authorization and Authentication. The hashCode and hashAlgorithm used in our demonstration is using MD5 make sure the password in your database is hashed using this algorithm or you configure the application according to your needs. To know how to use hashAlgorithm in Java read this article: Using Encryption Algorithm In Java.

NOTE: The queries written here are in the syntax of MySql queries, you should write the queries in the syntax of whichever DBMS you are using.

Now we are telling about various parameters we are using in the domain.

Now our security domain is ready to use, just save the configuration file and restart the wildfly server. If you want to look how this configuration looks under the Administrator panel, follow these steps:

  1. Log in into admin panel.
  2. Go to configuration tab.
  3. Expand Subsystems > Security > Security Domains
  4. There will be a list of Security Domains available. Click on view for the domain you want to explore.

Admin Panel Security Domain

Creating and Configuring security constraints in web application

In your web application you need to configure the web.xml in order to use the security domain, this is a step by step process.

  1. Defining the security domain to be used in jboss-web.xml
  2. Define the security constraints.
  3. Define the type of Authentication process and configure it to use the security domain created in first step.
  4. Define the roles supported by the application.

First thing first, expand your web application and look for WEB-INF directory. In eclipse it is located at, ApplicationRoot > WebContent > WEB-INF. In this create an XML file called “jboss-web.xml” and specify the name of domain to be used.

<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
<security-domain>school</security-domain>
</jboss-web>

After that in the WEB-INF look for web.xml and open it for editing. We need to define security constraint, authentication mechanism and roles in there. The complete web.xml will look like this once we are done.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>DemoWeb</display-name>
<welcome-file-list>
<welcome-file>/pages/index.xhtml</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<!--Defining security constraint for type of roles available-->
<security-constraint>
<web-resource-collection>
<web-resource-name>administrator</web-resource-name>
<url-pattern>/pages/admin/*</url-pattern>
<http-method>POST</http-method>
<http-method>GET</http-method>
<http-method>PUT</http-method>
<http-method>DELETE</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>ADMINISTRATOR</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>user</web-resource-name>
<url-pattern>/pages/user/*</url-pattern>
<http-method>POST</http-method>
<http-method>GET</http-method>
<http-method>PUT</http-method>
<http-method>DELETE</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>ADMINISTRATOR</role-name>
<role-name>USER</role-name>
</auth-constraint>
</security-constraint>
<!--Defining security constraint for type of roles available-->
<!--Defining type of authenitcation mechanism-->
<login-config>
<auth-method>FORM</auth-method>
<realm-name>school</realm-name>
<form-login-config>
<form-login-page>/login.xhtml</form-login-page>
<form-error-page>/error.xhtml</form-error-page>
</form-login-config>
</login-config>
<!--Defining type of authenitcation mechanism-->
<!--Denining security role-->
<security-role>
<role-name>ADMINISTRATOR</role-name>
</security-role>
<security-role>
<role-name>USER</role-name>
</security-role>
<!--Denining security role-->
</web-app>

In the code above we are going to focus on three sections, viz: security-constraint, login-config and security-role. The first part is to define the constraint and which type of role is allowed to access that part of application. We define it as follows:

Security Constraint

Login Configuration

We are going to use the FORM based authentication thus, first a login form and error page is required. We have created the login.xhtml and error.xhtml in the WebContent directory. The key part of your login page is login form which is of following structure. And the error page, you can design to please yourself.

<form action="j_security_check" method="post" class="form-horizontal">
<div class="form-group">
<label class="control-label col-sm-2">Username:</label>
<div class="col-sm-10">
<input type="text" class="" name="j_username" placeholder="Username" />
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">Password:</label>
<div class="col-sm-10">
<input type="password" class="" name="j_password" placeholder="Password" />
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-primary">Login</button>
</div>
</div>
</form>

**NOTE:**The name of this file need not to be login.xhtml or error.xhtml, you can use whatever name you like. The classes in the code above are bootstrap classes, if you want to learn the use of bootstrap with JSF try this article: Applying Bootstrap to JSF based Web Application And to learn to create the template based application in JSF read this article: Template based View in JSF Web Application.

Once you have login form and error page ready, you can use them in the login-config sections as shown in web.xml code above.

Defining Roles

This is all now you shall be able to work out the application. Whenever a user will try to access the url which comes under a url pattern specified in security-constraint, the user will be prompted for the login to proceed.

Please leave your queries or correct us if we did something wrong somewhere.