Beispiel: IBM WebSphere-spezifische User-Registry


Inhalt:


Anlegen der Application
Anlegen des EJB-Projekts
Implementierung der UserRegistry
Aktivieren der Sicherheit
Universal Test Client aktivieren
Sicherheit im EJB-Projekt
Sicherheit im Web-Projekt
Sicherheit im Application Client-Projekt
Sicherheit in der Enterprise Application
Troubleshooting und Security-Tipps

Für weitergehende Infos empfehle ich das IBM-Redbook "WebSphere V6: Security Handbook": http://www.redbooks.ibm.com/redpieces/pdfs/sg246316.pdf

Dieses Beispiel zeigt die von Hr. Dreher vorgestellte UserRegistry in einem konkreten Beispiel, außerdem wird die J2EE-Security gezeigt.
Aufbau des Beispiels: Hier gibt es das Beispiel zum Download: SecurityExport.zip


Anlegen der Application

Wir legen eine Enterprise Application namens "Security" mit einem EJB-Projekt, ein Webprojekt und einen Application Client an.

Anlegen des EJB-Projekts

Es wird eine EntityBean "Student" im Package de.fhw.swtvertiefung.knauf.security mit den Feldern ID (java.lang.Integer), NAME, LOGIN und PASSWORT (jeweils java.lang.String) erzeugt.
Anschließend ein Datenbankmapping für die Bean erzeugen lassen (Rechtsklick auf Deployment Deskriptor):
Schema erzeugen
Es wird ein Top-Down-Mapping für eine Datenbank namens "KnaufDB" erzeugt.

Eine simple Session-Bean "Secured" mit Remote Interface wird erzeugt.
Wir verpassen ihr drei Methoden forAdminOnly(), forStudentOnly() und forBoth(), die keine weitere Implementierung haben.


Implementierung der UserRegistry

Nachdem wir das Datenbankschema angelegt haben, können wir diesem Schema eine nicht-Bean-Tabelle "ADMINISTRATOR" zufügen. Dazu Rechtsklick auf das Projekt und "New" -> "Other..." -> "Data" -> "Table Definition" wählen.
Tabelle ADMINISTRATOR erzeugen (1)
Wir geben als Tabellenname "Administrator" an, bei "Database/schema" klicken wir auf "Browse..." und klicken uns zur Schema-Definition durch.
Tabelle ADMINISTRATOR erzeugen (2)
Wir fügen die Spalten zu. ID ist vom Typ INTEGER, die anderen drei sind VARCHAR der Länge 255. Name und Passwort lassen NULL-Werte zu, nur LOGIN nicht.
Tabelle ADMINISTRATOR erzeugen (3)
Im nächsten Schritt wählen wir ID als Primary-Key-Spalte aus.
Tabelle ADMINISTRATOR erzeugen (4)
Foreign Keys haben wir nicht.
Tabelle ADMINISTRATOR erzeugen (5)
Damit haben wir die Datenbanktabelle erzeugt.

Jetzt die Implementation der UserRegistry, de.fhw.swtvertiefung.knauf.security.userregistry.KnaufUserRegistry, sowie die beiden Hilfsklassen de.fhw.swtvertiefung.knauf.security.userregistry.Administrator und de.fhw.swtvertiefung.knauf.security.userregistry.Student zufügen.


Aktivieren der Sicherheit

Die folgenden Schritte unbedingt in einem eigenen Profile durchführen !
Auch auf einem Privat-PC können Fehler im folgenden dazu führen dass das Default-Profil des WebSphere ruiniert wird, und nur durch eine komplette Neuinstallation "repariert" werden kann.

Nach dem Erzeugen des Profils den Server starten und die Anwendung publizieren (beim Schritt "Add/Remove projects" im Schritt 2 die Checkbox "Create tables and data sources" unbedingt aktivieren, damit unsere ADMINISTRATOR-Tabelle erzeugt wird !).

In der Datenbank (im Beispiel: KnaufDB) müssen wir mittels CView in der Tabelle ADMINISTRATOR mindestens einen Datensatz anlegen (im Beispiel: Login=TEST, Passwort=TEST). Dieser User wird im nächsten Schritt verwendet um den WebSphere-Server zu starten und zu stoppen.

Jetzt müssen wir den Server für die UserRegistry vorbereiten.
Den Server starten und die Administrative Console aufrufen (entweder aus der Entwicklungsumgebung heraus oder unter der URL
https://localhost:9043/ibm/console/).
Wir gehen links im Baum zu "Sicherheit" -> "Globale Sicherheit" und wählen in den Fenster "globale Sicherheit" erstmal die "Benutzerdefinierte Registry" ganz rechts.
Globale Sicherheit (1)
In der Benutzerdefinierten Benutzer-Registry gehen wir direkt weiter zu den "Benutzerdefinierten Merkmalen".
Wir legen drei Werte an:
DBDRIVER: com.ibm.db2j.jdbc.DB2jDriver
DBURL: jdbc:db2j:KnaufDB
DBSCHEMA: APP
Den Namen des Schemas erfährt man wenn man die Datenbank mit CView öffnet. Die Änderungen speichern.
Das Ergebnis sollte so aussehen:
Globale Sicherheit (2)
Jetzt zurück zur Benutzerdefinierten Registry. Hier geben wir den Namen unserer Klasse ein, und tragen außerdem die User-ID ein, die wir im letzten Schritt in die Tabelle ADMINISTRATOR eingegeben haben. Beim Klassennamen geben wir unsere UserRegistry-Implementation (de.fhw.swtvertiefung.knauf.security.userregistry.KnaufUserRegistry) an.
Die Änderungen speichern.

Zurück in die globale Sicherheit. Jetzt können wir sie aktivieren. Dazu den Haken bei "Globale Sicherheit aktivieren" setzen, und direkt den automatisch gesetzten Haken bei "Java-2-Sicherheit erzwingen" rauswerfen (der macht uns nur mehr Arbeit). In der ComboBox "Aktive Benutzer-Registry" wählen wir die Benutzerdefinierte Benutzer-Registry aus.
Globale Sicherheit (3)
Es erfolgt eine Validierung ob die UserRegistry den konfigurierten User auch validieren kann. Wenn hier Fehler auftreten ist unser Server immerhin nicht unerreichbar kaputt. Hat unsere Benutzervalidierung geklappt, dann müssen wir nur noch mehrfach auf "Speichern" klicken.
Ab diesem Zeitpunkt müssen wir in der "IBM Rational Development Platform" zwei Einstellungen ändern:
-Als "Server connection type and admin port" funktioniert "RMI" leider nicht mehr (hat bei mir zwar den Server gestartet aber danach keine Verbindung hergestellt). Stattdessen: SOAP aktivieren.
-In der Kategorie "Security" muss der Haken "Security is enabled on this server" gesetzt werden, und ein gültiger Username und Passwort müssen angegeben werden.
Serverdefinition

Jetzt können wir den Tipp aus Hr. Drehers Anleitung umsetzen, der die Konsolenausgabe des Servers auf die RAD-Konsole umzuleitet.
Einzige Änderung zu diesem Tipp: der absolute Pfad zur Datei redeployFileTransfer.jacl muss angegeben werden, da die nicht in unserem eigenen Profil liegt. Der Befehl sieht also so aus:

wsadmin -profile C:\Programme\IBM\Rational\SDP\6.0\runtimes\base_v6\bin\redeployFileTransfer.jacl -lang jacl -c "fileTransferAuthenticationOn <cellname> <nodename> <servername>" -user <username> -password <password>

Falls ihr einen anderen Pfad verwendet muss der natürlich angepaßt werden.

Die Ausgabe eines erfolgreich verlaufenden Befehls sollte so aussehen:
WASX7209I: Mit Prozess "server1" auf Knoten NodeKnauf2 über SOAP-Connector verbunden. Typ des Prozesses: UnManagedProcess
Uninstall filetransfer -cell CellKnauf2 -node NodeKnauf2 -server server1
ADMA5017I: Die Deinstallation von filetransfer wurde gestartet.
ADMA5011I: Die Bereinigung des temporären Verzeichnisses für die Anwendung filetransfer ist abgeschlossen.
ADMA5106I: Die Anwendung filetransfer wurde deinstalliert.
Install C:\Programme\IBM\Rational\SDP\6.0\runtimes\base_v6/systemApps/filetransferSecured.ear -cell CellKnauf2 -node NodeKnauf2 -server server1 -appname filetransfer -usedefaultbindings -nocreateMBeansForResources
ADMA5016I: Die Installation von filetransfer wurde gestartet.
ADMA5011I: Die Bereinigung des temporären Verzeichnisses für die Anwendung filetransfer ist abgeschlossen.
ADMA5013I: Die Anwendung filetransfer wurde installiert.


Die Werte für "<cellname>", "<nodename>" und "<servername>" finden wir an den markierten Stellen im Profil:
redeployFileTransfer

Es kann sein dass beim Ausführen des Befehls folgende Fehlermeldung auftritt:
WASX7209I: Mit Prozess "server1" auf Knoten NodeKnauf2 über SOAP-Connector verbunden. 
Typ des Prozesses: UnManagedProcess
Uninstall filetransfer -cell CellKnauf2 -node NodeKnauf2 -server server1
Operation FAILED!
   com.ibm.ws.scripting.ScriptingException: WASX7280E: Es ist keine Anwendung mit dem Namen "filetransfer" vorhanden. 
Das bedeutet dass diese Änderung bereits durchgeführt wurde. In diesem Fall kann man sie mit folgendem Befehl rückgängig machen:

wsadmin -profile C:\Programme\IBM\Rational\SDP\6.0\runtimes\base_v6\bin\redeployFileTransfer.jacl -lang jacl -c "fileTransferAuthenticationOff <cellname> <nodename> <servername>" -user <username> -password <password>

Jetzt kann man einen neuen Installations-Versuch wagen.

Hinweis: manchmal scheint es länger zu dauern bis RAD die Konsolenausgabe umgeleitet hat, oder bis er erkannt hat dass der Server gestartet ist. Keine Ahnung woran das liegt...


Universal Test Client aktivieren

Im Default bietet der Universal Test Client leider nur Lesezugriff auf das JNDI, d.h. der Test von Beans ist nicht möglich. Kein Problem, wir tricksen ein bißchen:
In der Datei "properties\soap.client.props" im Profile suchen wir folgende Stelle:
#------------------------------------------------------------------------------
# SOAP Client Security Enablement
#
# - security enabled status  ( false[default], true  )
#------------------------------------------------------------------------------
com.ibm.SOAP.securityEnabled=false

com.ibm.SOAP.loginUserid=
com.ibm.SOAP.loginPassword= 
Wir ändern die Werte so ab (einbauen unseres Standard-Users):
com.ibm.SOAP.securityEnabled=true
com.ibm.SOAP.loginUserid=TEST
com.ibm.SOAP.loginPassword=TEST
Nachdem wir den UTC aktiviert haben können wir auch Studenten in die Datenbank packen.


Sicherheit im EJB-Projekt

Im EJB-Projekt wollen wir einige Methoden der Session-Bean "Secured" absichern, so dass nur Benutzer in spezifierten Rollen die Methoden aufrufen dürfen.
Dazu in den Deployment-Deskriptor von SecurityEJB wechseln und auf der Karteikarte "Assembly" zuerst die "Security Roles" zufügen.
Die erste Rolle soll "administratorejb" heißen (den Namen können wir völlig frei wählen, das Mapping auf echte Server-Gruppen/-Benutzer geschieht erst später.
Security Role adminstratorejb
Eine zweite Rolle "studentejb" zufügen.

Unter "Method Permissions" werden jetzt die Zugriffsrechte für diese Rollen vergeben. Wir fügen eine neue Methode Permission zu und wählen im ersten Schritt die Rolle "administratorejb" aus.
Method Permissions (1)
Wir wählen die zu sichernde Bean aus, also "Secured".
Method Permissions (2)
Jetzt die Methoden forAdminOnly und forBoth auswählen, für die diese Zugriffsberechtigung gilt.
Method Permissions (3)
Das gleiche wiederholen für die Rolle "studentejb", die Zugriff auf forStudentOnly und forBoth bekommt.
Das Ergebnis sollte so aussehen:
EJB security
Leider können wir das nicht im UTC testen da die Bean über keine Local Interfaces verfügt.


Sicherheit im Web-Projekt

Vorbereitung: Das Web-Projekt muss das EJB-Projekt referenzieren, eine EJB-Referenz auf die Bean "Secured" muss angelegt werden.
Bevor wir hier die Sicherheit definieren legen wir zuerst drei JSP-Seiten an. "index.jsp" soll unsere zugriffs-gesicherte Seite sein, "login.jsp" ist unser Login-Formular, und "errorpage.jsp" die Fehlerseite bei Login-Fehlern.
"login.jsp" wird immer dann aufgerufen wenn ein noch nicht am Server authentifizierter User auf eine gesicherte Seite zugreifen will.
Sie verwendet Form-Based Login, d.h. ein HTML-Formular wird zum User geschickt. Damit WebSphere die Informationen aus diesem Anmeldeformular auswerten kann müssen Ziel-URL, Submit-Button sowie die Feldnamen für Login und Passwort wie folgt aussehen:
<form method="post" ACTION="j_security_check">
   Login: <input type="text" name="j_username" /> <br>
   Passwort: <input type="password" name="j_password" /> <br>
   <input type="submit" name="login" value="Login">
</form> 
"index.jsp" ruft zum Test die drei gesicherten Methoden der Secured-Bean auf. Außerdem gibt es dort einen Logout-Button. Der muss in einem Formular stecken das so aussieht:
<FORM METHOD=POST ACTION="ibm_security_logout" NAME="logout">
   Für sauberen Logout hier klicken: <br>
   <input type="submit" name="logout" value="Logout">
   <INPUT TYPE="HIDDEN" name="logoutExitPage" VALUE="login.jsp">
</FORM> 
"logoutExitPage" gibt an auf welche Seite der User nach erfolgreichem Logout geleitet werden soll.

"errorpage.jsp" ist eine ganz normale Fehlerseite, ohne Besonderheiten.

Jetzt können wir uns der Security widmen. Im Web-Deployment-Deskriptor auf der Karteikarte "Security" zwei Security Roles "administratorweb" und "studentweb" zufügen.
Security Role adminstratorweb

Unter "Security Constraints" werden Regeln definiert, welche Ressourcen von der Sicherheit betroffen sind. Dazu eine neue zufügen und ihr einen aussagekräftigen Namen geben.
Security Constraint (1)
Im nächsten Schritt einen Resourcen-Namen (frei wählbar), die zu sichernden HTTP-Methoden und ein URL-Pattern ("/*") eingeben.
Security Constraint (2)

Jetzt müssen wir festlegen für welche Rollen diese Security Constraint gilt. Dazu auf der gleichen Karteikarte die "Authorized Roles" festlegen (eine neue "Authorization Constraint" zugefügt).
Authorization Constraint

Das Ergebnis sollte so aussehen:
Web-Security

Im letzten Schritt aktivieren wir den Form Based Login. Auf der Karteikarte "Pages" unter "Login" wählen wir als "Authentication Method" "FORM", und geben die Login- und Fehler-Seiten unserer Anwendung an entsprechender Stelle an.
Form Based Login


Sicherheit im Application Client-Projekt

Vorbereitung: Das Application Client-Projekt muss das EJB-Projekt referenzieren, eine EJB-Referenz auf die Bean "Secured" muss angelegt werden. Die Main Class muss auf de.fhw.swtvertiefung.knauf.security.SecurityClient geändert werden.
In Sachen Security gibt es hier nichts zu konfigurieren, da der Application Client ja prinzipiell nicht im Server-Context läuft. Sobald wir die Anwendung allerdings starten und auf eine gesicherte Methode der Bean zugreifen blendet die Web-Sphere-Client-Schicht automatisch einen Login-Dialog ein !
AppClient: Login

Sicherheit in der Enterprise Application

Im Deployment Deskriptor der Enterprise Application schließlich legen wir fest welche der Rollen in den Teilprojekten auf welche Nutzer oder Gruppen im Server gemappt werden.
Auf der Karteikarte "Security" auf "Gather..." klicken, dies sucht die in allen Deployment-Deskriptoren definierten Rollen zusammen (es sollten hier jetzt vier Stück auftauchen). Jede der Rollen muss ausgewählt werden. Unter "WebSphere Bindings" wird die Checkbox "Users/Groups" gesetzt und eine Gruppe zugefügt. Für "administratorweb" und "administratorejb" heißt die Gruppe "administrator" (unter diesem Namen wird sie von der UserRegistry zurückgegeben.
EAR security (Group)
Für "studentweb" und "studentejb" heißt die Gruppe "student".
Das Ergebnis sieht so aus:
EAR security


Jetzt endlich dürfen wir auf den Server deployen und können bei Application Client bzw. WebClient feststellen wie sich Logins als Student bzw. Adminstrator auf die Methodenaufrufe der SecuredBean auswirken.
Ich habe die Erfahrung gemacht dass es nach dem Publish mit geänderten Security-Einstellungen in der Enterprise Application am besten ist den Server neu zu starten !
Der Webclient ist zu erreichen unter
http://localhost:9080/SecurityWeb/.


Troubleshooting und Security-Tipps




Version 1.0.0.1, Stand 15.12.2005
Historie:
1.0.0.0 (13.12.2005): Erstellt
1.0.0.1 (15.12.2005): Doku zu "redeployFileTransfer" erweitert: Rückgängigmachen und Screenshot für Ermitteln von Cell, Node, Server. Ablaufdoku für Benutzervalidierung der UserRegistry.