Tutorial

JSF Authentication Login Logout Database Example

Published on August 3, 2022
Default avatar

By Pankaj

JSF Authentication Login Logout Database Example

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Authentication mechanism allows users to have secure access to the application by validating the username and password. We will be using JSF view for login, DAO object ,HttpSession for session management, JSF managed bean and mysql database. Lets now look in detail as how to create a JSF login logout authentication mechanism in JSF application. Step 1: Create the table Users in mysql database as

CREATE TABLE Users( 
uid int(20) NOT NULL AUTO_INCREMENT, 
uname VARCHAR(60) NOT NULL, 
password VARCHAR(60) NOT NULL, 
PRIMARY KEY(uid));

Here we create user table with uid as the primary key, username and password fields with not null constraints. Step 2: Insert data into the table Users as;

INSERT INTO Users VALUES(1,'adam','adam');

Before we move on to our project related code, below image shows the project structure in Eclipse. Just create a dynamic web project and convert it to maven to get the project stub and then keep on adding different components. JSF Login, JSF Authentication, JSF Login Logout, JSF Session Step 3: Create the JSF login page login.xhtml as;

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:h="https://java.sun.com/jsf/html">
<h:head>
	<title>login</title>
</h:head>
<h:body>
	<h:form>
		<h3>JSF Login Logout</h3>
		<h:outputText value="Username" />
		<h:inputText id="username" value="#{login.user}"></h:inputText>
		<h:message for="username"></h:message>
		<br></br><br></br>
		
		<h:outputText value="Password" />
		<h:inputSecret id="password" value="#{login.pwd}"></h:inputSecret>
		<h:message for="password"></h:message>
		<br></br><br></br>
		
		<h:commandButton action="#{login.validateUsernamePassword}"
			value="Login"></h:commandButton>
	</h:form>
</h:body>
</html>

Here we are creating a JSF login view page with username and password fields and set values for these fields through the login managed bean. We invoke the validateUsernamePassword method on click of Login button to validate the username and password. Step 4: Create the managed bean Login.java as;

package com.journaldev.jsf.beans;

import java.io.Serializable;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpSession;

import com.journaldev.jsf.dao.LoginDAO;
import com.journaldev.jsf.util.SessionUtils;

@ManagedBean
@SessionScoped
public class Login implements Serializable {

	private static final long serialVersionUID = 1094801825228386363L;
	
	private String pwd;
	private String msg;
	private String user;

	public String getPwd() {
		return pwd;
	}

	public void setPwd(String pwd) {
		this.pwd = pwd;
	}

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}

	public String getUser() {
		return user;
	}

	public void setUser(String user) {
		this.user = user;
	}

	//validate login
	public String validateUsernamePassword() {
		boolean valid = LoginDAO.validate(user, pwd);
		if (valid) {
			HttpSession session = SessionUtils.getSession();
			session.setAttribute("username", user);
			return "admin";
		} else {
			FacesContext.getCurrentInstance().addMessage(
					null,
					new FacesMessage(FacesMessage.SEVERITY_WARN,
							"Incorrect Username and Passowrd",
							"Please enter correct username and Password"));
			return "login";
		}
	}

	//logout event, invalidate session
	public String logout() {
		HttpSession session = SessionUtils.getSession();
		session.invalidate();
		return "login";
	}
}

We declare three String variables user, pwd and msg for username, password and error message fields along with the getter and setter methods. We write a method validateUsernamePassword() for validating the username and password field by invoking the LoginDAO class to fetch the username and password from the database and compare it with the front end values passed. If the username and password does not match an error message is displayed as “Incorrect username and password” . Also a logout() method is written to perform logout by invalidating HTTPSession attached. Step 5: Now create the LoginDAO java class as below. Note that database operations code is not optimized to be used in a real project, I wrote it as quickly as possible because the idea is to learn authentication in JSF applications.

package com.journaldev.jsf.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.journaldev.jsf.util.DataConnect;

public class LoginDAO {

	public static boolean validate(String user, String password) {
		Connection con = null;
		PreparedStatement ps = null;

		try {
			con = DataConnect.getConnection();
			ps = con.prepareStatement("Select uname, password from Users where uname = ? and password = ?");
			ps.setString(1, user);
			ps.setString(2, password);

			ResultSet rs = ps.executeQuery();

			if (rs.next()) {
				//result found, means valid inputs
				return true;
			}
		} catch (SQLException ex) {
			System.out.println("Login error -->" + ex.getMessage());
			return false;
		} finally {
			DataConnect.close(con);
		}
		return false;
	}
}

In the validate() method we first establish connection to the database by invoking the DataConnect class getConnection method. We use PreparedStatement to build the query to fetch the data from the database with the user entered values. If we get any data in result set, it means input is valid and we return true, else false. Step 6: Create the DataConnect.java class as;

package com.journaldev.jsf.util;

import java.sql.Connection;
import java.sql.DriverManager;

public class DataConnect {

	public static Connection getConnection() {
		try {
			Class.forName("com.mysql.jdbc.Driver");
			Connection con = DriverManager.getConnection(
					"jdbc:mysql://localhost:3306/cardb", "pankaj", "pankaj123");
			return con;
		} catch (Exception ex) {
			System.out.println("Database.getConnection() Error -->"
					+ ex.getMessage());
			return null;
		}
	}

	public static void close(Connection con) {
		try {
			con.close();
		} catch (Exception ex) {
		}
	}
}

We load the JDBC driver using Class.forName method and use DriverManager.getConnection method passing the url, username and password to connect to the database. Step 7: Create SessionUtils.java to obtain and manage session related user information.

package com.journaldev.jsf.beans;

import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

public class SessionUtils {

	public static HttpSession getSession() {
		return (HttpSession) FacesContext.getCurrentInstance()
				.getExternalContext().getSession(false);
	}

	public static HttpServletRequest getRequest() {
		return (HttpServletRequest) FacesContext.getCurrentInstance()
				.getExternalContext().getRequest();
	}

	public static String getUserName() {
		HttpSession session = (HttpSession) FacesContext.getCurrentInstance()
				.getExternalContext().getSession(false);
		return session.getAttribute("username").toString();
	}

	public static String getUserId() {
		HttpSession session = getSession();
		if (session != null)
			return (String) session.getAttribute("userid");
		else
			return null;
	}
}

Here we obtain a session for each user logged through the getUserId method thereby associating a session id to a particular user id. Step 8: Create the authorization filter class as;

package com.journaldev.jsf.filter;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@WebFilter(filterName = "AuthFilter", urlPatterns = { "*.xhtml" })
public class AuthorizationFilter implements Filter {

	public AuthorizationFilter() {
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		try {

			HttpServletRequest reqt = (HttpServletRequest) request;
			HttpServletResponse resp = (HttpServletResponse) response;
			HttpSession ses = reqt.getSession(false);

			String reqURI = reqt.getRequestURI();
			if (reqURI.indexOf("/login.xhtml") >= 0
					|| (ses != null && ses.getAttribute("username") != null)
					|| reqURI.indexOf("/public/") >= 0
					|| reqURI.contains("javax.faces.resource"))
				chain.doFilter(request, response);
			else
				resp.sendRedirect(reqt.getContextPath() + "/faces/login.xhtml");
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}

	@Override
	public void destroy() {

	}
}

We implement the standard filter class by overriding the destroy and doFilter methods. In the doFilter method we will redirect user to login page if he tries to access other page without logging in. Step 9: Create admin.xhtml as;

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="https://www.w3.org/1999/xhtml"
	xmlns:h="https://java.sun.com/jsf/html">
<h:head>
	<title>Facelet Title</title>
</h:head>
<h:body>
	<h:form>
		<p>Welcome #{login.user}</p>
		<h:commandLink action="#{login.logout}" value="Logout"></h:commandLink>
	</h:form>
</h:body>
</html>

This page is rendered when the user logs in successfully. Logout functionality is implemented by calling the logout method of the Login.java class. Step 10: Create faces-config.xml file as;

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

	<navigation-rule>
		<from-view-id>/login.xhtml</from-view-id>
		<navigation-case>
			<from-outcome>admin</from-outcome>
			<to-view-id>/admin.xhtml</to-view-id>
		</navigation-case>
	</navigation-rule>

</faces-config>

Once done with all the steps specified above run the application and see the following output in the browser. Login Page JSF Login Authentication Error Page JSF Authentication Login Success Page JSF Authentication, JSF Logout Accessing admin.xhtml while logged in JSF Authentication, JSF Session Just click on the Logout link and the session will be invalidated, after that try to access admin.xhtml page and you will be redirected to the login page, go ahead and download the project from below link and try it out.

Download JSF Authentication Login Logout Project

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors
Default avatar
Pankaj

author

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
JournalDev
DigitalOcean Employee
DigitalOcean Employee badge
December 3, 2020

Hi, the warning messages will not render. An error message of “INFO: WARNING: FacesMessage(s) have been enqueued, but may not have been displayed.” Any ideas as to why this is occurring?

- Christina Back

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    March 25, 2020

    You should really adjust the line around “reqURI.contains(“javax.faces.resource”)”, because many people just to copy & paste. This line would be a large security leach in case users just add “?javax.faces.resource” behind the normal urls.

    - Felix Gaebler

      JournalDev
      DigitalOcean Employee
      DigitalOcean Employee badge
      February 26, 2019

      I got almost everything, Just the error message I didn’t get it!

      - Marcel Motta

        JournalDev
        DigitalOcean Employee
        DigitalOcean Employee badge
        February 26, 2019

        Some Annotations are deprecated, so change like this: import java.io.Serializable; import javax.enterprise.context.SessionScoped; import javax.faces.context.FacesContext; import javax.inject.Named; import javax.servlet.http.HttpSession; import com.journaldev.jsf.dao.LoginDAO; import com.journaldev.jsf.bean.SessionUtils; import javax.faces.application.FacesMessage; @Named(“login”) @SessionScoped public class Login implements Serializable{

        - Marcel Motta

          JournalDev
          DigitalOcean Employee
          DigitalOcean Employee badge
          November 22, 2018

          Hello ! Perfect sample, but i’m connected and i want go to another page but i’m not access Please, can you help me to update methode Best regards.

          - JOEL

            JournalDev
            DigitalOcean Employee
            DigitalOcean Employee badge
            April 25, 2018

            the example is perfect.

            - hüseyin

              JournalDev
              DigitalOcean Employee
              DigitalOcean Employee badge
              February 10, 2018

              why i’ve this error /login.xhtml @12,52 value=“#{login.user}”: Objetivo inalcanzable, identificador [login] resuelto a nulo ?

              - Jeff

                JournalDev
                DigitalOcean Employee
                DigitalOcean Employee badge
                November 30, 2017

                /login.xhtml @13,52 value=“#{login.user}”: Target Unreachable, identifier ‘login’ resolved to null and the import ManagedBean is unused.

                - Rafie

                  JournalDev
                  DigitalOcean Employee
                  DigitalOcean Employee badge
                  June 21, 2017

                  Hello, guys i have a problem. I download a project, connect to my DB. But after writing form, i have error. Nullpointer exception.

                  - Koka

                    JournalDev
                    DigitalOcean Employee
                    DigitalOcean Employee badge
                    April 29, 2017

                    thnx so much

                    - Halgo

                      Try DigitalOcean for free

                      Click below to sign up and get $200 of credit to try our products over 60 days!

                      Sign up

                      Join the Tech Talk
                      Success! Thank you! Please check your email for further details.

                      Please complete your information!

                      Get our biweekly newsletter

                      Sign up for Infrastructure as a Newsletter.

                      Hollie's Hub for Good

                      Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

                      Become a contributor

                      Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

                      Welcome to the developer cloud

                      DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

                      Learn more
                      DigitalOcean Cloud Control Panel