Développement de filtres de servlet pour le traitement de la connexion par formulaire

Vous pouvez contrôler l'aspect de l'écran de connexion à l'aide du mécanisme de connexion par formulaire. Dans la connexion par formulaire, vous indiquez une page de connexion utilisée pour extraire les informations de mot de passe et d'ID utilisateur. Vous pouvez également indiquer une page d'erreur qui s'affiche lorsque l'authentification n'aboutit pas.

A propos de cette tâche

Si une authentification ou un traitement supplémentaire est requis avant ou après l'authentification, les filtres de servlet sont facultatifs. Les filtres de servlet peuvent dynamiquement intercepter des demandes et des réponses pour convertir ou utiliser les informations qu'elles contiennent. Un ou plusieurs filtres de servlet peuvent être associés à un servlet ou à un groupe de servlets. Les filtres de servlet peuvent également être associés à des fichiers JSP (JavaServer Pages) et des pages HTML. Tous les filtres de servlet associés son appelés avant le servlet.

Les connexions par formulaire et les filtres de servlet sont pris en charge par les conteneurs Web conformes à la spécification de servlet Version 2.3. Le servlet de connexion par formulaire effectue l'authentification et les filtres de servlet effectuent une authentification supplémentaire, un audit ou une consignation des informations.

Pour effectuer des actions de pré-connexion et de post-connexion à l'aide des filtres de servlet, configurez ces filtres pour la prise en charge de la page de connexion par formulaire ou pour l'URL /j_security_check. L'URL j_security_check est transmise par une page de connexion par formulaire avec le paramètre j_username contenant le nom d'utilisateur et le paramètre j_password contenant le mot de passe. Un filtre de servlet peut utiliser le paramètre de nom d'utilisateur et les informations de mot de passe pour une authentification avancée ou pour d'autres besoins spéciaux.

Procédure

  1. Un filtre de servlet implémente la classe javax.servlet.Filter. Implémentez trois méthodes dans la classe de filtre :
    • init (javax.servlet.FilterConfig cfg). Cette méthode n'est appelée par le conteneur qu'une seule fois ; lors de la mise en service du filtre de servlet. Le paramètre FilterConfig transmis à cette méthode contient les paramètres d'initialisation du filtre de servlet. Indiquez les paramètres d'initialisation pour un filtre de servlet lors de la configuration à l'aide de l'outil d'assemblage.
    • détruire. Cette méthode est appelée par le conteneur lorsque le filtre de servlet est retiré d'un service.
    • doFilter(ServletRequest req, ServletResponse res, FilterChain chain). Cette méthode est appelée par le conteneur pour chaque demande de servlet mappée vers ce filtre avant l'appel du servlet. La chaîne FilterChain transmise à cette méthode permet d'appeler le filtre suivant de la chaîne de filtres. Le servlet d'origine demandé est exécuté lorsque le dernier filtre de la chaîne appelle la méthode chain.doFilter. C'est pourquoi, tous les filtres appellent la méthode chain.doFilter pour que le servlet d'origine soit exécuté après le filtrage. Si une vérification d'authentification supplémentaire est implémentée dans le code du filtre et qu'elle se traduit par un échec, le servlet d'origine n'est pas exécuté. La méthode chain.doFilter n'est pas appelée et peut être redirigée vers une autre page d'erreur.
  2. Si un servlet est mappé à de nombreux filtres de servlet, les filtres de servlet sont appelés dans l'ordre indiqué dans laweb.xmldescripteur de déploiement de l'application. Placez le fichier de classe de filtre de servlet dans leWEB-INF/classesrépertoire de l'application.

Exemple

Exemple de filtre de servlet.

Ce filtre de connexion peut être mappé vers l'URL /j_security_check pour effectuer les actions de pré-connexion et de post-connexion.

import javax.servlet.*;
     public class LoginFilter implements Filter {
     protected FilterConfig filterConfig;
     // Called once when this filter is instantiated. 
     // If mapped to j_security_check, called 
     // very first time j_security_check is invoked.
     public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
        }
     public void destroy() {
        this.filterConfig = null;
        }
      // Called for every request that is mapped to this filter. 
     // If mapped to j_security_check, 
     // called for every  j_security_check action
     public void doFilter(ServletRequest request, 
     ServletResponse response, FilterChain chain) 
         throws java.io.IOException, ServletException   {
         // perform pre-login action here
         chain.doFilter(request, response);  
         // calls the next filter in chain.  
         // j_security_check if this filter is 
         // mapped to j_security_check.
        // perform post-login action here.
                 }
       }
Utilisation des filtres de servlet pour effectuer le traitement préconnexion et postconnexion lors d'une connexion par formulaire

Cet exemple explique comment des filtres de servlet peuvent effectuer le traitement préconnexion et postconnexion, lors d'une connexion par formulaire.

Servlet filter source code: LoginFilter.java
/**
 * A servlet filter example: This example filters j_security_check and
 * performs pre-login action to determine if the user trying to log in
 * is in the revoked list. If the user is on the revoked list, an error is
 * sent back to the browser.
 *
 * This filter reads the revoked list file name from the FilterConfig 
 * passed in the init() method. It reads the revoked user list file and
 * creates a revokedUsers list.
 * 
 * When the doFilter method is called, the user logging in is checked 
 * to make sure that the user is not on the revoked Users list.
 *
 */

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class LoginFilter implements Filter {

   protected FilterConfig filterConfig;

   java.util.List revokeList; 
   

   /**
    * init() : init() method called when the filter is instantiated.
    * This filter is instantiated the first time j_security_check is 
    * invoked for the application (When a protected servlet in the 
    * application is accessed).
    */
   public void init(FilterConfig filterConfig) throws ServletException {
      this.filterConfig = filterConfig;

      // read revoked user list
      revokeList = new java.util.ArrayList(); 
      readConfig();
   }


   /**
    * destroy() : destroy() method called when the filter is taken 
    * out of service.
    */
   public void destroy() {
      this.filterConfig = null;
      revokeList = null;
   }

   /**
    * doFilter() : doFilter() method called before the servlet to 
    * which this filter is mapped is invoked. Since this filter is  
    * mapped to j_security_check,this method is called before 
    * j_security_check action is posted.
    */
   public void doFilter(ServletRequest request, ServletResponse response, 
FilterChain chain) throws java.io.IOException, ServletException {


      HttpServletRequest req = (HttpServletRequest)request;
      HttpServletResponse res = (HttpServletResponse)response;

      // pre login action
      
      // get username 
      String username = req.getParameter("j_username");

      // if user is in revoked list send error
      if ( revokeList.contains(username) ) {
      res.sendError(javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED);
      return;
      }
      
      // call next filter in the chain : let j_security_check authenticate 
      // user
      chain.doFilter(request, response);

      // post login action

   }

   /**
    * readConfig() : Reads revoked user list file and creates a revoked 
    * user list.
    */
   private void readConfig() {
      if ( filterConfig != null ) {

         // get the revoked user list file and open it.
         BufferedReader in;
         try { 
               String filename = filterConfig.getInitParameter("RevokedUsers");
               in = new BufferedReader( new FileReader(filename));
         } catch ( FileNotFoundException fnfe) {
               return;
         }
	
         // read all the revoked users and add to revokeList. 
         String userName;
         try {
               while ( (userName = in.readLine()) != null ) 
                   revokeList.add(userName);
         } catch (IOException ioe) {
         }

      }
  
   }

   
}
Important: Dans l'exemple de code précédent, la ligne qui commencepublic void doFilter(ServletRequest requestest divisé en deux lignes à des fins d'illustration uniquement. :NONE.public void doFilter(ServletRequest requestligne et la ligne qui la suit sont une ligne continue.
Un exemple de laweb.xmlqui montre le filtre LoginFilter configuré et mappé au j_security_check URL :
<filter id="Filter_1">
    <filter-name>LoginFilter</filter-name>
	   <filter-class>LoginFilter</filter-class>
	        <description>Performs pre-login and post-login operation</description>
			 <init-param>
			 <param-name>RevokedUsers</param-name>
			 <param-value>c:\WebSphere\AppServer\installedApps\
                            <app-name>\revokedUsers.lst</param-value>
				</init-param>
</filter-id>

<filter-mapping>
	<filter-name>LoginFilter</filter-name>
	    <url-pattern>/j_security_check</url-pattern>
</filter-mapping>
Exemple de fichier de liste d'utilisateurs révoqués :
user1
cn=user1,o=ibm,c=us
user99
cn=user99,o=ibm,c=us