Servlet-Filter für die Verarbeitung von Anmeldeformularen entwickeln

Bei der formularbasierten Anmeldung können Darstellung und Funktionsweise der Anmeldeanzeige gesteuert werden. Bei der formularbasierten Anmeldung geben Sie eine Anmeldeseite an, die angezeigt wird, um die Benutzer-ID und das Kennwort abzurufen. Sie können auch eine Fehlerseite angeben, die beim Scheitern der Authentifizierung angezeigt wird.

Informationen zu diesem Vorgang

Wenn vor und nach der Authentifizierung zusätzliche Verarbeitungsschritte für die Authentifizierung erforderlich sind, können Servlet-Filter verwendet werden. Servlet-Filter können Anforderungen und Antworten abfangen, um die darin enthaltenen Informationen umzusetzen oder zu verwenden. Einem Servlet oder einer Gruppe von Servlets können mehrere Servlet-Filter zugeordnet werden. Sie können Servlet-Filter auch JSP-Dateien und HTML-Seiten zuordnen. Alle zugeordneten Servlet-Filter werden vor dem Servlet aufgerufen.

Jeder Web-Container, der der Servlet-Spezifikation 2.3 entspricht, unterstützt sowohl die formularbasierte Anmeldung als auch Servlet-Filter. Das Servlet mit dem Anmeldeformular führt die Authentifizierung durch. Die Servlet-Filtern können dann die Authentifizierung erweitern oder Informationen prüfen bzw. protokollieren.

Wenn Sie für die Vor- und Nachbereitung der Anmeldung (pre-login und post-login) Servlet-Filter verwenden möchten, können Sie die Filter für die Unterstützung des Anmeldeformulars oder für den URL /j_security_check konfigurieren. Der URL j_security_check wird von einem Anmeldeformular mit dem Parameter j_username für den Benutzernamen und dem Parameter j_password für das Kennwort übergeben. Ein Servlet-Filter könnte den Benutzernamen und das Kennwort für eine weitergehende Authentifizierung oder andere spezielle Aufgaben verwenden.

Vorgehensweise

  1. Ein Servlet-Filter implementiert die Klasse javax.servlet.Filter. Aus der Filterklasse müssen drei Methoden implementiert werden:
    • init(javax.servlet.FilterConfig cfg). Diese Methode wird vom Container einmal aufgerufen, wenn der Servlet-Filter in Dienst gestellt wird. Die an diese Methode übergebene Filterkonfiguration (FilterConfig) enthält die Initialisierungsparameter für den Servlet-Filter. Geben Sie die Initialisierungsparameter für einen Servlet-Filter beim Konfigurieren mit dem Assembliertool an.
    • destroy. Diese Methode wird vom Container aufgerufen, wenn der Servlet-Filter außer Dienst gestellt wird.
    • doFilter(ServletRequest req, ServletResponse res, FilterChain chain). Der Container ruft diese Methode für jede Servletanforderung auf, die diesem Filter zugeordnet ist, bevor das Servlet aufgerufen wird. Mit der an diese Methode übergebenen Filterkette (FilterChain) kann der nächste Filter der Kette aufgerufen werden. Das ursprünglich angeforderte Servlet wird ausgeführt, wenn der letzte Filter der Kette die Methode chain.doFilter aufruft. Deshalb rufen alle Filter die Methode chain.doFilter auf, damit nach dem Filtern das ursprüngliche Servlet ausgeführt wird. Wenn im Filtercode eine zusätzliche Authentifizierungsprüfung implementiert ist und diese nicht bestanden wird, wird das ursprüngliche Servlet nicht ausgeführt. Die Methode chain.doFilter wird nicht aufgerufen und kann an eine andere Fehlerseite umgeleitet werden.
  2. Wenn ein Servlet vielen Servlet-Filtern zugeordnet ist, werden die Filter in der Reihenfolge aufgerufen, die im Implementierungsdeskriptor der Anwendung (web.xml) vorgegeben ist. Stellen Sie die Klassendatei für den Servlet-Filter in das Verzeichnis WEB-INF/classes der Anwendung.

Beispiel

Beispiel für einen Servlet-Filter.

Dieser Anmeldefilter kann zur Vor- und Nachbereitung der Anmeldung dem URL /j_security_check zugeordnet werden:

import javax.servlet.*;
     public class LoginFilter implements Filter {
     protected FilterConfig filterConfig;
     // Wird einmalig bei Instanziierung des Filters aufgerufen. 
     // Bei Zuordnung zu j_security_check erfolgt der Aufruf
               // beim erstmaligen Aufruf von j_security_check.
     public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
        }
     public void destroy() {
        this.filterConfig = null;
        }
      // Wird für jede diesem Filter zugeordnete Anforderung aufgerufen. 
     // Bei Zuordnung zu j_security_check erfolgt der Aufruf bei
                 // jeder "j_security_check"-Aktion.
     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
         throws java.io.IOException, ServletException   {
         // Anmeldungsvorbereitung hier ausführen
         chain.doFilter(request, response);  
         // Ruft den nächsten Filter in der Kette auf.  
         // j_security_check, wenn dieser Filter 
         // j_security_check zugeordnet ist.
        // Anmeldungsnachbereitung hier ausführen
                 }
       }
Verwendung von Servletfiltern für die Vor- und Nachverarbeitung der Anmeldung bei einer formularbasierten Anmeldung

Dieses Beispiel veranschaulicht eine Methode, mit der Servletfilter die Vor- und Nachverarbeitung der Anmeldung bei einer formularbasierten Anmeldung durchführen können.

Quellcode für Servletfilter: LoginFilter.java
/**
 * Beispiel für einen Servlet-Filter: Dieser Code filtert j_security_check und
 * für vor der Anmeldung eine Aktion durch, um festzustellen, ob der Benutzer,
 * der versucht sich anzumelden, in der Liste widerrufener Benutzer enthalten
 * ist. Falls der Benutzer on dieser Liste enthalten ist, wird ein Fehler an
 * den Browser zurückgesendet.
 *
 * Der Filter liest den Namen der Liste widerrufener Benutzer aus der Filterkonfiguation, 
 * die mit der Methode init() übergeben wurde. Er liest die Datei mit der Liste widerrufener
 * Benutzer und erstellt eine Liste widerrufener Benutzer.
 * 
 * Beim Aufruf der Methode doFilter wird der sich anmeldende Benutzer überprüft, um 
 * sicherzustellen, dass er nicht on der Liste widerrufener Benutzer enthalten ist.
 *
 */

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

public class LoginFilter implements Filter {

   protected FilterConfig filterConfig;

   java.util.List revokeList; 
   

   /**
    * init() : Beim Instanziieren des Filters wird die Methode init() aufgerufen.
    * Dieser Filter wird instanziiert, wenn j_security_check das erste Mal
    * für die Anwendung aufgerufen wird (wenn auf ein geschütztes Servlet
    * in der Anwendung zugegriffen wird).
    */
   public void init(FilterConfig filterConfig) throws ServletException {
      this.filterConfig = filterConfig;

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


   /**
    * destroy() : Die Methode destroy() wird aufgerufen, wenn der Filter
    * inakiviert wird.
    */
   public void destroy() {
      this.filterConfig = null;
      revokeList = null;
   }

   /**
    * doFilter() : Die Methode doFilter() wird vor dem Servlet, dem dieser
    * Filter zugeordnet wird, aufgerufen. Da dieser Filter j_security_check
    * zugeordnet wird, wird diese Methode vor dem Ausführen der
    * Aktion j_security_check aufgerufen.
    */
   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");

      // Falls der Benutzer in der Liste widerrufener Benutzer enthalten ist,
      // wird ein Fehler gesendet.
      if ( revokeList.contains(username) ) {
      res.sendError(javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED);
      return;
      }
      
      // Nächsten Filter in der Kette aufrufen: Benutzer mit j_security_check
      // authentifizieren
      chain.doFilter(request, response);

      // post login action

   }

   /**
    * readConfig() : Liest die Datei mit der Liste widerrufener Benutzer und
    * erstellt eine Liste mit widerrufenen Benutzern
    */
   private void readConfig() {
      if ( filterConfig != null ) {

         // Datei mit der Liste widerrufener Benutzer abrufen und öffnen.
         BufferedReader in;
         try  { 
               String filename = filterConfig.getInitParameter("RevokedUsers");
               in = new BufferedReader( new FileReader(filename));
         } catch ( FileNotFoundException fnfe) {
               return;
         }
	
         // Alle widerrufenen Benutzer lesen und zur Liste widerrufener Benutzer hinzufügen. 
         String userName;
         try  { 
               while ( (userName = in.readLine()) != null ) 
                   revokeList.add(userName);
         } catch (IOException ioe) {
         }

      }
  
   }

   
}
Wichtig: Im vorherigen Codebeispiel wurde die Zeile, die mit public void doFilter(ServletRequest request beginnt, wegen der besseren Lesbarkeit hier auf zwei Zeilen aufgeteilt. Die Zeile public void doFilter(ServletRequest request und die Zeile danach sind eine fortlaufende Zeile.
Es folgt ein Beispiel für die Datei web.xml, in der der Filter LoginFilter konfiguriert und dem URL j_security_check zugeordnet wird:
<filter id="Filter_1">
    <filter-name>Anmeldefilter</filter-name>
	   	   <filter-class>LoginFilter</filter-class>
	        	        <description>Führt Operationen vor und nach der
        Anmeldung aus</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>Anmeldefilter</filter-name>
	    	    <url-pattern>/j_security_check</url-pattern>
</filter-mapping>
Beispiel für eine Datei mit einer Liste widerrufener Benutzer:
user1
cn=user1,o=ibm,c=us
user99
cn=user99,o=ibm,c=us

Symbol, das den Typ des Artikels anzeigt. Taskartikel



Symbol für Zeitmarke Letzte Aktualisierung: 25.05.2016
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=tsec_servlet
Dateiname:tsec_servlet.html