Mécanisme d’authentification permet aux utilisateurs d’avoir un accès sécurisé à l’application en validant le nom d’utilisateur et le mot de passe. Nous utiliserons la vue JSF pour la connexion, l’objet DAO, HttpSession pour la gestion de session, le bean géré JSF et la base de données MySQL. Examinons maintenant en détail comment créer un mécanisme d’authentification de connexion JSF dans une application JSF. Étape 1: Créez la table Users dans la base de données MySQL comme
CREATE TABLE Users(
uid int(20) NOT NULL AUTO_INCREMENT,
uname VARCHAR(60) NOT NULL,
password VARCHAR(60) NOT NULL,
PRIMARY KEY(uid));
Ici, nous créons une table utilisateur avec uid comme clé primaire, les champs nom d’utilisateur et mot de passe avec des contraintes non nulles. Étape 2: Insérez des données dans la table Users comme;
INSERT INTO Users VALUES(1,'adam','adam');
Avant de passer au code lié au projet, l’image ci-dessous montre la structure du projet dans Eclipse. Créez simplement un projet Web dynamique et convertissez-le en Maven pour obtenir l’ébauche du projet, puis continuez à ajouter différents composants. Étape 3: Créez la page de connexion JSF
login.xhtml
comme;
<?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>
Ici, nous créons une page de vue de connexion JSF avec des champs de nom d’utilisateur et de mot de passe et définissons les valeurs de ces champs via le bean géré de connexion. Nous invoquons la méthode validateUsernamePassword
lors du clic sur le bouton de connexion pour valider le nom d’utilisateur et le mot de passe. Étape 4: Créez le bean géré Login.java
comme;
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;
}
//valider la connexion
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";
}
}
//événement de déconnexion, invalider la session
public String logout() {
HttpSession session = SessionUtils.getSession();
session.invalidate();
return "login";
}
}
Nous déclarons trois variables de type String, user, pwd et msg, pour les champs de nom d’utilisateur, de mot de passe et de message d’erreur, ainsi que les méthodes getter et setter. Nous écrivons une méthode validateUsernamePassword()
pour valider le champ de nom d’utilisateur et de mot de passe en invoquant la classe LoginDAO
pour récupérer le nom d’utilisateur et le mot de passe depuis la base de données et les comparer avec les valeurs de l’interface utilisateur transmises. Si le nom d’utilisateur et le mot de passe ne correspondent pas, un message d’erreur est affiché comme « Nom d’utilisateur et mot de passe incorrects ». De plus, une méthode logout()
est écrite pour effectuer la déconnexion en invalidant la session HTTP attachée. Étape 5: Créez maintenant la classe Java LoginDAO
comme indiqué ci-dessous. Notez que le code des opérations sur la base de données n’est pas optimisé pour être utilisé dans un projet réel, je l’ai écrit aussi rapidement que possible car l’idée est d’apprendre l’authentification dans les applications JSF.
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()) {
//résultat trouvé, signifie des entrées valides
return true;
}
} catch (SQLException ex) {
System.out.println("Login error -->" + ex.getMessage());
return false;
} finally {
DataConnect.close(con);
}
return false;
}
}
Dans la méthode validate()
, nous établissons d’abord une connexion à la base de données en invoquant la méthode getConnection
de la classe DataConnect
. Nous utilisons PreparedStatement
pour construire la requête afin de récupérer les données de la base de données avec les valeurs entrées par l’utilisateur. Si nous obtenons des données dans le jeu de résultats, cela signifie que l’entrée est valide et nous retournons true, sinon false. Étape 6: Créez la classe DataConnect.java
comme suit;
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) {
}
}
}
Nous chargeons le pilote JDBC en utilisant la méthode Class.forName
et utilisons la méthode DriverManager.getConnection
en passant l’URL, le nom d’utilisateur et le mot de passe pour se connecter à la base de données. Étape 7: Créez SessionUtils.java pour obtenir et gérer les informations utilisateur liées à la session.
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;
}
}
Ici, nous obtenons une session pour chaque utilisateur connecté via la méthode getUserId, associant ainsi un ID de session à un ID utilisateur particulier. Étape 8: Créez la classe de filtre d’autorisation comme suit;
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() {
}
}
Nous implémentons la classe de filtre standard en substituant les méthodes destroy et doFilter. Dans la méthode doFilter, nous redirigerons l’utilisateur vers la page de connexion s’il tente d’accéder à une autre page sans se connecter. Étape 9: Créez admin.xhtml
comme suit;
<?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>
Cette page est rendue lorsque l’utilisateur se connecte avec succès. La fonction de déconnexion est implémentée en appelant la méthode de déconnexion de la classe Login.java
. Étape 10: Créez le fichier faces-config.xml
comme suit;
<?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>
Une fois toutes les étapes spécifiées ci-dessus terminées, exécutez l’application et observez la sortie suivante dans le navigateur. Page de connexion Page d’erreur d’authentification
Page de succès de connexion
Accès à admin.xhtml connecté
Cliquez simplement sur le lien de déconnexion et la session sera invalidée, ensuite essayez d’accéder à la page admin.xhtml et vous serez redirigé vers la page de connexion, allez-y et téléchargez le projet via le lien ci-dessous et essayez-le.
Télécharger le projet de connexion/déconnexion d’authentification JSF
Source:
https://www.digitalocean.com/community/tutorials/jsf-authentication-login-logout-database-example