Nutzungsvorgaben Sicherheit

IFS-Logo Diese Seite ist ein Teil der IsyFact-Standards. Alle Inhalte der Seite, insbesondere Texte und Grafiken, sind urheberrechtlich geschützt. Alle urheberrechtlichen Nutzungs- und Verwertungsrechte liegen beim Bundesverwaltungsamt.

Creative Commons Namensnennung Die Nutzung ist unter den Lizenzbedingungen der Creative Commons Namensnennung 4.0 International gestattet.

Java Bibliothek / IT-System

Name Art Version

isy-sicherheit

Bibliothek

v3.3.x

isy-aufrufkontext

Bibliothek

v3.3.x

Deprecation

Dieser Baustein ist veraltet und wird in einem zukünftigen Release entfernt. Die Inhalte dieser Seite sollten zur Entwicklung neuer Anwendungen nicht mehr berücksichtigt werden. Stattdessen wird empfohlen, Nutzungsvorgaben Security zu verwenden.

1. Einleitung

Das Dokument Sicherheit - Konzept konzentriert sich auf die konzeptionellen Aspekte der Authentifizierung und Autorisierung.

Dieses Dokument beschreibt, wie der Baustein Sicherheit und die von ihm bereitgestellte Bibliothek isy-sicherheit verwendet werden, um die Autorisierung innerhalb von IT-Systemen umzusetzen. Es richtet sich an Entwickler, die ein IT-Systeme gemäß den Vorgaben der IsyFact mit der Fähigkeit zur Autorisierung ausstatten müssen und beschreibt, wie und in welchen Teilen einer Anwendung die Autorisierung umzusetzen ist.

Dazu beschreibt das Kapitel Grundkonzepte und Konfiguration zunächst die grundlegenden Konfiguration, um den Baustein in ein IT-System einzubinden.

Die folgenden Kapitel leiten durch die Funktionen des Bausteins Sicherheit. Zuerst wird die wichtigste Funktion - die Autorisierung in IT-Systemen - erklärt. Dann folgen weitere Themen:

Schließlich beschreibt das letzte Kapitel, wie siehe Entwickeln und Testen mit dem Baustein Sicherheit möglich ist.

2. Grundkonzepte und Konfiguration

Der Baustein Sicherheit definiert in der Bibliothek isy-sicherheit folgende, zentrale Schnittstellen:

  • Sicherheit: Einstiegspunkt in die Bibliothek

  • Berechtigungsmanager: Zugriff auf Informationen zur Berechtigung einzelner Anwender (Rollen & Rechte)

Wie im Dokument Sicherheit - Konzept beschrieben, fokussiert sich die Bibliothek isy-sicherheit auf die Zuordnung von Rechten zu Anwendern anhand ihrer Rollen. Die Authentifizierung und die Auflösung der Rollen geschieht in einem anderen Baustein der IsyFact und kann für die Benutzung der Bibliothek als gegeben angenommen werden.

Die folgende Abbildung zeigt die Schnittstellen und ihre Verbindung untereinander. Die zentrale Schnittstelle für den Zugriff auf Rollen und Rechte eines Anwenders ist der Berechtigungsmanager. Instanzen dieser Schnittstelle zur Autorisierung einer Anfrage werden über die Schnittstelle Sicherheit erzeugt.

sicherheit schnittstellen
Abbildung 1. Schnittstellen des Bausteins Sicherheit

Ein Berechtigungsmanager gibt Instanzen der Schnittstellen Recht und Rolle zurück. Anwender bekommen Rollen bereits an anderer Stelle zugewiesen. Für den Baustein Sicherheit ist diese Zuordnung fest vorgegeben und nicht änderbar. Anhand seiner Rollen werden dem Anwender durch das IT-System Rechte zugewiesen. Diese Zuordnung erfolgt über eine Konfigurationsdatei.

Die Implementierung des Aufrufkontextes richtet sich nach dem verwendeten IsyFact-Baustein zur Authentifizierung.

2.1. Maven-Konfiguration

Zur Verwendung des Bausteins Sicherheit genügt es, die folgenden zwei Bibliotheken aus der IsyFact als Maven-Abhängigkeiten einzubinden.

Listing 1. Einbindung des Bausteins Sicherheit
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>de.bund.bva.isyfact</groupId>
            <artifactId>isy-sicherheit</artifactId>
        </dependency>
        <dependency>
            <groupId>de.bund.bva.isyfact</groupId>
            <artifactId>isy-aufrufkontext</artifactId>
        </dependency>
    </dependencies>
</dependencyManagement>

2.2. Spring-Konfiguration

Zur Konfiguration der zentralen Schnittstellen müssen Spring Beans definiert werden. Die Autokonfiguration von isy-sicherheit führt die folgende Konfiguration durch:

  • Der zur Verwendung der Annotation @Gesichert notwendige Interceptor wird konfiguriert.

  • Die normalerweise in Spring nicht verfügbaren Bean Scopes thread und request werden registriert.

  • Die Bean für die AufrufKontextFactory wird konfiguriert.

  • Die Bean für die Komponente SicherheitAdmin wird konfiguriert, wenn ein AccessManager-Bean vorhanden ist.

Die Beans für Sicherheit und den AufrufKontextVerwalter werden in einer separaten Spring-Konfigurationsklasse manuell konfiguriert. Ein Beispiel dazu findet sich in Listing 2. Die fehlenden Typparameter sind in der echten Konfiguration zu ergänzen. Des Weiteren muss eine Bean für den verwendeten AccessManager existieren.

Listing 2. Konfiguration für Spring
@Configuration
public class SicherheitConfiguration {

    @Bean
    @Scope(value="request", proxyMode = ScopedProxyMode.TARGET_CLASS)
    public AufrufKontextVerwalter aufrufKontextVerwalter() {
        return new AufrufKontextVerwalterImpl();
    }

    @Bean
    public Sicherheit sicherheit(AufrufKontextVerwalter aufrufKontextVerwalter, AufrufKontextFactory aufrufKontextFactory, AccessManager accessManager, IsySicherheitConfigurationProperties properties) {
        return new SicherheitImpl("/resources/sicherheit/rollenrechte.xml", aufrufKontextVerwalter, aufrufKontextFactory, accessManager, properties);
    }

Hierbei werden auch direkt die Spring Beans zur Verwaltung der Aufrufkontexte und zur Überwachung des Bausteins konfiguriert.

Die Implementierung der Schnittstelle AccessManager stellt einer der IsyFact-Bausteine für die Authentifizierung bereit. Eine Beschreibung der Konfiguration findet sich in den jeweiligen Nutzungsvorgaben.

2.3. Caching von Authentifizierungen

Der Baustein liefert eine Standard-Konfiguration für das Caching von Authentifizierungen an. Der Standardwert für die Lebensdauer von Cache-Elementen liegt bei 5 Minuten (300 Sekunden), die maximale Anzahl an Elementen im Cache bei 1000. Wird die maximale Anzahl an Elementen überschritten, löscht der Cache die am längsten nicht mehr verwendeten Elemente zuerst.

Die Konfiguration des Caches erfolgt über die betriebliche Konfiguration in application.properties. Hierzu sind folgende Parameter zu setzen:

isy.sicherheit.cache.ttl=300
isy.sicherheit.cache.maxelements=1000

Wird der Parameter isy.sicherheit.cache.ttl auf 0 gesetzt oder nicht konfiguriert, ist der Cache deaktiviert. Wird der Parameter isy.sicherheit.cache.maxelements auf 0 gesetzt, werden beliebig viele Elemente im Cache vorgehalten.

2.4. Konfiguration von Rollen und Rechten

Jede Geschäftsanwendung spezifiziert im Rahmen ihrer Systemspezifikation Rechte und bildet diese auf fachliche und technische Rollen ab. Bei der technischen Umsetzung müssen alle spezifizierten Rollen und Rechte konfiguriert und korrekt zugeordnet werden. Dies geschieht in der statischen Konfiguration in der Datei /resources/sicherheit/rollenrechte.xml. Der Baustein liefert ein XML-Schema für den Aufbau der Konfigurationsdatei mit.

Dieser Zusammenhang wird mit einem Beispiel verdeutlicht: Die Geschäftsanwendung X spezifiziert zwei Rechte, DialogA.Aufrufen und DialogB.Aufrufen. Aus diesen werden zwei fachliche Rollen gebildet:

  • FAX_DialogNutzerA darf nur Dialog A aufrufen,

  • FAX_DialogNutzerAlle darf Dialog A und Dialog B aufrufen.

Dieses Beispiel führt zu folgender Konfigurationsdatei.

Listing 3. Beispielhafte Definition von Rollen und Rechten
<tns:Anwendung AnwendungsId="GeschäftsanwendungX"
    xmlns:tns="http://www.isyfact.de/RollenRechteSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.isyfact.de/RollenRechteSchema RollenRechteSchema.xsd ">

    <!-- Definition der Rechte -->
    <tns:rechte>
        <tns:rechtId Id="DialogA.Aufrufen" />
    </tns:rechte>

    <tns:rechte>
        <tns:rechtId Id="DialogB.Aufrufen" />
    </tns:rechte>

    <!-- Definition der Rollen -->
    <tns:rollen RolleId="FAX_DialogNutzerA">
        <tns:rechtId Id="DialogA.Aufrufen" />
    </tns:rollen>

    <tns:rollen RolleId="FAX_DialogNutzerAlle">
        <tns:rechtId Id="DialogA.Aufrufen" />
        <tns:rechtId Id="DialogB.Aufrufen"/>
    </tns:rollen>
</tns:Anwendung>

2.5. Zusammenhang von Rechten und Rollen

Innerhalb jeder Rolle werden gemäß Spezifikation die zugeordneten Rechte festgelegt. Rollen können überlappende Teilmengen von Rechten enthalten.

Die Konfiguration muss die folgenden Anforderungen erfüllen:

  • Es sind alle in der Geschäftsanwendung spezifizierten Rechte definiert.

  • Es sind alle in der Geschäftsanwendung spezifizierten Rollen definiert.

Werden in Überprüfungen Rollen oder Rechte verwendet, die hier nicht definiert sind, wird ein technischer Fehler erzeugt. Die Konfiguration gibt also verlässlich Auskunft darüber, welche Rollen und Rechte in der Geschäftsanwendung überprüft werden.

Der Baustein Sicherheit ermöglicht eine Autorisierung nur auf Basis von Rechten, nicht von Rollen. Jeder Rolle muss also zumindest ein Recht zugeordnet werden, um anhand dessen eine Autorisierung durchführen zu können. Werden im Lebenszyklus der Geschäftsanwendung weitere Rollen (z.B. für neu hinzukommende Akteure) spezifiziert und mit bestehenden Rechten ausgestattet, sind neben den Änderungen in der Konfigurationsdatei keine weiteren Änderungen notwendig.

3. Umsetzung der Autorisierung

Im Dokument IsyFact Referenzarchitektur IT-Systeme werden drei Möglichkeiten des Zugriffs auf ein IT-System: Grafische Oberflächen (GUIs), Services und Batches beschrieben. Für alle diese Möglichkeiten gilt, dass der Aufrufkontext so früh wie möglich aus der eingehenden Anfrage auszulesen und im Verwalter (d.h. dem Spring Bean AufrufKontextVerwalter) zu speichern ist. Nur so kann sichergestellt werden, dass alle Prüfungen auf Rechte korrekt funktionieren. Dazu bietet der Baustein Sicherheit einige Hilfsmittel an. Durch Verwendung dieser Hilfsmittel lässt sich die Autorisierung weitgehend deklarativ und transparent abwickeln. Die Autorisierung wird zum Aspekt des Querschnitts und beschränkt sich auf deklarative Elemente des Quellcodes. Fachliche Schnittstellen werden von Parametern befreit und Prüfungen auf vorhandene Rechte können nur schwer vergessen werden.

3.1. Autorisierung in der GUI

Beim Aufruf grafischer Oberflächen wird der Aufrufkontext über einen AbstractAuthenticationProcessingFilter aus Spring Security ausgelesen. Die Autorisierung geschieht auf Ebene der Flows aus Spring Webflow. Weitere Details zur Umsetzung der Autorisierung in der GUI sind im Dokument Detailkonzept Komponente WebGUI) beschrieben.

3.1.1. Spring-Konfiguration

Zur Absicherung der Flows sowie zum Auslesen des Aufrufkontextes ist folgende Spring-Konfiguration erforderlich.

Listing 4. Spring-Konfiguration für Autorisierung in der GUI
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.addFilterBefore(processingFilter(), AbstractPreAuthenticatedProcessingFilter.class);
        http.exceptionHandling().authenticationEntryPoint(preAuthenticatedProcessingFilterEntryPoint());
    }

    @Bean
    public AuthenticationEntryPoint preAuthenticatedProcessingFilterEntryPoint() {
        return new Http403ForbiddenEntryPoint();
    }

    @Bean
    public AccessDecisionManager accessDecisionManager(Sicherheit sicherheit) {
        return new DelegatingAccessDecisionManager(sicherheit);
    }

    @Bean
    public Filter processingFilter() {
        ...
    }

    @Bean
    public AuthenticationProvider authenticationProvider() {
        ...
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) {
        auth.authenticationProvider(authenticationProvider());
    }

Wichtig ist, dass sich der Filter an der Position PRE_AUTH_FILTER befindet. Greift er nicht, weil z.B. keine gültige Authentifizierung vorliegt, wird die Anfrage direkt mit einem HTTP-Statuscode 403 (Forbidden) beantwortet. Dies stellt das Bean preAuthenticatedProcessingFilterEntryPoint sicher.

Die Implementierung der Beans authenticationProvider sowie processingFilter stellt einer der IsyFact-Bausteine für die Authentifizierung bereit. Eine Beschreibung der Konfiguration findet sich in den jeweiligen Nutzungsvorgaben.

3.1.2. Absicherung der Flows

Ein Webflow wird durch das Tag <secured/> abgesichert. Das Tag kann den ganzen Flow, einzelne Zustände oder einzelne Transitionen betreffen und ermöglicht so eine feingranulare Vergabe von Rechten. Im Parameter attributes stehen die für den Zugriff erforderlichen Rechte.

Listing 5. Absichern eines Flows, Zustands und einer Transition
<flow>
    <secured attributes="DialogA.Aufrufen" />

    <view-state id="sichererZustand">
        <secured attributes="DialogA.Aufrufen" />
    </view-state>

    <transition on="sichererZustand" to="sichererZustand">
        <secured attributes="DialogA.Aufrufen, DialogB.Aufrufen" />
    </transition>
</flow>

3.2. Autorisierung an einer Service-Schnittstelle

Beim Aufruf von Service-Schnittstellen wird der Aufrufkontext über Annotationen und Interceptoren an den Service-Methoden ausgelesen. Anhand der Informationen aus dem Aufrufkontext geschieht die Autorisierung auf ähnliche Art und Weise. Zentral hierfür sind die Annotationen @StelltAufrufKontextBereit und @Gesichert. Alle Annotationen nutzen Spring AOP und sind daher nur an Methoden mit öffentlicher Sichtbarkeit (public) von Spring-Beans funktionsfähig. Weitere Details zur Umsetzung der Autorisierung an Service-Schnittstellen sind in den Nutzungsvorgaben der Bausteine zur Umsetzung von Services beschrieben.

3.3. Autorisierung eines Batches

Beim Aufruf von Batches stellt der Batchrahmen das Auslesen des Aufrufkontextes und die Autorisierung des Batches sicher. Zur Autorisierung ist im Batchrahmen bereits die Möglichkeit enthalten, einen Anwender zu konfigurieren. Weitere Details zur Umsetzung der Autorisierung bei Batches sind im Dokument Detailkonzept Komponente Batch beschrieben.

3.3.1. Konfiguration

Die Absicherung von Batches erfolgt über die betriebliche Konfiguration des Batches. Dazu muss die Implementierung des Batches über die Methode getAuthenticationCredentials() des Interfaces BatchAusfuehrungsBean die Daten zur Authentifizierung bereitstellen. Diese werden als Properties in die Property-Datei des Batches eingetragen. Ein Beispiel für Properties zur Absicherung eines Batches zeigt siehe Listing Batchbenutzer.

Listing 6. Konfiguration zur Autorisierung von Batches
batch.anwenderkennung = FAX_BAT_Fristenkontrolle
batch.anwenderpasswort = <secret>
batch.anwenderbehoerde = 4200

Neben der Kennung und dem Passwort kann auch eine Behörde (über eine ID oder Kennzeichen) angegeben werden, falls diese Information zur Authentifizierung oder zur Ermittlung der Rollen benötigt wird.

3.3.2. Absicherung eines Batches

Damit der Benutzer bei der Ausführung des Batches authentifiziert wird, muss die Methode initialisieren der Klasse BatchAusfuehrungsBean mittels der Annotation @Gesichert geschützt werden. Der Batchrahmen authentifiziert den Benutzer anhand der betrieblichen Konfiguration, erstellt einen neuen Aufrufkontext und speichert ihn im Verwalter. Der eigentliche Prozess der Authentifizierung sowie die Ermittlung der Rollen sind für Nutzer des Batchrahmens vollständig transparent.

Des Weiteren muss die Methode getAuthenticationCredentials der Klasse BatchAusfuehrungsBean implementiert werden, damit der Batchrahmen den korrekten Anwender zur Authentifizierung nutzt. So ist es möglich, neben dem üblichen Auslesen der Information aus der Konfiguration weitere Berechnungen oder Default-Werte anzugeben.

Listing 7. Implementierungsbeispiel für die Versorgung des Batchrahmens mit Benutzerdaten
@Override
public AuthenticationCredentials getAuthenticationCredentials(
    BatchKonfiguration konfiguration) {

    AuthenticationCredentials auth = new AuthenticationCredentials();

    auth.setBehoerdenkennzeichen(
        konfiguration.getAsString("batch.<batchname>.anwenderbehoerde"));
    auth.setBenutzerkennung(
        konfiguration.getAsString("batch.<batchname>.anwenderkennung"));
    auth.setPasswort(
        konfiguration.getAsString("batch.<batchname>.anwenderpasswort"));

    return auth;
}

Ab diesem Punkt kann der Batch jederzeit auf den Aufrufkontext zugreifen, um im Zuge des Batchlaufes Berechtigungsprüfungen vorzunehmen oder Services von Nachbarsystemen (vgl. Aufruf von Nachbarsystemen) unter Bereitstellung des Aufrufkontextes aufzurufen.

In Ausnahmefällen ist es auch möglich, einen Batch zu implementieren, der ohne authentifizierten Benutzer laufen soll. Dies ist allerdings nur möglich, wenn bei Aufrufen des Anwendungskerns keine Berechtigungsprüfungen stattfinden und keine Nachbarsystemschnittstellen aufgerufen werden. In diesem Fall muss die Methode getAuthenticationCredentials so implementiert werden, dass sie null zurückgibt.

3.4. Autorisierung im Anwendungskern

Im Regelfall wird die Autorisierung einer Anfrage an den Schnittstellen der Anwendung durchgeführt. Es ist jedoch bei Bedarf auch möglich, Prüfungen innerhalb des Anwendungskerns durchzuführen.

3.4.1. Autorisierung an Methoden des Anwendungskerns

An den Schnittstellen des Anwendungskerns können durch Verwendung der Annotation @Gesichert einzelne Methoden deklarativ abgesichert werden. Die Verwendung funktioniert genauso wie bei der Autorisierung an einer Service-Schnittstelle. Die wichtigste Voraussetzung für das Funktionieren dieses Ansatzes ist, dass im Rahmen des Aufrufs der Anwendung der Aufrufkontext bereits gefüllt wurde.

3.4.2. Autorisierung in Methoden des Anwendungskerns

Berechtigungsprüfungen können ebenso an beliebiger Stelle im Quellcode erfolgen. Dazu stellt der Baustein Sicherheit über die Schnittstelle Berechtigungsmanager entsprechende Funktionen bereit. Der Berechtigungsmanager ist ein Container für die Rechte und Rollen des aktuell authentifizierten Anwenders.

Zur Erzeugung eines Berechtigungsmanagers muss das Spring Bean des Typs Sicherheit verfügbar sein. Die folgenden zwei Methoden des Beans erzeugen einen Berechtigungsmanager:

getBerechtigungsManager()

Die Methode ermittelt die Informationen zum Anwender und zugehörige Rollen aus dem Aufrufkontext. Diese Methode muss verwendet werden, wenn der Anwender bereits anderweitig authentifiziert und der Aufrufkontext bereits gefüllt wurde.

getBerechtigungsManagerUndAuthentifiziere(AufrufKontext unauthentifzierterAufrufkontext)

Die Methode authentifiziert den Anwender zunächst und füllt mit dem Ergebnis den übergebenen Aufrufkontext. Welche Informationen für eine erfolgreiche Authentifizierung benötigt werden, hängt von dem dafür eingesetzten IsyFact-Baustein ab. Diese Methode muss verwendet werden, wenn der Anwender noch nicht anderweitig authentifiziert wurde.

Zur Formulierung von Berechtigungsprüfungen stehen folgende Methoden des Berechtigungsmanagers zur Verfügung:

Set<Rolle> getRollen()

Liefert die Menge aller Rollen des Anwenders.

Set<Recht> getRechte()

Liefert die Menge aller Rechte des Anwenders.

Recht getRecht(String recht)

Gibt das Recht mit dem angegebenen Namen zurück, falls es der Anwender besitzt.

boolean hatRecht(String recht)

Ermittelt, ob der Anwender ein bestimmtes Recht besitzt.

void pruefeRecht(String recht)

Prüft, ob der Anwender das angegebene Recht besitzt und erzeugt einen Fehler vom Typ AutorisierungFehlgeschlagenException, wenn das nicht der Fall ist.

3.5. Autorisierung innerhalb des Regelwerks

In einem Regelwerk sind oft Prüfungen zur Sichtbarkeit, Melde- und Auskunftsrechten sowie von Primärdaten abhängigen Rechten umzusetzen. Hierbei handelt es sich meist nicht um eine Autorisierung gegen Rollen, sondern um datenbezogene Prüfungen (z.B. Prüfung der Behördengruppe des Anwenders). Für diese Fälle stellt der Baustein Sicherheit keine Funktionalität bereit. Es wird empfohlen, solche Regeln direkt im Regelwerk zu hinterlegen.

Soll in einem Regelwerk doch auf Rollen geprüft werden, bietet sich die Lösung aus dem Abschnitt Anwendungskern - Autorisierung in Methoden an.

3.6. Autorisierung in asynchronen Prozessen

Einige Anwendungsfälle (z.B. Nachrichtenempfang über einen Mailserver) verwenden asynchrone Prozesse. Diese Prozesse starten nicht aufgrund einer Anfrage eines Anwenders, sondern ereignis- oder zeitgesteuert. Somit geht diesen Prozessen im Moment der Bearbeitung keine Benutzeranfrage voraus. Daher kann die Bearbeitung im Regelfall nicht mit dem Aufrufkontext eines anfragenden Benutzers durchgeführt werden. Stattdessen wird zum Start des Prozesses ein hinreichend berechtigter Anwender (technischer Anwender bzw. System) verwendet. Auch hier bietet sich die Lösung aus dem Abschnitt Anwendungskern - Autorisierung in Methoden an.

4. Aufrufen von Nachbarsystemen

Ein Nachbarsystem, das aufgerufen wird, erwartet einen gültigen, vollständigen Aufrufkontext vorzufinden. Der Aufrufer muss daher einen Aufrufkontext mitliefern. Im Regelfall soll dabei der Aufrufkontext der originären Anfrage verwendet und unverändert weitergeleitet werden.

Zum Aufruf des Nachbarsystems werden entweder die mit dem Nachbarsystem bereit gestellten Service-Client-Bibliotheken oder direkt die Schnittstelle des Nachbarsystems verwendet. Wenn ein Nachbarsystem über eine spezifische Client-Bibliothek aufgerufen wird, so enthält diese bereits die Logik zur Weiterleitung des Aufrufkontextes. Wenn ein Nachbarsystem direkt aufgerufen wird, so ist die Weiterleitung des AufrufKontextes manuell zu leisten. Hierbei muss immer das Transportobjekt (AufrufKontextTo) der Bibliothek isy-serviceapi-sst verwendet werden, da in der Regel nur dieses im Nachbarsystem korrekt deserialisiert werden kann.

Listing 8. Weiterleitung des Aufrufkontextes beim Aufruf eines Nachbarsystems
AufrufKontext aufrufKontext = aufrufKontextVerwalter.getAufrufKontext();
AufrufKontextTo transportobjekt = beanMapper.map(aufrufKontext, AufrufKontextTo.class);
nachbarService.aufruf(transportobjekt, weitere, parameter);

Listing 8 enthält folgende Schritte:

  • Der Aufrufkontext der Anwendung wird vom Spring Bean aufrufKontextVerwalter abgerufen.

  • Es wird ein Bean-Mapping verwendet, um das für den Aufruf zu verwendende Transportobjekt zu erstellen.

  • Das erzeugte Transportobjekt wird an die Schnittstelle des Nachbarsystems übergeben.

5. Verwendung der Korrelations-ID

Der Aufrufkontext enthält neben Informationen zur Authentifizierung und Rollen auch die Korrelations-ID, die alle Log-Ausgaben einer Anfrage durch eine gemeinsame ID kennzeichnet – auch wenn die Anfrage mehrere IT-Systeme durchläuft. Dies erfordert eine korrekte Entgegennahme, Verwendung und Weiterleitung der Korrelations-ID über alle Service-Aufrufe hinweg. Details zum Aufbau der Korrelations-ID sind im Dokument Nutzungsvorgaben Logging beschrieben.

Eine Korrelations-ID wird entweder bereits im eingehenden Aufruf mitgeliefert, oder muss neu erzeugt werden. Sie wird stets im MDC (Mapped Diagnostic Context) der IT-Systeme abgelegt.

Eine Korrelations-ID wird folgendermaßen manuell erzeugt.

Listing 9. Manuelle Erzeugung einer Korrelations-ID
String korrelationsId = UUID.randomUUID().toString();
MdcHelper.pushKorrelationsId(korrelationsId);

Neben dem MDC wird die Korrelations-ID ebenfalls im Aufrufkontext hinterlegt. So wird die Korrelations-ID beim Aufruf eines Nachbar­systems als Bestandteil des Aufrufkontextes automatisch weitergeleitet.

Im Fall einer zentralen Authentifizierung kümmert sich die mitgelieferte Implementierung des Bausteins Sicherheit um die Entgegennahme der Korrelations-ID.

Im Fall der lokalen Authentifizierung wird keine Korrelations-ID von außen übertragen und das IT-System muss für jede Anfrage eine neue Korrelations-ID manuell erzeugen (s. Listing 9).

6. Verwenden anwendungsspezifischer Aufrufkontexte

Gelegentlich möchte eine Geschäftsanwendung zusätzliche Informationen im Aufrufkontext ablegen. Hierzu kann von der Standard-Implementierung (de.bund.bva.isyfact.aufrufkontext.impl.AufrufKontextImpl) geerbt und die neue, anwendungsspezifische Klasse um zusätzliche Attribute erweitert werden.

Die anwendungsspezifische Implementierung muss in der Spring-Konfiguration hinterlegt werden.

Listing 10. Verwendung eines anwendungsspezifischen Aufrufkontext
@Bean
public AufrufKontextFactory<MeinAufrufKontextImpl> aufrufKontextFactory() {
    AufrufKontextFactory<MeinAufrufKontextImpl> aufrufKontextFactory = new AufrufKontextFactory<>();
    aufrufKontextFactory.setAufrufKontextKlasse(MeinAufrufKontextImpl.class);

    return aufrufKontextFactory;
}

Die zusätzlichen Attribute können bereits beim automatischen Befüllen des Aufrufkontextes gesetzt werden. Dazu kann eine anwendungsspezifische AufrufKontextFactory verwendet werden.

7. Überwachung des Bausteins Sicherheit

Der Baustein Sicherheit bietet über die Schnittstelle SicherheitAdmin die Möglichkeit, die Verfügbarkeit des jeweils verwendeten AccessManager kontinuierlich zu prüfen. Dazu gibt es folgende Methode:

boolean pingAccessManager()

Prüft die Erreichbarkeit des AccessManager mittels einer trivialen Anfrage.

Diese Methode kann in den Watchdog des IT-Systems (siehe Konzept Überwachung) eingebunden werden.

8. Entwickeln und Testen ohne externe Authentifizierung

In der Entwicklung und im Test steht nicht immer ein externes System zur Authentifizierung zur Verfügung. Hierzu stellt der Baustein Sicherheit einen konfigurierbaren Stub für die Klasse Aufruf­KontextVerwalter bereit. Der Stub simuliert das Vorliegen eines Aufrufkontextes (mit Informationen zu einem Anwender und dessen Rollen), ohne dass dieser von außen übergeben werden muss. Er gibt bei jeder Anfrage statisch konfigurierte Daten eines Anwenders zurück.

Die Konfiguration des Stubs sollte in einem eigenen Spring-Profil für die Entwicklung und den Test erfolgen.
Listing 11. Konfiguration des Stubs
@Bean
public AufrufKontextVerwalter aufrufKontextVerwalterStub(AufrufKontextFactory aufrufKontextFactory) {
    AufrufKontextVerwalterStub stub = new AufrufKontextVerwalterStub();
    stub.setRollen("FAX_DialogNutzerA", "FAX_DialogNutzerAlle");
    stub.setDurchfuehrenderBenutzerKennung("<kennung>");
    stub.setDurchfuehrenderBenutzerPasswort("<passwort>");
    stub.setDurchfuehrendeBehoerde("<behoerde>");
    stub.setAufrufKontextFactory(aufrufKontextFactory);

    return stub;
}

Neben den gezeigten Eigenschaften lassen sich auch alle weiteren Eigenschaften des Aufrufkontextes konfigurieren. Mit der Eigenschaft festerAufrufKontext lässt sich darüber hinaus steuern, ob bei jeder Anfrage derselbe Aufrufkontext (true) oder jedes Mal eine neue Instanz mit den gleichen, konfigurierten Werten (false) zurückgegeben wird.

9. Anhang

9.1. Anhang A: Standard-Cache-Konfiguration

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="false" monitoring="autodetect" dynamicConfig="true">
  <!--
  Pflicht: Standard-Einstellungen fuer Caches.
  Diese Einstellungen werden verwendet,
  sofern Caches programmatisch erzeugt werden mithilfe von
  CacheManager.add(String cacheName).
  Der defaultCache hat den impliziten Namen "default",
  welcher einer reservierter
  Cache-Name ist.
  -->
  <defaultCache
    maxEntriesLocalHeap="1000"
    eternal="false"
    timeToLiveSeconds="300"
    timeToIdleSeconds="0"
    overflowToDisk="false"
    memoryStoreEvictionPolicy="LRU" />
  <cache
    name="authentifizierungen"
    maxEntriesLocalHeap="1000"
    eternal="false"
    timeToLiveSeconds="300"
    timeToIdleSeconds="0"
    overflowToDisk="false"
    memoryStoreEvictionPolicy="LRU" />
</ehcache>

9.2. Anhang B: Rollen-Rechte-Schema

Im Folgenden ist der Inhalt der Datei RollenRechteSchema.xsd wiedergegeben, die das Format der Konfigurationsdatei für Rollen und Rechte (rollenrechte.xml) festlegt.

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://www.isyfact.de/RollenRechteSchema"
    xmlns:tns="http://www.isyfact.de/RollenRechteSchema"
    elementFormDefault="qualified">
  <include schemaLocation=""></include>
  <complexType name="Rolle">
    <sequence>
      <element name="rechtId" type="tns:RechtId" minOccurs="0" maxOccurs="unbounded"/>
    </sequence>
    <attribute name="RolleId" type="string" use="required"/>
  </complexType>
  <complexType name="Recht">
    <sequence>
      <element name="rechtId" type="tns:RechtId" minOccurs="1" maxOccurs="1"/>
    </sequence>
  </complexType>
  <element name="Anwendung" type="tns:Anwendung"/>
  <complexType name="Anwendung">
    <sequence>
      <element name="rollen" type="tns:Rolle" minOccurs="1" maxOccurs="unbounded"/>
      <element name="rechte" type="tns:Recht" minOccurs="0" maxOccurs="unbounded"/>
    </sequence>
    <attribute name="AnwendungsId" type="string" use="required"/>
  </complexType>
  <complexType name="RechtId">
    <attribute name="Id" type="string" use="required"/>
  </complexType>
</schema>

9.3. Anhang C: Verwaltung von Rollen im Benutzerverzeichnis

Damit Rollen auch an Benutzer im Benutzerverzeichnis vergeben werden können, müssen die Rollen in das Benutzerverzeichnis eingespielt werden.

Dies erfolgt für Testsysteme und das Produktivsystem (im Rahmen von Inbetriebnahmen) per Import-Batch, bei dem ein Excel-Dokument mit zu importierenden Rollen in das Benutzerverzeichnis geladen wird. Der Import ist der einzige Weg, um Rollen hinzuzufügen.

Mit dem Batch ist es möglich Rollen hinzuzufügen (Add), zu verändern (Upd) oder zu löschen (Del).

Das Excel-Dokument zum Einspielen von Rollen benötigt ein Arbeitsblatt „Rollen“ und hat folgendes Format:

Tabelle 1. Einspielen von Rollen in das Benutzerverzeichnis (Beispiel)
Aktion Rollenlabel Rollenname Rollentyp Unterrollen

Add

BNVZ_Rolle1

BNVZ_Rolle1

fachlich

BHVZ_Schnittstellennutzer

Upd

BNVZ_Rolle2

BNVZ_Rolle2

fachlich

BHVZ_Schnittstellennutzer,
SVZ_Schnittstellennutzer

Del

BNVZ_Rolle3

Zusätzlich zu den oben abgebildeten Spalten enthält das Excel-Dokument die folgenden weiteren Spalten, deren Inhalt bereits im Dokument Sicherheit - Konzept beschrieben wurde:

  • Rollenbeschreibung

  • SichtbarkeitAnwender

  • SichtbarkeitSystemeExtern

  • SichtbarkeitSystemeIntern

Nach der letzten zu importierenden Zeile des Arbeitsblatts sollte eine Zeile mit der Aktion End eingefügt werden. Dies verbessert die Performance beim Import. Bei allen anderen Werten in der Spalte „Aktion“ wird die Zeile ignoriert.

Zusätzlich kann das Excel-Dokument ein weiteres Tabellenblatt „Systeme“ enthalten. Dieses folgt demselben Schema zum Hinzufügen (Add), Ändern (Upd) und Löschen (Del) von Einträgen. Es dient dazu, die Systeme (interne und ggf. auch externe) zu pflegen, wie im Dokument Sicherheit - Konzept beschrieben. Systeme sind im Benutzerverzeichnis spezialisierte Benutzer. Sie haben daher alle Attribute der Entitäten ETY_Benutzer, ETY_System und ETY_Rollenträger.

Das Tabellenblatt „Systeme“ enthält die folgenden Spalten, deren Inhalte in den Attributbeschreibungen im Datenmodell des Benutzerverzeichnisses erklärt werden:

  • Aktion: Add, Upd, Del oder End

  • InterneKennung

  • Name

  • Status: gueltig oder ungueltig

  • BHKNZ: Kennzeichen der Organisation (Behördenkennzeichen) durch die das System genutzt wird.

  • Anbieter

  • Intern: true oder false

  • PasswortPlain: Passwort im Klartext, wird beim Import verschlüsselt

  • Anlagedatum

  • PasswortLaeuftAb: true oder false (für Systeme sinnvollerweise false)

  • PasswortLetzteAenderung

  • PasswortMussGeaendertWerden: true oder false

  • Beschreibung

  • LetzteAenderung

  • LetzteAenderungDurch

  • RollenDirekt: Kommaseparierte Liste der direkt zugeordneten fachlichen Rollen des Systems

Motivation für die Updatefunktion

Die Löschung einer bereits verwendeten Rolle kann große Auswirkungen auf die Rollenzuordnung des Benutzerbestandes haben, da diese allen besitzenden Benutzern weggenommen werden muss. Eine nachträgliche hinzugefügte Ersatzrolle müsste dann manuell administrativ den Benutzern wieder zugeordnet werden. Das ist nicht praktikabel. Daher wird für eine Aktualisierung einer Rolle das Ändern einer Rolle (Upd) angeboten. Die Rollendefinition wird dabei verändert, während die Rolle allen Benutzern und Nutzergruppen zugeordnet bleibt.

Einschränkungen für den Rollenimport

Folgende Einschränkungen bestehen beim Import von Rollen:

  • Erzeugen einer Rolle:

    • Der Name der Rolle darf noch nicht vergeben sein.

    • Eine fachliche Rolle darf nur technische Unterrollen haben. Im Excel-Dokument referenzierte Unterrollen müssen im Datenbestand bereits bekannt sein, bzw. im Excel-Dokument weiter oben stehen.

  • Ändern einer Rolle

    • Der Typ der Rolle (fachlich, technisch) kann nicht geändert werden.

    • Der (neue) Name der Rolle darf nicht bereits an eine andere Rolle vergeben sein.

  • Löschen der Rolle: Handelt es sich um eine technische Rolle, so darf diese Rolle zum Zeitpunkt der Löschung nicht mehr in einer anderen Rolle als Unterrolle verwendet werden. Die fachliche Rolle ist zunächst explizit zu löschen.

9.3.1. Verwaltung des Rollen-Masters

Die Rollendefinition der Anwendungslandschaft (in Form eines Excel-Dokuments) ist ein zentral zu verwaltendes Dokument, welches zur Befüllung von Testumgebungen verwendet wird. Es repräsentiert den insgesamt verfügbaren Rollenvorrat über alle Anwendungssysteme. Das Dokument trägt den Namen Rollen-Master.

Änderungen am Rollenmodell im Rahmen von Wartungsarbeiten werden in dieses Dokument übertragen. Zum Einspielen einer Rollenänderung in ein produktiv- oder Testsystem wird jedoch ein passendes Rollen-Delta (ebenfalls Excel) verwendet, welches nach einer Inbetriebnahme gelöscht wird.

Die Koordination der Änderungen am Rollen-Master obliegt dem Release-Verantwortlichen.

9.3.2. Releases und Rollen-Deltas

Für jedes Release, welches Änderungen an dem Rollenbestand der Anwendungslandschaft vornimmt, werden ein oder mehrere Rollen-Deltas aufbauend auf dem Rollen-Master erstellt, die das Rollenmodell vom Ist-Zustand in den Soll-Zustand überführen. Die Rollen-Deltas werden in den Quellen des zugehörigen IT-Systems im Verzeichnis /src/main/skripte/sicherheit abgelegt

Diese Rollen-Deltas werden auf Testumgebungen im Rahmen der Integrationstests getestet und mit dem Release ausgeliefert. Die Reihenfolge, in der sie eingespielt werden müssen, wird im Releaseletter für die Rollen-Deltas definiert. Sie hängt von den Abhängigkeiten der Systeme ab, die in den Releaselettern der jeweiligen Systeme beschrieben sind.