jsf

JSF Authentication Example

In our previous example we have learned how to create a sample JSF-HelloWorld application. This article will focus on creating a simple login application using the authentication mechanism and will demonstrate the following.

  • How can we navigate from one page to another?
  • Sending and retrieving data to and from a managed bean and using the same in another page.

 
 
 
 

1. Introduction

Authentication mechanism allows users to have secure access to the application by validating the username and password. We will have following components in our login application

  • LoginBean.java – Managed bean
  • index.xhtml – Contains the login form with JSF components
  • success.xhtml – If the login is successful, it will show the logged in username
  • failure.xhtml – If user credentials are invalid error page will be shown
  • faces-config.xml – It’s the JSF configuration file where the success & failure navigation rule will be set
  • web.xml – Web application configuration file

But before we create the sample authentication application let’s briefly understand the authentication mechanism in JSF.

The below example shows how to use form-based authentication with a Java Server Faces application. With a form-based application, we can customize the login & error pages that are shown to the client for authentication of the username and password. When a user submits his/her credentials, the server will check whether the user’s credentials are authorized or not. If the user is successfully authenticated, he will be shown the success page or else the error/failure page.

When using the form-based authentication, we specify a page that contains the form for obtaining the username and password. Here is the sample code for this page.

<h:outputLabel value="Username: " />
<h:inputText value="#{loginBean.userName}" />
		
<h:outputLabel value="Password: " />
<h:inputSecret value="#{loginBean.password}" />

<h:commandButton value="Login" action="#{loginBean.validateUserLogin}" />

The entered credentials will be authenticated by the server and if the user is authorized, he/she will be shown the success page with a welcome message else the failure page with an error message.

This example is based on the JSF method binding approach where the entered credentials will be authenticated against the managed-bean and the user will be shown the expected result based on the navigation rules defined in the JSF configuration.

1.1 JSF Navigation Rule

In simple language, page navigation means the flow of the application from one page to another page. Navigation in JSF defines the set of rules for choosing the next view to be displayed after a specified action is completed.

In JSF, navigation between pages is defined by a set of rules. These rules determine which next page to be displayed depending upon a user clicking a navigation component (such as a button or a hyperlink) or when the navigation is based on the form-based authentication. These navigation rules are defined in JSF configuration file namely faces-config.xml

1.1.1 How to Create Page Navigation Rules

Navigation rule definitions are stored in the JSF configuration file. The general syntax of a JSF navigation rule element in the faces-config.xml file is shown below:

<navigation-rule>
  <from-view-id>page-or-pattern</from-view-id>
  <navigation-case>
    	<from-outcome>outcome</from-outcome>
    	<to-view-id>destination-page</to-view-id>
  </navigation-case>
  <navigation-case>
   		...
  </navigation-case>
</navigation-rule>

A navigation rule can consist of the following elements –

  • navigation-rule: A mandatory element for navigation case elements.
  • from-view-id: An optional element that contains either a complete page identifier or a page identifier prefix ending with the asterisk (*) character. If we use the wildcard character, the rule applies to all pages that match the wildcard pattern. To make a global rule that applies to all pages, leave this element blank.
  • navigation-case: A mandatory element for each case in the navigation rule. Each case defines the different navigation paths from the same page. A navigation rule must have at least one navigation case.
  • from-action: An optional element that limits the application of the rule only to outcomes from the specified action method.
  • from-outcome: A mandatory element that contains an outcome value that is matched against values specified in the action attribute.
  • to-view-id: A mandatory element that contains the complete page identifier of the page to which the navigation is routed when the rule is implemented.

A sample navigation from our example :

<navigation-rule>
     <from-view-id>/index.xhtml</from-view-id>
     <navigation-case>
	   <from-action>#{loginBean.validateUserLogin}</from-action>
	   <from-outcome>success</from-outcome>
	   <to-view-id>/success.xhtml</to-view-id>
     </navigation-case>
</navigation-rule>

This code specifies that view index.xhtml has two outputs – success and failure associated with a particular outcome. Below is the sample managed bean code in which this navigation case is listed:

public String validateUserLogin() {
	String navResult = "";
	System.out.println("Entered Username is= " + userName + ", password is= " + password);
	if (userName.equalsIgnoreCase("javacodegeeks") && password.equals("access123")) {
		navResult = "success";
	} else {
		navResult = "failure";
	}
	return navResult;
}

1.1.2 Navigation Rule Flow

Here when the Login button is clicked in the index.xhtml, the request containing the form values is intercepted by the validateUserLogin() method of the LogicBean class.

Once the credentials are validated, JSF will resolve the success view name in the faces-config.xml and shows the corresponding result to the user. Similar execution happens in the case of invalid credentials and the user is shown the failure or the error page.

Now, open up the eclipse IDE and let’s start building the application!

2. JSF Authentication Example

2.1 Tools Used

Our preferred environment is Eclipse. We are using Eclipse Kepler SR2, JDK 8 (1.8.0_131) and Tomcat 7 application server. Having said that, we have tested the code against JDK 1.7 and it works well.

2.2 Project Structure

First, let’s review the final project structure, in case you are confused about where you should create the corresponding files or folder later!

jsf-authentication-application-project-structure
jsf-authentication-application-project-structure

2.3 Project Creation

In this section, we will see how to create a Dynmaic Web Java project with Eclipse. In eclipse IDE, go to File -> New -> Dynamic web project

jsf-project-guide-1
fig. 1 – Create Dynamic Web Project

In the New Dynamic Project window fill in the below details and click next

  • Enter the project name and project location
  • Select Target runtime as Apache Tomcat v7.0 from dropdown
  • Select Configuration as JavaServer Faces v.2.2 Project from dropdown (this is required to download the java server faces capabilities in your project)

jsf-project-guide-2
fig. 2 – Project Details

Leave everything as default in this window as we will be making the required java file at a later stage. Simply click next and we will land up on the web-module window

jsf-project-guide-src
fig. 3 – Java Src Window

In the Web Module window, leave the context_root and content_directory values as default (however, you can change the context_root but for this application let’s keep it as a default value). Simply, check Generate web.xml deployment descriptor checkbox and click next

jsf-project-guide-3
fig. 4 – Web Module Window

In the JSF Capabilities windows, we will require downloading the dependencies (not available by default) so that our project is configured as a JSF module in Eclipse. Add the JSF capabilities to the web project by clicking on the download icon (encircled in fig. 5) and download the JSF 2.2 mojara implementation

jsf-project-guide-5
fig. 5 – JSF Capabilities Window

A new pop-up window will open where it will auto lists down the JSF library. Select the JSF 2.2 library and click next (the library name and download destination will be auto populated)

jsf-project-guide-6
fig. 6 – JSF Capabilities Download Window

Check the license checkbox and click finish. Eclipse will download the JSF 2.2 library and will display them on the JSF capabilities windows (i.e. fig5)

jsf-project-guide-7
fig. 7 – JSF Capabilities License Window

Now the JSF implementation libraries will be listed down on the capabilities page. Select the checkbox (JSF2.2 (Mojarra 2.2.0)) and leave everything else as default. Click Finish

jsf-project-guide-8
fig. 8 – JSF Capabilities Library Selection Window

Eclipse will create the project named JSF Authentication in the workspace and web.xml will be configured for accepting the JSF requests. It will have the following code:

<?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" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>JSF Authentication</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</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>/faces/*</url-pattern>
  </servlet-mapping>
  <context-param>
    <description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
  </context-param>
  <context-param>
    <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
    <param-value>resources.application</param-value>
  </context-param>
  <listener>
    <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
  </listener>
</web-app>

Now let’s start building the application!

3. Application Building

3.1 File Creation

For the demo, we will have an input file containing the form page and the output files on which the result will be displayed based on the authentication result. Right click on project WebContent -> New -> File

Note – In JSF 2.0, it’s recommended to create a JSF page in xhtml format, a file format with .xhtml extension

jsf-project-guide-10
fig. 9 – File Creation

A pop-up window will open, verify the parent folder location as JSF Authentication/WebContent and enter the file name (index. xhtml) and click Finish

jsf-project-guide-11
fig. 10 – index.xhtml

Repeat the step where we need to create the file for our application (i.e. fig. 9). Again, verify the parent folder location as JSF Authentication/WebContent and enter the filename (success.xhtml) and click Finish

jsf-project-guide-12
fig. 11 – success.xhtml

Again repeat the similar step and enter the file name as – failure.xhtml. Click Finish

jsf-project-guide-13
fig. 12 – failure.xhtml

3.1.1 Implementation of Index & Output files

Now in order to use the rich UI components, we need to declare the below namespaces at top of the page in the prepared files:

html xmlns="http://www.w3.org/1999/xhtml"
 xmlns:h="http://java.sun.com/jsf/html">

Here in the index.xhtml we will have the form based UI components. The action attribute on the button will show the corresponding result based on the corresponding logic written in the managed-bean. Add the following code to it:

index.xhtml

<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html">
<h:head>
	<title>JSF Authentication</title>
	<style type="text/css">
		.textPlacement {
			margin: 12px;
		}
	</style>
</h:head>
<h:body>
	<h2>JSF Authentication Example</h2>
	<h:form id="loginForm">
		<div id="userNameDiv" class="textPlacement">
			<h:outputLabel value="Username: " />
			<h:inputText value="#{loginBean.userName}" />
		</div>
		<div id="passwordDiv" class="textPlacement">
			<h:outputLabel value="Password: " />
			<h:inputSecret value="#{loginBean.password}" />
		</div>
		<div id="submitBtn" class="textPlacement">
			<h:commandButton value="Login" action="#{loginBean.validateUserLogin}" />
		</div>
	</h:form>
</h:body>
</html>

In the output page, JSF will display the output based on the authentication result. Add the following code to it:

success.xhtml

<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html">
<h:head>
	<title>JSF Authentication</title>
	<style type="text/css">
		.successText {
			color: green;
			margin: 12px;
			font-weight: bold;
		}
	</style>
</h:head>
<h:body>
	<div id="result">
		Welcome, <span id="userName"><h:outputLabel class="successText" value="#{loginBean.userName}" /></span>
	</div>
</h:body>
</html>

failure.xhtml

<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html">
<h:head>
	<title>JSF Authentication</title>
	<style type="text/css">
		.errorText {
			color: red;
			margin: 12px;
			font-weight: bold;
		}
	</style>
</h:head>
<h:body>
	<div id="resultErr">
		<span id="invalidCre" class="errorText">Invalid Credentials</span>
	</div>
</h:body>
</html>

3.2 Java Class Creation

Let’s create the required java files. Right click on src folder New -> Package

jsf-project-guide-14
fig. 13 – Java Package Creation

A new pop window will open where we will enter the package name, namely com.jsf.authentication

jsf-project-guide-15
fig. 14 – Java Package Name

Once the package is created in the application, we will need to create the required managed bean class. Right-click on the newly created package New -> Class

jsf-project-guide-16
fig. 15 – Java Class Creation

A new pop window will open and enter the file name as LoginBean. The bean class will be created inside the package – com.jsf.authentication

jsf-project-guide-17
fig. 16 – LoginBean.java

3.2.1 Managed Bean & Implementation of Navigation Rule in faces-config.xml

LoginBean.java

This class has a method validateUserLogin() which interacts with login action event and does the user authentication based on the entered credentials. In the validateUserLogin() if the entered credentials matches with the already defined credentials, user will be granted access else the failure page will be displayed

Note – The navigation outcome is specified in the faces-config.xml for which the code is written below.

package com.jsf.authentication;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean @SessionScoped
public class LoginBean {

	private String userName;
	private String password;

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String validateUserLogin() {
		String navResult = "";
		System.out.println("Entered Username is= " + userName + ", password is= " + password);
		if (userName.equalsIgnoreCase("javacodegeeks") && password.equals("access123")) {
			navResult = "success";
		} else {
			navResult = "failure";
		}
		return navResult;
	}
}

faces-config.xml

In this file, we will specify the navigation rules based on the output of the validateUserLogin() which is specified in the managed bean i.e. LoginBean.java

<?xml version="1.0" encoding="UTF-8"?>
<faces-config xmlns="http://xmlns.jcp.org/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
	version="2.2">

	<navigation-rule>
		<from-view-id>/index.xhtml</from-view-id>
		<navigation-case>
			<from-action>#{loginBean.validateUserLogin}</from-action>
			<from-outcome>success</from-outcome>
			<to-view-id>/success.xhtml</to-view-id>
		</navigation-case>
		<navigation-case>
			<from-action>#{loginBean.validateUserLogin}</from-action>
			<from-outcome>failure</from-outcome>
			<to-view-id>/failure.xhtml</to-view-id>
		</navigation-case>
	</navigation-rule>

</faces-config>

4. Project Deploy

Once we are ready with all the changes done, let us compile and deploy the application on tomcat7 server. In order to deploy the application on tomcat7, right-click on the project and navigate to Run as -> Run on Server

jsf-tomcat-deploy-fig. 1
fig. 1 – How To Deploy Application On Tomcat

Tomcat will deploy the application in its webapps folder and shall start its execution to deploy the project so that we can go ahead and test it on the browser

jsf-tomcat-deploy-fig. 2
fig. 2 – Tomcat Processing

Open your favorite browser and hit the following URL. The output page will be displayed

http://localhost:8082/JSF_Authentication/faces/index.xhtml

Server name (localhost) and port (8082) may vary as per your tomcat configuration

5. Project Demo

When we will hit the application URL, you will see the login page

jsf-project-demo-fig. 1
demo-fig. 1 – Application Login Page

Enter the credentials javacodegeeks/access123 as username/password and press the login button

jsf-project-demo-fig. 2
demo-fig. 2 – Enter the Credentials

If the username and password are correct, the following success message will appear

jsf-project-demo-fig. 3
demo-fig. 2 – Success Page

If the username and password are incorrect, the error message will appear

jsf-project-demo-fig. 4
demo-fig. 4 – Failure/Error page

Hope this helped :)

6. Conclusion

Through this example, we have learned about the authentication mechanism in jsf and how to configure the authentication in eclipse and deploy it using the tomcat7 application server

7. Download the Eclipse Project

This was a JSF authentication example with Eclipse and Tomcat

Download
You can download the full source code of this example here: JSF Authentication

Yatin

An experience full-stack engineer well versed with Core Java, Spring/Springboot, MVC, Security, AOP, Frontend (Angular & React), and cloud technologies (such as AWS, GCP, Jenkins, Docker, K8).
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
vanja
vanja
5 years ago

How does this prevent an attacker you from seeing other facelets?
This is JSF Navigation example, not JSF Authentication example.

uncert
uncert
1 year ago

You also can use a Filter. Check the following:
https://jcodepoint.com/jsf/jsf-autenticacion/

Back to top button