Die Erstellung einer Applikation zur Verwaltung der Partner- und Bestandsdaten eines Versicherungsunternehmens dient als theoretisches Beispiel zur Diskussion verschiedener Aspekte der J2EE Security. Dieser Anwendungsbereich ist besonders sicherheitskritisch. Es soll Kunden sowie intern und extern arbeitenden Mitarbeitern des Versicherungsunternehmens einerseits möglichst einfach und flexibel Zugriff auf die eigenen Daten gegeben werden. Andererseits wird hier mit ganz besonders schützenswerten Informationen umgegangen. Daher muss unter allen Umständen vermieden werden, dass Unberechtigte diese Daten lesen oder gar verändern können.
Ein simples Beispiel soll aus den idealtypischen Rollen „Kunde“ (KD), „Angestellter Außendienst“ (AD) und „Sachbearbeiter“ (SB) bestehen, wobei Rollen eine Gruppierung von Rechten innerhalb verschiedener Anwendungen darstellen, die zur Erfüllung von Funktionen oder Arbeitsprozessen notwendig sind.
Die fachliche Welt ist aber deutlich komplexer: Weder gibt es „den Außendienstler“ noch „den Sachbearbeiter“. Der AD ist oft in größeren Agenturen hierarchisch organisiert, wobei höhere Ebenen Zugriff auf Daten der unteren Ebenen haben und über mehr Rechte verfügen. Noch komplexer ist es beim Innendienst der Versicherung. SB gibt es in vielfacher Typisierung, unterschieden nach Sparte (Leben, Kranken, diverse Sachversicherungen), Vollmachtsstufen, Hierarchiestufen mit Zusatzrechten, Spezialbearbeitungsrechten auf VIP- oder Mitarbeiterverträge.
Wie sehen mögliche Prozesse der einzelnen Rollen aus? Ein Kunde sollte die Möglichkeit haben, über Internet seine vertraglichen (Bestandsdaten) und persönlichen Nutzerdaten (Partnerdaten) zu sehen und teilweise zu ändern (etwa Nachname und Adressdaten). Änderungen können aber weitere interne Benachrichtigungen zur Folge haben, etwa die Datenanpassung in anderen Systemen oder die Information von speziellen SB oder des Kundenvertreters (Bsp.: Kunde ändert die Adresse und besitzt eine Hausratversicherung: Gibt es jetzt neue Risiken?).
Der Außendienst darf eine größere Anzahl Partner- und Vertragsdaten neu anlegen, lesen, ändern, zusammenführen und löschen. Vor Übertrag in die Host-Systeme müssen aber Konsistenzprüfungen und teilweise weiterführende Prozesse angestoßen werden. Die Zugriffsrechte der Sachbearbeiter auf Partner und Bestände sollten einschränkbar hinsichtlich Region, Status des Kundendatensatzes, Bearbeitungsvollmacht (z.B. Regulierungshöhe) und Zugriffsart (lesen, ändern, neu anlegen, zusammenführen, löschen/stornieren …) sein. Letztlich ist es durch eine Kombination von Rollen möglich, jede fachliche Aktivität damit durchzuführen, teilweise sind Rollen aber voneinander abhängig oder aber auch nicht miteinander vereinbar (4-Augen-Prinzip, „Separation of duties“-Paradigma).
Authentifizierung
Der erste Schritt zur Sicherung von Webanwendungen ist die sichere Authentifizierung des Benutzers. Prinzipiell sind eine ganze Reihe unterschiedlicher Authentifizierungsmethoden möglich. Diese reichen von wissensbasierten (z.B. über die Eingabe von User ID und Passwort) über schlüsselbasierte (z.B. SmartCard) bis hin zu biometrischen (z.B. Iris-Scan) Verfahren. Für einen Kunden-Login sind schlüsselbasierte oder biometrische Verfahren für das hier vorgestellte Beispiel (noch) nicht praktikabel, sodass die Entscheidung auf die Eingabe von User ID und Passwort fällt. Die J2EE-Spezifikation definiert dafür drei Typen von Authentifizierung:- HTTP-Basic-Authentifizierung: Eingabe von User ID und Passwort in einem vom System bereitgestellten Anmeldefenster
- Form-based Authentification: User-ID- und Passworteingabe über ein selbst erstelltes Formular
- Authentifizierung über Client-Zertifikate: Datenübergabe durch ein Client-Zertifikat
...<login-config><auth-method>BASIC</auth-method><realm-name>default</realm-name></login-config>...
Verfügbare Sicherheitsmechanismen
Nach erfolgreicher Authentifizierung am Application Server erhält der Benutzer seine Zugriffsrechte. Die J2EE-Spezifikation beschreibt zur Autorisierung zwei Ansätze: die deklarative und die programmatische Security. Bei der programmatischen Security werden die Sicherheitsprüfungen in das Programm in aller technischen Detailtiefe integriert, während bei deklarativer Security der Container alle Sicherheitsabfragen übernimmt.Für beide Ansätze sind die benötigten Rollen vom Application Component Provider in den DDs der jeweiligen Komponenten (EJB oder Web) zu definieren. Dazu werden entsprechende Security-Role- Einträge im DD hinterlegt (Listing 1 und 2). Diese applikationsspezifischen Rollen werden vom Deployer bzw. Systemadministrator auf die realen Benutzergruppen der zugrunde liegenden Benutzerverwaltung abgebildet.
Listing 1...<assembly-descriptor><security-role><description/><role-name>Kunde</role-name></security-role><security-role><description/><role-name>Sachbearbeiter</role-name></security-role><security-role><description/><role-name>Aussendienst</role-name></security-role></assembly-descriptor>...
Listing 2..<web-app><security-role><description/><role-name>Kunde</role-name></security-role><security-role><description/><role-name>Sachbearbeiter</role-name></security-role><security-role><description/><role-name>Aussendienst</role-name></security-role></web-app>...
Deklarative Security
Die deklarative Security delegiert die Sicherheitsprüfungen an den Web- bzw. EJB- Container. Hierbei hat der Entwickler bereits beim Design der Anwendung festzulegen, auf welcher Ebene die Prüfungen durchgeführt werden.Im Falle einer Webanwendung wird der Zugriff im DD per Security Constraint festgelegt. Eine solche Sicherheitsrestriktion besteht aus einer oder mehreren Web Resource Collection (Listing 3). Mittels Patterns können einzelne Seiten bzw. Seitenmengen anhand einer URL definiert werden. Die im Auth Constraint angegebenen Rollen erhalten Zugriff auf die Webressourcen.
Listing 3...<security-constraint><web-resource-collection><web-resource-name>Eingabe</web-resource-name><description>Definiert die Eingabemasken</description><url-pattern>/input/*</url-pattern><http-method>GET</http-method><http-method>POST</http-method></web-resource-collection><auth-constraint><description>Berechtigte Benutzergruppen</description><role-name>Sachbearbeiter</role-name><role-name>Kunde</role-name><role-name>Aussendienst</role-name></auth-constraint></security-constraint>...
Listing 4...<assembly-descriptor>...<method-permission><role-name>Kunde</role-name><role-name>Sachbearbeiter</role-name><role-name>Aussendienst</role-name><method><ejb-name>Partner</ejb-name><method-name>lesePartner</method-name></method></method-permission><method-permission><role-name>Sachbearbeiter</role-name><method><ejb-name>Partner</ejb-name><method-name>*</method-name></method></method-permission>...</assembly-descriptor...
Programmatische Security
Die programmatische Security ermöglicht eine flexiblere Kontrolle über den Zugriff auf geschützte Ressourcen. Mittels der beiden Methoden isCallerInRole() und getCallerPrincipal() kann der Entwickler einer EJB prüfen, ob der aktuelle Benutzer sich in einer bestimmten Rolle befindet, bzw. er erhält die Security Principals des aktuellen Nutzers aus dem EJB Context. Die Methoden isUserInRole() und get UserPrincipal() stellen die gleiche Funktionalität für Servlets aus dem HttpServletRequest zur Verfügung.Listing 5public class PartnerDatenBean implements SessionBean{private SessionContext ctx;...public Object getPersonalData(){// ...// Prüfung, ob Aufrufer "Customer" istif( ctx.isCallerInRole("Customer"){Principal user = ctx.getCallerPrincipal();if( user != null){String name = user.getName();// Holen der Partnerdaten des Kunden// ...}}}...}
Listing 6...<enterprise-beans><session><ejb-name>PartnerDaten</ejb-name>...<security-role-ref><description>...</description><role-name>Customer</role-name><role-link>Kunde</role-link></security-role-ref>...</session>...</enterprise-beans>...<assembly-descriptor><security-role><description/><role-name>Kunde</role-name></security-role>...</assembly-descriptor>...
Beim Design der programmatischen Security ist darauf zu achten, dass es Fälle geben kann, in denen ein Benutzer mehrere Rollen einnimmt. Dies kann beabsichtigt, aber auch unbeabsichtigt geschehen. Beabsichtigt, wenn ein Benutzer wirklich mehrere Aufgaben wahrnimmt, die wiederum mehrere Rollen erfordern und unbeabsichtigt zum Beispiel durch eine versehentlich falsche Administration der Benutzer. Der Entwickler der Komponente muss danach diese Kombinationen berücksichtigen, auch wenn aus seiner Sicht die Rollen nicht zur gleichen Zeit erfüllt werden dürfen. Durch die konkrete Implementierung der Prüfungen im Programmcode nimmt der Entwickler eine Priorisierung der Rollen vor. Dies geschieht sowohl hinsichtlich der Reihenfolge der Abfragen (hier: Kunde, Außendienst, Sachbearbeiter oder umgekehrt: Sachbearbeiter, Außendienst, Kunde) als auch hinsichtlich deren Exklusivität, das heißt, es werden z.B. mehrere einfache if- Abfragen hintereinander gestellt oder es wird eine geschachtelte if-else- Abfrage erstellt.
Somit sind die Rollenrechte im Rahmen der programmatischen Security im Gegensatz zur deklarativen Security nicht unbedingt additiv. Man kann nicht davon ausgehen, dass zwei Benutzer, denen neben bereits vorhandenen Rollen zusätzlich die gleiche Rolle zugewiesen wurde, auch dieselben (Mindest-)Rechte erhalten. Die Gewährung von zusätzlichen Rechten kann demnach sogar dazu führen, dass einem Benutzer effektiv Rechte entzogen werden, beispielsweise, wenn eine exklusive Abfragereihenfolge Kunde, Außendienst, Sachbearbeiter implementiert wurde und einem Anwender zusätzlich zur Sachbearbeiterrolle auch noch die Kundenrolle zugewiesen. wird. In diesem Fall übt der Benutzer effektiv nur die Kundenrolle aus, weil sie zuerst gefunden wurde und die Suche dann abgebrochen wird.
Sind einem Benutzer mehrere Rollen zugewiesen, kann es passieren, dass der User über unterschiedliche Rollen für die gleiche Anwendung sich ausschließende Rechte erhält, z.B. “nur lesen” und gleichzeitig “ändern”, “Auszahlung” und gleichzeitig “Kontrolle der Auszahlung”. Um hier keine technischen, fachlichen oder gesetzlichen Vorgaben zu verletzen, müsste ein automatisiertes Regelwerk (Rules Engine) Prioritätenkonflikte oder Abhängigkeiten bzw. Unvereinbarkeiten auflösen. Derartige, sehr granular einstellbare Funktionalitäten inklusive eines Admin Workflow finden sich in IdM-Systemen (Identity Management). Diese Werkzeuge ermöglichen außerdem eine zentrale Verwaltung von Usern und Rollen über Systemgrenzen hinweg.
Die Problematik programmatischer Sicherheitsprüfungen liegt in der Verflechtung der Sicherheitsabfragen mit der Business-Logik und in der fehlenden Trans- parenz der gewährten Zugriffe. So führen Änderungen in den fachlichen Vorgaben an die Security direkt zu einer neuen Applikationsversion und damit zu einem Redeployment aller betroffenen Anwendungen. Der eigentliche Programmcode wird durch diese Verflechtung schwerer lesbar und die benötigten Sicherheitsabfragen stören den Programmfluss. Dieses Aufbrechen des Paradigmas “Separation of concerns” verschlechtert die Qualität des Designs und die Wartbarkeit der gesamten Architektur. Die Nachvollziehbarkeit der Zugriffsgewährung – also die Revisionssicherheit – ist nicht ganz ohne weiteres sicherzustellen. Jedoch erst durch den Einsatz der programmatischen Security kann vor dem Zugriff auf geschützte Komponenten eine Prüfung durchgeführt werden, zum Beispiel beim dynamischen Seitenaufbau.
Host-Anbindung
Bisher laufen alle Teile des entwickelten Systems im gleichen Sicherheitskontext ab, d.h., der Zugriff erfolgt im Application Server mittels der gleichen Sicherheitsattribute. Um aber die im Beispiel bestehenden Host-Systeme anzubinden, reicht dies nicht mehr aus. Im speziellen Fall besitzt jeder Sachbearbeiter und Mitarbeiter im Außendienst eine Benutzerkennung im Partner- bzw. Bestandssystem mit entsprechenden Rechten. Da nicht für alle Kunden eine Benutzerkennung im Host-System bereitgestellt werden kann und ein direkter Zugriff nicht vorgesehen ist, muss er auf andere Weise bereitgestellt werden. Die J2EE-Spezifikation sieht dafür die Java 2 Connector Architecture (J2C) vor [Sun J2EE Connector Architecture Specification, 1.5]. Hier soll nur ein kurzer Einblick gegeben werden, da dies eine sehr komplexe Problematik ist und den Rahmen dieses Artikels sprengen würde. Es bestehen verschiedene Möglichkeiten, den Zugriff auf diese Fremdsysteme abzusichern. Zum einen kann der Zugriff komplett über einen technischen User abgewickelt werden, unabhängig davon, welcher Benutzer die Bean aufruft. Dies geschieht mittels eines Security-Identity-Abschnitts innerhalb der EJB-Beschreibung des DD. Die dort angegebene Rolle im run-as-Abschnitt ist diejenige, unter der der Zugriff auf die Bean realisiert wird (Listing 7).Listing 7...<enterprise-beans>...<entity><ejb-name>PartnerdatenBackendsystem</ejb-name>...<security-identity><run-as><role-name>PDTechUser</role-name></run-as></security-identity>...</entity>...</enterprise-beans>...
Listing 8...<resource-ref><description/><res-ref-name>eis/partnerDatenConnection</res-ref-name>...<res-auth>Application</res-auth></resource-ref>...
if ( isUserInRole("Kunde")// greife auf Hostsystem mit technischen User zuelse// nimm aktuellen/aktiven User
Fazit und Ausblick
Bereits bei den vereinfachten fachlichen Zusammenhängen fällt auf, dass Sicherheitsaspekte schon frühzeitig in der Designphase mit einbezogen werden müssen und dass die J2EE-Sicherheitsinfrastruktur für den Entwickler offene Probleme hinterlässt. Weiterhin wird deutlich, dass die bestehenden Konzepte der J2EE Security eine Basis für sichere Anwendungen bilden, aber trotzdem noch nicht zur Sicherung komplexerer Umgebungen ausreichen. Auch ist die Administration der Rollen-Rechte-Zuordnungen sehr komplex und fehleranfällig und wird zurzeit nicht ausreichend durch geeignete Tools unterstützt. Identity-Management-Systeme bieten hier eine deutliche Erleichterung auf fachlicher Administrationsebene, weisen aber im technischen Zusammenspiel mit der Anwendungsinfrastruktur noch Mängel auf.Die J2EE-Plattform-Beschreibung definiert sechs Rollen, die alle zusammen die Sicherung einer Applikationslandschaft sicherstellen müssen. Der Tool Provider und der Container Provider stellen mit ihren Tools die Umsetzung der J2EE Security sicher. Der Application Assembler und der Deployer legen die Sicherheitsrichtlinien der Anwendung fest und definieren die benötigten Rollen zur Ausführung. Der Systemadministrator legt eine Abbildung zwischen Anwendungsrollen und den Gruppen des Benutzerverzeichnisses fest. Der Application Component Provider, also der Entwickler der Bean, sollte sich eigentlich nur noch um die fachliche Umsetzung der Business-Logik kümmern müssen. Er kann allerdings immer noch mittels programmatischer Security die Sicherstellung des korrekten Zugriffs auf Ressourcen beeinflussen.
Hinsichtlich der Anforderungen scheinen auch die neuen Spezifikationen von Enterprise JavaBeans 3.0 und J2EE 5.0 im Bereich Security nichts Neues zu bringen – außer natürlich, dass durch den Wegfall des DD die entsprechenden Einträge zur Sicherheit in den Annotations der Bean aufgehen werden. Inhaltlich ändert sich aber nichts daran, dass das Thema Sicherheit in einer heterogenen Systemumgebung auch zukünftig eine weite Spielwiese für Innovationsansätze bietet.
Jörg Kohmann ist als IT-Berater für Enterprise Java für Entwicklung, QM/QS und Testautomatisierung zuständig. Die drei Autoren arbeiten für die in Köln ansässige FSP Consulting & IT-Services. Wir freuen uns auf Anregungen und Kommentare ( J2EE-security@fsp-gmbh. com ).






