DOAG Deutsche ORACLE-Anwendergruppe e.V.
|  
   

Write Secure Code - Don't Write Security Code: Die Autorisierung deklarativ lösen

Abbildung 2: Mehrere XACML-PEPs greifen auf denselben PDP zu.

Abbildung 3: Geringe Latenz und hoher Durchsatz: eine Applikation mit eingebettetem PDP.

Bei einem programmatischen Ansatz ist die Zugriffssteuerung im Programm kodiert, sodass die Applikation selbst diese Aufgabe übernimmt. Bei einer deklarativen Lösung werden die Autorisierungsregeln zentral außerhalb der Applikation abgelegt.

Dies bringt gewisse Vorteile mit sich: Erstens können die Autorisierungsregeln unabhängig von der Applikation geändert werden. Zweitens können auch mehrere Applikationen ein und dieselbe Datenbank als Grundlage für Autorisierungen verwenden. Zentralisierte Policies ermöglichen eine effizientere Verwaltung und eine bessere Unterstützung beim Auditing (u.a. für Compliance) als dezentrale Policies.

Beispiel für eine programmatische Autorisierung:

if ( (user.role == roles.sales) && (transaction.amount < 10000) )

  ALLOW_TRANSACTION 
}

Beispiel für eine deklarative Autorisierung:                                        

Authorizer authZ = new Authorizer();
if ( authZ.authorize(user, transaction) ) {
   ALLOW_TRANSACTION
}

Die Klasse Authorizer nutzt eine externe Datenquelle, um die dort hinterlegten Autorisierungsregeln abzufragen. In unserem Fall, kann das eine einfache Tabelle sein:

ROLE | MAX AMOUNT | PERMIT ------------------------ sales | 100000 | YES eng | 20000 | YES

Der deklarative Ansatz ist zudem insbesondere bei der Einführung neuer Anwendungen interessant, denn erfahrungsgemäß ändern sich die Regeln in dieser Phase häufig. Liegen die Regeln außerhalb der Applikation, wird in diesem Fall ein Maximum an Flexibilität gewährleistet: Diese können beliebig oft und problemlos geändert werden. Mit einem programmatischen Ansatz hingegen wäre bei jeder Änderung ein erneutes Deployment der Applikation erforderlich. Dieses kann allerdings nicht zu jedem beliebigen Zeitpunkt durchgeführt werden.

Webapplikationen mit ihren Deployment-Deskriptoren setzen das deklarative Prinzip schon seit Jahren um. Für allgemeine Autorisierungen, wie sie in Applikationen benötigt werden, reichen solche Mechanismen jedoch nicht immer aus. Konkret fehlt es beim oben beschriebenen Ansatz an Standardisierung, Ausdrucksmächtigkeit und Praxistauglichkeit. Was muss dabei beachtet werden? Ein paar Kernfragen helfen, sich einen Überblick zu verschaffen.

Standardisierung

  • Wie kann eine standardisierte Klasse (SDK) Authorizer aussehen?
  • Gibt es ein einheitliches Datenbankschema zur Speicherung der Autorisierungsregeln?
  • Kann Authorizer über einen standardisierten Webservice aufgerufen werden (API statt SDK)?

Ausdrucksmächtigkeit

  • Ist die Sprache mächtig genug, um auf programmatische Konstrukte zu verzichten? (Spätestens hier fällt auf, dass mächtige Sprachen auch Widrigkeiten wie Entscheidbarkeit und Berechnungskomplexität mit sich bringen.)
  • Werden Modellierungsparadigmen wie "Role Based Access Control" (RBAC - nach NIST) und "Attribute based access control" (ABAC) unterstützt?

Praxistauglichkeit

  • Wie viele Autorisierungsanfragen können pro Sekunde verarbeitet werden?
  • Wie lässt sich die Regelmenge effizient verwalten?
  • Wie ausgereift sind die angebotenen Produkte?

Grobgranulare versus feingranulare Berechtigungen

Die Granularität der Berechtigungen kann stark variieren. Grobgranular ist die Berechtigung (auch Access Rights genannt), weil hier ein Mechanismus den allgemeinen Zugriff auf eine URL erlaubt bzw. verbietet. Im Fall von dem DOAG-Redaktionssystem bedeutet es, dass die Applikation https://redaktionssystem.doag.com nach erfolgreicher Authentisierung erreicht werden kann. Im Unternehmensumfeld erfüllen klassische Access Management Systeme wie OpenSSO oder Oracle Access Manager diese Aufgabe. Es sei darauf hingewiesen, dass die Deployment-Deskriptoren lediglich grobgranulare Berechtigungen steuern.

Im Gegensatz dazu steuern feingranulare Regeln die Berechtigungen innerhalb der Applikation. Im Fall vom DOAG-Redaktionssystem: Darf Fred als Gastautor Bilder in Artikel der Kategorie 'Development' einfügen? Diese Art von Berechtigungsanfragen wird häufig als Entitlements bezeichnet. Sie lässt im Allgemeinen nicht anhand der URL erkennen, welche Parameter den Kontext bilden. Neben der Granularität unterscheiden sie sich von Access Rights wie folgt:

  • Es gibt pro Applikation deutlich mehr Entitlements als Zugriffsrechte
  • Entitlements kommen eher aus der Fachabteilung und haben andere Anforderungen an eine Management-GUI.
  • Typischerweise muss eine hohe Anzahl von Regeln verwaltet werden. Mögliche Ordnungskriterien sind die Zuordnung zu Applikationen (wenn die Applikation nicht mehr benötigt wird, können auch die zugehörigen Regeln gelöscht werden) sowie die Zuordnung zu Personen/Gruppen für eine delegierte Administration
  • Entitlementanfragen sind typischerweise komplexer als gewöhnliche Zugriffsrechtanfragen

XACML Standard

Wie bereits erwähnt ist die feingranulare Berechtigungsvergabe komplex und erfordert andere Konzepte in puncto Sprache, Werkzeuge, Standards etc. als die grobgranulare Variante. Wer sich also mit dem Thema beschäftigt, kommt nicht drum herum, sich mit dem relevanten Standard im Umfeld der feingranularen Berechtigungsvergabe zu befassen: eXtensible Access Control Markup Language (XACML). Dabei handelt es sich um eine standardisierte Sprache von OASIS, womit sowohl Entitlements abgefragt als auch Autorisierungsregeln formuliert werden können. Ihre Syntax ist in XML definiert.

Typischerweise funktioniert das Ganze folgendermaßen: Ein Benutzer ist bereits in einer Applikation angemeldet und möchte den Zugriff auf bestimmte Ressourcen erhalten. Nehmen wir den konkreten Beispiel von Fred. Nach einer erfolgreichen Anmeldung in das Redaktionssystem möchte er ein Bild in diesen Artikel einfügen. Eine Anfrage wird gestartet und zum Policy Enforcement Point (PEP) geschickt. Dieser ist da, um die Ressourcen zu schützen. Also formuliert er eine Anfrage anhand der Informationen über den Benutzer (Fred), die Ressource (Dokument: "Write Secure Code"), die Aktion (Schreiben) etc. und schickt diese dem Policy Decision Point (PDP). Der PDP trifft anhand dieser Anfrage und weiterer Richtlinien eine Entscheidung, die er dem PEP kommuniziert. Als Antwortmöglichkeiten gibt es vier Werte: Permit (zulassen), Deny (Verweigern), Indeterminate (unbestimmt, wenn eine Entscheidung nicht getroffen werden kann) oder  Not Applicable (die Anfrage kann nicht beantwortet werden).

Werfen wir einen Blick auf die Komponenten, die im XACML-Umfeld von Bedeutung sind.

Policy Decision Point (PDP)

Es handelt sich um die zentrale Stelle für die Verteilung von Entscheidungen. Der PDP analysiert anhand der vorhandenen Informationen (Regeln, Attribute, Aktion), ob ein Benutzer für eine Aktion berechtigt ist oder nicht. Er evaluiert die Policies und trifft Entscheidungen. Im obigen Listing stellt die Klasse "Authorizer" zusammen mit der von ihr genutzten Datenbank der PDP dar.

Policy Enforcement Points (PEP)

Der PEP ist für die Kontrolle der Zugriffsrechte zuständig. Er sorgt dafür, dass nur autorisierte Benutzer (mit entsprechenden gültigen Entitlements) Aktionen innerhalb der Applikationen durchführen können. Konkret formuliert er die Anfrage, die er dann dem PDP übermittelt. Im obigen Listing ist der PEP das IF-statement: if ( authZ.authorize(user, transaction) )

Policy Retrieval Point (PRP) und Policy Information Point (PIP)

Zur Bearbeitung einer XACML-Anfrage ermittelt der PDP die Regeln und weitere Attribute zu Benutzer und Kontext. Die Regeln bekommt er vom PRP, während die Attribute vom PIP kommuniziert werden. Diese Informationen sind übrigens ebenfalls in XACML beschrieben.

Policy Administration Point (PAP)

Der PAP ist für die Verwaltung der Regelmenge zuständig. Durch seine saubere Benutzeroberfläche mit klarer Strukturierung ermöglicht er die Verwaltung von großen Regelmengen. Nehmen wir beispielsweise an, dass eine Applikation deinstalliert werden soll. Mit dem PAP kann der Administrator nachvollziehen, welche Regeln ausschließlich von dieser Applikation genutzt wurden und die zugehörigen Regeln ge­ge­be­nen­falls löschen.

Eine XACML-Abfrage (Request) kann wie folgt aussehen:

<Request (...) xmlns:xsi="http://www.w3.org/2001/XMLSchemainstance">
<Subject>
 <Attribute AttributeId="(...):subject:subject-id">
  <AttributeValue>ff123321</AttributeValue>
</Attribute>
<Attribute AttributeId="email" DataType="urn:oasis:(...):rfc822Name">
  <AttributeValue>fred.fredsen@foo.bar</AttributeValue>
 </Attribute>
</Subject>
<Resource>
 <Attribute AttributeId="urn:oasis:(...):resource-id"
  <AttributeValue>http://www.foo.bar:14100/oic_rest/rest/someService</AttributeValue>
 </Attribute>
</Resource>
<Action>
 <Attribute AttributeId="urn:oasis:(...):action-id"
  <AttributeValue>read</AttributeValue>
 </Attribute>
</Action>
<Environment/>
</Request>

Eine XML-Policy kann wie folgt aussehen

<Policy PolicyId="ExecutivePolicy"
RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combiningalgorithm:permit-overrides">
<Description>Simple Policy</Description>
<Target />
<Rule RuleId="MailRule" Effect="Permit">
<Target>
 <Subjects>
  <Subject>
   <SubjectMatch MatchId="urn:(...):rfc822Name-match">
    <AttributeValue>foo.bar
        </AttributeValue>
    <SubjectAttributeDesignator AttributeId="urn:(...):subjectid" />
   </SubjectMatch>
  </Subject>
 </Subjects>
</Target>
<Condition>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:stringis-in">
  <AttributeValue>executive</AttributeValue>
    <SubjectAttributeDesignator AttributeId="urn:(...):role" />
 </Apply>
</Condition>
</Rule>
<Rule RuleId="DefaultPolicy" Effect="Deny" />
</Policy>
</PolicySet>

 

Die Standardisierung von XACML 3.0 steht kurz vor dem Abschluss. Auf der RSA 2012 (http://www.rsa2012.org/) fanden die ersten XACML 3.0 Interoperability-Tests statt, innerhalb derer die Produkthersteller (u.a. auch Oracle) ihre Produkte zertifizieren ließen. (Ja, obwohl der Standard noch nicht wirklich verabschiedet ist - Informationstechnik ist manchmal lustig!)

Rollenbasiert (RBAC) versus attributbasiert (ABAC)

Man unterscheidet zwischen zwei verschiedenen Arten der Zugriffskontrolle. Rollenbasiert  (RBAC) oder attributbasiert (ABAC). Bei RBAC (Role Based Access Control) sind – vereinfacht ausgedrückt – Zugriffsrechte an Rollen (statt an Personen) gebunden. In der Autorisierungsdatenbank wird hinterlegt: die Rolle 'Engineer' darf schreibend auf "MyResource" zugreifen. Um also zu prüfen, ob Fred auf "MyResource" zugreifen darf, wird geprüft, ob Fred die Rolle "Engineer" hat. Setzt man ein sinnvolles Rollen-/Nutzerverhältnis von ca. 10 Rollen pro 100 Mitarbeiter voraus, vereinfacht eine solche Modellierung den Prüfungsvorgang enorm.

ABAC (Attribute Based Access Control) hat einen anderen Ansatz: Das Konzept basiert in diesem Fall nicht auf Rollen, sondern auf "Attributen". Dabei kann ein Attribut ziemlich alles sein:

  • Nutzerattribute (auch eine Rolle!)
  • Resourceattribute (z.B. "ist magnetisch" - Fred hat dann Zugriff auf Bänder, Disks aber keine Lochkarten)
  • Umgebungsattribute

Der ABAC-Ansatz hat den Vorteil, dass er eine recht flexible Modellierung erlaubt. Der Preis ist die Laufzeit: die Evaluierung von ABAC-Regeln dauert deutlich länger als bei RBAC-Regeln. Bei Letzterem ist der Preis die Modellierungszeit. Es ist nämlich schwer, alle Regeln und Sonderfälle über eine Rolle abzubilden. Manche Organisationen können 4.000 Rollen für knapp 3.000 Mitarbeiter haben. Dabei kann bereits ein Verhältnis von einer Rolle für zehn Mitarbeiter ein Projekt zum Scheitern verurteilen.

Das Gute dabei ist: Man muss sich nicht für das eine oder andere Konzept entscheiden. Es spricht nichts dagegen, 70 Prozent der Zugriffsregeln über RBAC und 30 Prozent über ABAC zu modellieren. 

Vor- und Nachteile im Überblick:

 

RBAC

ABAC

Vorteile

  • Hoher Reifegrad
  • Leicht verständlich und zu modellieren
  • Bessere Performanz bei der Regelauswertung 
  • Relativ neu im Vergleich zu RBAC
  • Sehr flexibel
  • Gut zur Modellierung dynamischer Relationen 

Nachteile

  • Eingeschränkte Flexibilität

 

  • Im Großen können ABAC-Modelle sehr komplex und schwer analysierbar werden
  • Einbußen bei der Performanz auf Grund der hohen Dynamik 

Unterstützung durch Werkzeuge

Will man nicht unnötige Stunden mit dem Formulieren von Policies und Abfragen verbringen, sollte man sich erkundigen, welche Werkzeuge da Abhilfe schaffen können. Zur Formulierung der Policies kann ein Policy-Editor verwendet werden, während die OpenAZ-API die Formulierung der Abfragen übernehmen kann. Der Programmierer kann einfach über einen SDK-Aufruf eine Autorisierungsanfrage stellen und muss demnach die XACML-Anfragen nicht mehr selber erstellen. Neben der einfacheren Programmierung wird hierbei auch auf XML verzichtet. Oracle Entitlement Server Oracle Entitlement Server (OES) ist eine Kernkomponente des Oracle Middleware-Stacks. Mit "Kernkomponente" ist hier nicht nur ein Element des Produktportfolios gemeint, sondern eine Komponente, auf die sich alle anderen Produkte stützen, ähnlich wie JAAS für Java Programme. OES ist nämlich die zentrale Autorisierungsmaschine (AuthZ Engine) für sämtliche Middleware-Komponenten. In dieser Hinsicht sind zwei Aspekte besonders wichtig: die Performance (inkl. Skalierbarkeit) und die Stabilität.

Der OES unterstützt verschiedene PDP-Implementierungen (von Oracle „Security Module“ genannt), die wir uns im folgenden Abschnitt näher ansehen:

  • WebService PDPs (XACML)
  • Standalone Java JAR PDPs (OpenAZ)
  • Container-integrierte Java PDPs (OpenAZ), z.B. zur JMQ Absicherung
  • Applikationsspezifische PDPs (z.B. für Micrsoft SharePoint)

PDPs kommunizieren mittels eines proprietären Protokolls mit dem Policy Retrieval Point (PRP). Die Anwendung kommuniziert mit dem PDP über Standardschnittstellen (XACML, OpenAZ etc). Die Abbildung 1 zeigt die Architektur mit PEP, PDP und PRP. Falls der PDP ein XACML-Web-Service ist, ermöglicht dies den Zugriff von mehrerer PEPs aus.

Zentraler XACML-PDP

Das Modell mit (zentralem) XACML-PDP (siehe Abbildung 2) hat in vielen Situationen Vorteile. Allerdings werden die Anfragen immer noch per XML über das Netz geschickt. Dies bedeutet: erhöhter Verarbeitungsaufwand und Latenz. Für hochperformante Lösungen kann ein Java-basierter PDP mit in die Applikation als JAR eingebunden werden. Auf diesen PDP wird dann nicht mehr per XACML zugegriffen, sondern mittels der erwähnten OpenAZ API. Die Applikation, die den PDP nutzt, kann eine standalone Java-Applikation oder eine JEE-Applikation sein.

Eingebetteter PDP

In Abbildung 3 zeigen wir ein Beispiel für einen eingebetteten PDP. Der PEP fragt mittels 'newPepRequest' eine Autorisierung an: der Nutzer 'fred.fredsen' möchte schreibend (Action 'write') auf die Resource 'MyResource' zugreifen. Zusätzlich kann man der Anfrage noch Kontextparamter (IP Adresse etc) mitgeben. Mögliche Antworten sind: Deny, Indeterminate, Not Applicable und Permit. Zusätzlich können auch Obligations mitgeliefert werden. Dies sind (im XACML-Standard vorgesehene) Zusatzinformationen des PDPs an den PEP wie "Ja, der Nutzer darf das, aber schicke dem Vorgesetzten noch eine E-Mail (Obligation)". Es ist Aufgabe des PEPs, die Obligations auszuwerten und durchzuführen. Der PDP hat keine Möglichkeit zu prüfen, ob der PEP diese befolgt.

Das Codebeispiel illustriert, wie einfach es mit der OpenAZ API ist, Autorisierungsanfragen zu stellen und Antworten zu erhalten. Entsprechende Module können in XML-Firewalls wie Vordel oder Oracle Enterprise Gateway leicht integriert werden und so als PEP für feingranulare, WebService-spezifische Autorisierungsregeln eingesetzt werden.

import java.util.*;
import com.bea.security.*;
import weblogic.security.principal.*;
import javax.security.auth.*;
import java.security.*;
import oracle.security.jps.openaz.pep.*;
import org.openliberty.openaz.azapi.pep.*;

public class HelloOESworld {
  public static void main(String[] args) {
      Principal p = new WLSUserImpl("fred.fredsen");
    Subject user = new Subject();
           user.getPrincipals().add(p);
String resourceString = "HelloOESworld/MyResourceType/MyResource";
String action = "write";
    PepResponse response =
       PepRequestFactoryImpl.getPepRequestFactory()
         .newPepRequest(
                 user,
                 action,
                 resourceString,
                 null).decide();
      …
    }
}

Ausdruckmächtigkeit

Deklarative Sicherheit ist dann sinnvoll, wenn all das, was programmatisch formuliert wird (nicht werden kann), auch deklarativ darstellbar ist.  OES unterstützt folgende Modellierungskonzepte:

  • Attribute Based Access Control (ABAC)XACMLOpenAZNIST
  • Role Based Access Control (RBAC)Enterprise RBACJava2 / JAAS
  • Code Based Access ControlJSR 115 / Jave Authorization Contract for Container

Alles, was sich mittels NIST RBAC modellieren lässt, lässt sich auch im OES modellieren. Welchen Modellierungsansatz man wählt, hängt von vielen Randparametern ab. Entscheidend ist, dass die Regelmenge, die beim Modellieren entsteht, übersichtlich bleibt. Neben dem Sprachumfang sind Eigenschaften wie Vererbung mittels Hierarchien wichtig, wenn es darum geht, effizient zu modellieren:

  • Resourcenhierarchie: alle Zugriffe auf /Resources/MyResources werden verboten. Das schliesst Zugriffe auf /Resources/MyResources/ResA, /Resources/MyResources/ResB ein.
  • Rollenhierarchie : Rolle "Engineer" darf auf "/export/nfs/engshare" zugreifen; wenn Fred die Rolle "Software Engineer" hat soll ihm der Zugriff ebenfalls erlaubt werden.

Ausdrucksmächtigkeit ist eine Sache, effiziente Regelgestaltung eine ganz andere. Deklarative Sicherheit bietet ganz klar Vorteile gegenüber der programmatischen Sicherheit. Allerdings muss Sicherheit handhabbar bleiben. Deswegen ist es wichtig zu überprüfen, ob die deklarative Sprache mindestens die Umsetzung von RBAC- und ABAC-Modellen ermöglicht. Praktische Systeme benötigen aus Performancegründen nicht nur XACML-basierte sondern auch OpenAZ-basierte Schnittstellen/Dienste.

08.11.2012 Development, Security, Top News
Von: Steffo Weber, Abdi Mohammadi