Authentification ADF sans reload de la page

Vous avez peut-être déjà eu envie d’avoir une page d’authentification en ADF qui, après validation du formulaire ne se recharge pas intégralement.
Cet article est alors fait pour vous !

Commençons tout d’abord par créer un fichier login.jspx qui contient le formulaire d’authentification et le panel à afficher une fois authentifié.

<!-- Display when user is not logged -->
<af:panelFormLayout id="pfl1">
 <af:inputText id="j_username" value="#{loginBean.username}" columns="25" required="true"
 label="nom d'utilisateur"/>
 <af:inputText id="j_password" value="#{loginBean.password}" columns="25" secret="true" required="true"
 label="mot de passe"/>
<af:commandButton id="connexion" text="Connexion"
action="#{loginBean.doLogin}"   partialSubmit="true"/>
</af:panelFormLayout>
<!-- Display when user is logged -->
 <af:panelGroupLayout id="pgl7"  layout="vertical">
 <af:outputText id="ot2" value="Utilisateur connecté:"/>
 <af:outputText id="ot4" value="#{security.login}"/>
<af:commandLink text="Déconnexion" id="logoutLink" partialSubmit="true"
action="#{loginBean.doLogout}"/>
</af:panelGroupLayout>

Au fichier login.jspx , nous avons associé un managedbean loginBean créé dans le fichier adfc-config.xml.
Ce bean est appelé lors de l’envoi de la demande d’authentification que nous allons détailler ci-après.
L’astuce est de contourner l’action effectuée par un request dispatcher :

ServletContext sc = this.getServletContext();
RequestDispatcher rd = sc.getRequestDispatcher("/login.jspx");
rd.forward(request,response);

Et pour cela , nous allons implémenter une méthode refresh() qui se chargera d’actualiser la page.

import java.io.IOException;
import java.util.ResourceBundle;
import javax.faces.application.FacesMessage;
 import javax.faces.application.ViewHandler;
 import javax.faces.component.UIViewRoot;
 import javax.faces.context.ExternalContext;
 import javax.faces.context.FacesContext;
import javax.security.auth.Subject;
 import javax.security.auth.login.FailedLoginException;
 import javax.security.auth.login.LoginException;
import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpSession;
import weblogic.security.URLCallbackHandler;
 import weblogic.security.services.Authentication;
import weblogic.servlet.security.ServletAuthentication;
 public class Login {
 private String username;
 private String password;
public Login() {
 super();
 }
public String doLogin() {
 String userNameStr = username;
 if (password==null) {
 return null;
 }
 byte[] passwordByte = password.getBytes();
FacesContext facesContext = FacesContext.getCurrentInstance();
 HttpServletRequest request = (HttpServletRequest) facesContext.getExternalContext().getRequest();
ResourceBundle bundle= ResourceBundle.getBundle("com.easyteam.easytrust.authentificationview.AuthenticationViewControllerBundle");
 try {
 Subject subject = Authentication.login(new URLCallbackHandler(userNameStr, passwordByte));
 ServletAuthentication.runAs(subject, request);
 refresh(facesContext);
} catch (FailedLoginException fle) {
 FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, bundle.getString("INCORRECT_LOGIN_PASSWORD"), bundle.getString("INCORRECT_LOGIN_PASSWORD"));
facesContext.addMessage(null, msg);
} catch (LoginException le) {
 reportUnexpectedLoginError("LoginException", le);
 }
 return null;
 }
public String doLogout() throws IOException {
 ExternalContext externalContext;
 externalContext = FacesContext.getCurrentInstance().getExternalContext();
 FacesContext context;
 context = FacesContext.getCurrentInstance();
 HttpSession session = (HttpSession) externalContext.getSession(false);
 session.invalidate();
 refresh(context);
return null;
 }
/**
 *Refresh current view after accessing user information
 * @param facesContext
 *
 */
public void refresh(FacesContext facesContext) {
String refreshpage = facesContext.getViewRoot().getViewId();
 ViewHandler viewHandler = facesContext.getApplication().getViewHandler();
 UIViewRoot viewroot = viewHandler.createView(facesContext, refreshpage);
 viewroot.setViewId(refreshpage);
 facesContext.setViewRoot(viewroot);
}
/**
 * Report unexpected login error
 * @param errType
 * @param e
 */
 private void reportUnexpectedLoginError(String errType, Exception e) {
 FacesMessage msg =
 new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erreur d'authentification inattendue", "Erreur d'authentification inattendue (" + errType + "), consultez les traces pour plus de détails");
 FacesContext.getCurrentInstance().addMessage(null, msg);
 e.printStackTrace();
 }
/**
 * @param username
 */
 public void setUsername(String username) {
 this.username = username;
 }
public String getUsername() {
 return username;
 }
/**
 * @param password
 */
 public void setPassword(String password) {
 this.password = password;
 }
public String getPassword() {
 return password;
 }
 }

Et voilà , il n’y plus qu’à exécuter!