Der Einsatz von JAAS in Web-Applikationen

Türsteher

Wolfgang Korn

JAAS (Java Authentication and Authorization Service) definiert eine API für technologieunabhängige Authentisierung sowie benutzerzentrierte deklarative Autorisierung. Der vorliegende Artikel beschreibt die Sicherheitsmechanismen von J2EE Web-Applikationen, sowie deren Einsatz in Kombination mit JAAS.

Mit dem Java Authentication and Authorization Service (JAAS) besitzt Java eine API, welche die Authentisierung unterstützt, also die Identifikation von Benutzern und Systemen einerseits, sowie die Vergabe von Zugriffrechten andererseits. JAAS-basierte Authentisierungskomponenten besitzen eine definierte Schnittstelle, sodass sie leicht ausgetauscht oder auch in anderen Anwendungen wiederverwendet werden können. Diese Schnittstelle ist unabhängig von der verwendeten Technologie zur Identifikation eines Benutzers. Beispielsweise ist das Ersetzen einer Benutzername- oder Passwort-basierten Authentisierung durch eine Smartcard gestützte Benutzeridentifikation so ohne nennenswerte Änderungen in der aufrufenden Anwendung möglich.

Der Autorisierungsteil von JAAS erlaubt die Vergabe von Zugriffsrechten in Abhängigkeit des Benutzers einer Anwendung (benutzerzentriert). Die Rechtevergabe erfolgt dabei deklarativ. Das bedeutet, dass in einer Anwendung kein Code zur Überprüfung von Rechten implementiert werden muss. Vielmehr werden die Rechte in sogenannten Policy-Dateien spezifiziert und zur Laufzeit durch einen Security Manager überprüft. Einen Überblick über die Verwendung sowie eine Bewertung der Einsatzmöglichkeiten von JAAS findet sich in [1], detaillierte Dokumentation von Sun Microsystems in [2], [3] und [4].

Beispiel-Anwendung

Alle im Rahmen des Artikels vorgestellten Konzepte werden an einer durchgängig genutzten Beispielanwendung demonstriert (Abb. 1). Bevor mit der Betrachtung der verschiedenen Konzepte begonnen wird, erfolgt zunächst eine Beschreibung der Fachlichkeit der Beispielanwendung. Als Beispiel dient eine Servlet-basierte Anwendung zur Recherche von Telefonnummern eines Unternehmens, die auch über das Internet genutzt werden kann. Neben den Rufnummern der Mitarbeiter des Unternehmens enthält das Verzeichnis Servicenummern (Support, Sales, …). Diese sind durch ein Flag gekennzeichnet. Der Zugriff auf die Anwendung soll sowohl für Mitarbeiter, als auch für registrierte Kunden des Unternehmens möglich sein. Letztere können jedoch nur Rufnummern, die als Servicenummer gekennzeichnet sind recherchieren. Die Pflege der Rufnummern ist nur für Mitarbeiter, die als Administrator eingestuft sind, möglich. Die Authentisierung der Benutzer erfolgt auf Basis eines HTML-Formulars. Auszüge aus der Anwendung werden im Verlauf des Artikels vorgestellt.

Abb. 1: Screenshot der Beispielanwendung

Die Sicherheitsmechanismen, die durch einen J2EE-konformen Web Application Container realisiert werden müssen, sind in der Servlet-Spezifikation [6] festgelegt. Die hierin beschriebenen Mechanismen stehen sowohl in Servlets als auch in Java Server Pages (JSP), die vor der Darstellung schließlich in Servlets übersetzt werden, zur Verfügung. Die Spezifikation sieht zwei verschiedene Arten zur Realisierung von Sicherheitsmechanismen vor. Beiden gemeinsam ist, dass zur Vergabe von Zugriffsrechten zunächst der Benutzer identifiziert werden muss, der auf eine geschützte Ressource zugreifen will. An dieser Stelle kommt der Deployment-Deskriptor der Web-Applikation ins Spiel.

Abb. 2: Auszug aus dem Web Application Deployment Deskriptor

In Abb. 2 sind die Elemente dieses Deskriptors dargestellt, die zur Realisierung von Sicherheit in Web-Applikationen benötigt werden. Zur Implementierung von Zugriffsschutz für Ressourcen einer Web-Applikation müssen diese zunächst dem Container bekannt gemacht werden. Bestandteil eines security-constraint ist daher immer mindestens eine Definition einer web-resource-collection. Neben Namen und einer optionalen Beschreibung definiert eine solche Ressourcen-Sammlung insbesondere URL-Patterns, welche die zu schützenden Ressourcen beschreiben, sowie die zum Einsatz kommenden HTTP-Methoden (get, post). Weiterhin muss festgelegt werden, auf welche Weise sich der zugreifende Benutzer (oder ein zugreifendes System) ausweisen muss. Die Servlet-Spezifikation sieht zu diesem Zweck HTTP Basic Authentication, HTTP Digest Authentication, Form Based Authentication und HTTPS Client Authentication auf Basis von Zertifikaten vor. Aufgrund der geringen Verbreitung ist die Unterstützung der Digest Authentication jedoch nicht zwingend vorgeschrieben. Details zur Durchführung der Authentisierung finden sich im Deployment-Deskriptor im Element login-config. Hier wird zunächst eine der genannten Authentisierungs-Methoden festgelegt (auth-method). Dem schließt sich die Definition des realm-names an, wie er in der HTTP-Spezifikation [10] beschrieben ist. Erfolgt die Authentisierung auf Basis von HTML-Formularen, sind weitere Informationen notwendig: Zum Einen muss eine HTML-Seite spezifiziert werden, welche die Login-Informationen ermittelt (form-login-page). Diese Seite muss ein Formular enthalten, welches Felder zur Ermittlung von Benutzernamen und Passwort bereitstellt. Die Namen dieser Felder werden in der Spezifikation mit j_username und j_password vorgegeben. Die eingegebenen Daten werden mit einem HTTP-post an einen Form Handler mit Namen j_security_check übertragen. Schlägt ein Login fehl, wird die in form-error-page festgelegte Seite angezeigt.


               ...
  Show/PhoneBook/ShowHits/*GET
               ...
  
               ...
  ShowEdit/PhoneBook/ShowEditHits/*/PhoneBook/Edit/*/PhoneBook/Save/*GET
               ...
   
    ...
  FORMJAAS Inc. Phonebook/login.jsp/login-error.jsp
    
               ...

Nach der Grundkonfiguration, die für die Realisierung von Zugriffsschutz notwendig ist, kann nun festgelegt werden, wer auf die geschützten Ressourcen zugreifen darf. Eine Möglichkeit, welche die Servlet-Spezifikation zu diesem Zweck vorsieht ist die deklarative Sicherheit. Diese kommt ohne jeden Eingriff in den Quellcode einer Web-Applikation aus. Vielmehr stützt sich die deklarative Sicherheit ausschließlich auf den Deployment-Deskriptor der Web-Applikation. In diesem kann für jede Web-Resource-Collection festgelegt werden, welche Rollen das Recht haben, auf diese Ressourcen zuzugreifen. Die Verknüpfung von Zugriffsrechten mit Rollen ist bei Verwendung deklarativer Sicherheit die einzige Möglichkeit, Rechte zu vergeben. Die Vergabe von Rechten an einzelne Benutzerkennungen ist hiermit nicht möglich. Rollen, die zur Vergabe von Zugriffsrechten referenziert werden, müssen zusätzlich im Deployment-Deskriptor definiert werden.

In der Beispielanwendung lässt sich auf Basis der deklarativen Sicherheit steuern, ob ein Benutzer prinzipiell Zugriff auf die Anwendung hat. Durch die Definition unterschiedlicher Web-Resource-Collections für Recherche und Pflege können unterschiedliche Rollen für die jeweiligen Funktionen der Anwendung berechtigt werden. Listing 2 zeigt die notwendigen Einträge im Deployment-Deskriptor, welche Kunden und Mitarbeitern Lese- und Administratoren Pflegezugriff auf die Telefonbuch-Anwendung einräumen. Darüber hinaus erfolgt am Ende des Deskriptors die Definition aller im Rahmen der Rechtevergabe referenzierten Rollen.

private void retrieve(...)
{
    String sqlStmt = SELECT *  +
        FROM PhoneBook WHERE Name LIKE ?;
    
    if(request.isUserInRole(customer) {
        sqlStmt +=  AND ServiceNr = 1;
    }
PreparedStatement stmt = 
        conn.prepareStatement( sqlStmt );
               ...
}

Die vorgestellten Techniken sind durch die Servlet-Spezifikation festgeschrieben und funktionieren damit in jedem Web Application Container der konform zu dieser Spezifikation ist. Verschiedene Aspekte, die für Deployment und Betrieb von Web-Applikationen von Bedeutung sind, werden durch die Spezifikation jedoch (bewusst) nicht festgeschrieben. Hierzu gehören auch Dinge, die für die Implementierung von Zugangsschutz relevant sind. Beispiele hierfür sind:

  • Die Definition von Benutzern und deren Zuordnung zu Rollen,
  • die Festlegung von Security Domains, in welchen Benutzer authentisiert werden
    und
  • die interne Realisierung der Authentisierung (JAAS oder eine Nicht-Standard-Implementierung).

Vor diesem Hintergrund nutzen die meisten Application Server neben dem durch die Servlet-Spezifikation definierten Deployment-Deskriptor web.xml einen weiteren produktspezifischen Deskriptor. In diesem können die Aspekte des Deployment konfiguriert werden, die sich nicht mit dem Standard-Deskriptor einstellen lassen. Im weiteren Verlauf des Artikels wird der spezifische Deployment-Deskriptor, wie er zum Betrieb der Beispielanwendung auf einem JBoss Application Server benötigt wird, vorgestellt.


    ...
  jmdemo.usersjmdemo.roles
    ...

Listing 5 zeigt die Login-Konfiguration der Beispielanwendung. Die gesamte Konfiguration erfolgt mit einer Application-Policy mit Namen JMDemo. Es werden die Klasse, welche das Module implementiert mit den möglichen Flags (hier required) spezifiziert, sowie die Dateinamen für User- und Rollendatei. Erstere enthält Einträge der Form =. Die Rollendatei definiert für jeden User dessen Rollen in der Form =, …, .

Abschließend muss noch dafür gesorgt werden, dass die Web-Applikation die konfigurierte Application-Policy für die Authentisierung von Benutzern heranzieht. An dieser Stelle kommt der JBoss-spezifische Deployment-Deskriptor jboss-web.xml ins Spiel. Hier wird eine Security Domain spezifiziert, die auf die Login-Konfiguration verweist. Die mit der Konfiguration aus Listing 5 verbundene Security-Domain ist unter dem Namen java:/jaas/JMDemo verfügbar. Der notwendige JBoss-spezifische Eintrag im Deployment-Deskriptor lautet:


    java:/jaas/JMDemo
  
    ...

Grundlage bei der Realisierung von Zugriffsschutz ist die Überprüfung aller eingehenden Requests. Zum Einen muss vor dem Zugriff auf eine geschützte Ressource der zugreifende Benutzer identifiziert worden sein. Zweitens muss der Zugriff auf die angefragte Ressource für diesen Benutzer erlaubt sein.

Abb. 3: Request-Verarbeitung

Abb. 3 zeigt, wie die Prüfung der Requests im Einzelnen abläuft. An den verschiedenen Farben ist erkennbar, dass in der Verarbeitung eines Requests neben dem Browser drei weitere Komponenten involviert sind. Eingehende Requests werden zunächst einem Filter übergeben. Dieser überprüft, ob der Request bereits Authentisierungs-Informationen enthält. Ist dies nicht der Fall, wird der Request zunächst auf eine Login-Seite umgeleitet. Hier werden Benutzername und Passwort eingegeben und einem Servlet zur Überprüfung zur Verfügung gestellt. Dieses Servlet darf aus leicht erkennbaren Gründen nicht unter Zugriffsschutz stehen. War die Benutzerprüfung durch das Servlet erfolgreich, wird der ursprüngliche Request erneut gestellt. Da jetzt Authentisierungs-Informationen vorhanden sind, kann der Request die erste Prüfung passieren. Im nächsten Schritt erfolgt die Überprüfung der Zugriffsrechte. Erst wenn auch diese Prüfung erfolgreich verlaufen ist, wird der Request an das Servlet der Beispielanwendung (PhoneBookServlet) weitergereicht. Aus der Beschreibung des Ablaufs ist erkennbar, dass die wesentliche Funktionalität dieser Implementierungsvariante in Filter (AuthFilter) und Authentisierungs-Servlet (AuthServlet) angesiedelt sind.


               ...
  
  
         ...
    customeremployee
              ...
  
  
         ...
    administrator
              ...
  customeremployeeadministrator
Geschrieben von
Wolfgang Korn
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.