blog.bartlweb - a technologist's external brain

HTML-Anmeldeformulare mit Apache Modul mod_auth_form

Apache stellt verschiedene Varianten für die Authentifizierung von Nutzern bereit. Die bekannteste ist wohl AuthType Basic die im Browser eine schnöde Eingabeaufforderung für Benutzername und Passwort erzeugt. Aber der Apache Webserver liefert mit mod_auth_form auch ein Modul mit, mit dem sich ein HTML-Formular für die Anmeldung nutzen und vor allem selbst adaptieren und gestalten lässt.

Module laden

Damit mod_auth_form funktioniert, muss das entsprechende Modul durch Auskommentieren in der httpd.conf geladen werden. Außerdem werden noch weitere Module zum Verarbeiten der Requests und zum Erzeugen und Speichern der Sessions benötigt.

LoadModule auth_form_module modules/mod_auth_form.so
LoadModule session_module modules/mod_session.so
LoadModule request_module modules/mod_request.so
LoadModule session_cookie_module modules/mod_session_cookie.so
LoadModule session_crypto_module modules/mod_session_crypto.so

vHosts konfigurieren

Die Konfiguration der vHosts muss entsprechend angepasst werden und unterscheidet sich ein wenig, je nachdem ob es sich um ein reales Verzeichnis oder eine Proxy-Konfiguration handelt.

Das Template für das HTML-Formular liegt in meinem Beispiel in einem eigenen Verzeichnis, dass mittels Alias alias.static.apache angesprochen werden kann. Auch eine manuelle Logout-Funktion lässt sich über ein virtuelles Verzeichnis logout und das Session-Handling realisieren.

Konfiguration für ein Verzeichnis

<Directory "/srv/www/admin">
  Options FollowSymlinks
  AllowOverride AuthConfig Indexes
  
  AuthType form
  AuthFormUsername bw_username
  AuthFormPassword bw_password
  ErrorDocument 401 /alias.static.apache/authform/login.htm
 
  AuthName "Authentication required"
 
  AuthFormProvider file
  AuthUserFile /srv/htpasswd/admin.htpasswd
        
  Session On
  SessionCryptoPassphrase gUxw1NQnqCbkj01Ubv2E
  SessionCookieName session path=/
  SessionMaxAge 0
 
  Require valid-user
</Directory>

<Location "/logout">
  SetHandler form-logout-handler
  AuthFormLogoutLocation "/"
  Session on
  SessionCryptoPassphrase gUxw1NQnqCbkj01Ubv2E
  SessionCookieName session path=/
  SessionMaxAge 1
</Location>

Konfiguration für einen Proxy

ProxyPreserveHost On
ProxyPass /alias.static.apache/ !
ProxyPass /logout !
ProxyPass / http://backendserver:8420/
ProxyPassReverse / http://backendserver:8420/
 
<Location />        
  AuthType form
  AuthFormUsername bw_username
  AuthFormPassword bw_password
  ErrorDocument 401 /alias.static.apache/authform/login.htm
        
  AuthName "Authentication required"
 
  AuthFormProvider file
  AuthUserFile /serv/htpasswd/backend.htpasswd
 
  Session On
  SessionCryptoPassphrase gUxw1NQnqCbkj01Ubv2E
  SessionCookieName session path=/
  SessionMaxAge 86400
 
  <RequireAny>
    Require valid-user
  </RequireAny>
</Location>
 
<Location "/alias.static.apache">
  Require all granted
</Location>
 
<Location "/logout">
  SetHandler form-logout-handler        
  AuthFormLogoutLocation "/"
 
  Session on
  SessionCryptoPassphrase gUxw1NQnqCbkj01Ubv2E
  SessionCookieName session path=/
  SessionMaxAge 1
</Location>

Manchmal kann die durch den Proxy bereitgestellte Anwendung, nach der Umstellung auf mod_auth_form, nicht geladen werden (Browser lädt endlos). Dann sorgt die zusätzliche Direktive AuthFormLoginSuccessLocation / für Abhilfe.

HTML-Formular

Das HTML-Formular kann frei gestaltet werden, insofern die Feldbezeichnungen aus der Konfiguration für Benutzername und Passwort beachtet bzw. entsprechend adaptiert werden.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
   <title>Authentication required</title>
   <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
   <meta name="robots" content="noindex, nofollow" />
   <link rel="shortcut icon" href="/alias.static.apache/authform/favicon.ico" type="image/x-icon" />
   <link rel="stylesheet" type="text/css" href="/alias.static.apache/authform/style.css" />
   <script language="javascript" src="/alias.static.apache/authform/jquery/jquery-3.1.0.min.js" type="text/javascript"></script>
   <script language="javascript" src="/alias.static.apache/authform/script.js" type="text/javascript"></script>
</head>
<body>
   <h1>Authentication required to access <span class="bw_domain">the requested website</span></h1>
   <form method="post" action="">
     <div id="bw_error">
       <p>Login failed!<br/>Please check the provided username and password and try again.</p>
     </div>
     <fieldset>
       <label>Username</label>
       <input type="text" name="bw_username" value="" id="bw_username" />
       <label>Password</label>
       <input type="password" name="bw_password" value="" id="bw_password" />
       <input type="submit" value="Login" name="bw_login" />
     </fieldset>
   </form>
</body>
</html>

Das eingebundene JavaScript kümmert sich, um das Vorausfüllen des Benutzernamens und die Anzeige von Fehlermeldungen, denn das beherscht mod_auth_form leider noch nicht.

jQuery(document).ready(function(){
   // write domain name in header
   jQuery("span.bw_domain").text(window.location.hostname);
 
   // invalidate locale storage items after 5 seconds
   d = new Date();
   limit = d.getTime() - 1000 * 5;
   if(localStorage.getItem("bw_login") && localStorage.getItem("bw_login") < limit) {
     localStorage.removeItem("bw_username");
     localStorage.removeItem("bw_login");
   }
 
   // error handling and preserved values
   if(localStorage.getItem("bw_login")){
     jQuery("#bw_error").show();
   }
 
   if(localStorage.getItem("bw_username") && localStorage.getItem("bw_username").length > 0){
     jQuery("#bw_username").val(localStorage.getItem("bw_username"));
     jQuery("#bw_password").focus();
   } else {
     jQuery("#bw_username").focus();
   }
 
   // store data on login
   jQuery("form").submit(function(){
     localStorage.setItem("bw_username", jQuery("#bw_username").val());

     d = new Date();
     localStorage.setItem("bw_login", d.getTime());
   });

   // remove data after usage
   localStorage.removeItem("bw_username");
   localStorage.removeItem("bw_login");
});

Dieser Artikel hat Dir deinen Tag gerettet?

... und mühevolles Probieren, Recherchieren und damit Stunden an Zeit gespart? Oder einfach nur Dein Problem gelöst?

Dann würde ich mich freuen, wenn Du meine Zeit für die Erstellung dieses Blogartikels mit einer kleinen Anerkennung honorierst:

Zahlung mit PayPal oder Kreditkarte.

Hinweis zur Verwendung

Die Übermittlung einer Zahlung ist eine persönliche Anerkennung Ihrerseits an den Entwickler (Christian Bartl, Privatperson). Eine Zahlung ist nicht zweckgebunden und es ist keine Gegenleistung zu erwarten. Bitte beachten Sie, dass für eine übermittelte Zahlung keine Quittung ausgestellt werden kann.

Über den Autor

Christian Bartl

Christian Bartl Requirements Engineer
& Solution Architect für Online und Mobile

Als Technologie-Enthusiast und begeisterter Programmierer entwickle ich in meiner Freizeit Websites, Software und IT-Lösungen, die mir selbst und anderen den Alltag vereinfachen.

mehr auf christian.bartl.me

Kommentare

Noch kein Kommentar vorhanden.
Sei der Erste! - Ich freue mich über deine Anmerkung, Kritik oder Frage.

Kommentar schreiben

Der hier angegebene Name wird gemeinsam mit deinem Kommentar auf der Website veröffentlicht.

Deine E-Mail-Adresse wird zur einmaligen Benachrichtigung bei Veröffentlichung des Kommentars genutzt.

Benachrichtigung per E-Mail über Antworten auf meinen Kommentar erhalten.

Bitte tippe die Zahlenkombination "3275" ein, nur dann kann ich deinen Kommentar entgegennehmen.

Bitte fülle dieses Feld nicht aus, nur dann kann ich deinen Kommentar entgegennehmen.