Betrifft Oracle und .NET im n-Tier Umfeld Autor Urs Meier ([email protected]) Art der Info Technical Info (April 2003) Quelle Aus unserer Projekterfahrung Einführung Oracle und .NET sind ein populäres Gespann. Doch wie lassen sich Oracle Features mit .NET nutzen? Dieser Artikel zeigt auf wie Oracle-Features in einer n-Tier Umgebung zusammen mit .NET verwendet werden können. Am Beispiel von Security-Policies wird illustriert, wie die – auf den ersten Blick widersprüchlichen – Anforderungen von Connection-Pooling und individuellem Login in der Datenbank gelöst werden können. Zum Schluss wird gezeigt, wie eine Oracle Security Policy genutzt werden kann, damit die End-User die Datenbank immer lesen, jedoch nur über unsere .NET Applikation verändern dürfen. Zweiteilige Artikel Serie mit Java und .NET Für diesen ersten Artikel sollte der Leser ADO.NET und Oracle Grundkenntnisse haben. Der vorliegende erste Teil dient gleichzeitig als kleine Einführung in die Problematik. Ein zweiter Artikel befasst sich mit der Umsetzung von Security-Policies und Java. Problemstellung Java wie auch .NET ermöglichen die physische Verteilung der Software Layers über mehrere Tiers. Damit vom Middle-Tier her effiziente Datenbank-Verbindungen gemacht werden, gilt es zwei Grundsätze zu verfolgen (losgelöst von Security-Policies): 1. Connection-Pooling. Dies erlaubt die „Wiederverwendung“ von inaktiven, aber bereits erstellten Datenbank-Connections. Das Erstellen einer DatenbankConnection ist eine relativ aufwändige Operation und Connection-Pooling (eine Art Caching von Connections) ist die Antwort darauf. 2. Verwendung eines technischen Users (Sammel-User) vom Middle-Tier in die Datenbank, so dass keine Security-Probleme entstehen (nur der Sammel-User hat die nötigen Privilegien in der Datenbank) und damit das Connection-Pooling effizienter wird. Mit .NET übernimmt der ADO.NET Provider das Connection-Pooling automatisch. Somit wäre Punkt 1 eigentlich schon gelöst. Bei Punkt 2 (Verwendung eines technischen Users) scheiden sich die Geister und gerade mit Oracle möchten die Entwickler und DBAs die Oracle Features nutzen. Häufig kommt die Frage, wie mit einem einzigen technischen User Features wie z.B. Row-Level Security und Security-Policies genutzt werden können, da diese Features ein Login des individuellen End-Users erfordern. Lösungsansatz mit ODP.NET Damit Oracle Features genutzt werden können, verwenden wir den ADO.NET Provider (ODP.NET) für Oracle von Oracle (es gibt auch einen ADO.NET Provider für Oracle von Microsoft). Der Provider kann unter http://technet.oracle.com (Oracle Technology Network > Software > ODP.NET > Oracle9i Release 2 Data Provider for .NET 9.2.0.2.102) bezogen werden. ODP.NET unterstützt einige Oracle Features, darunter auch Proxy-Authentication. Proxy-Authentication erlaubt es eine Light-weight Session zu Oracle aufzubauen. Lightweight Sessions sind im Oracle Call Interface (OCI, also die direkte Schnittstelle zu Oracle) enthalten und erlauben über eine physische Connection (gut für ConnectionPooling) eine Art logische Session für individuelle End-User (gut für Security-Policy) zu erstellen. Der Connection-String mit ODP.NET sieht schlussendlich so aus: private Oracle.DataAccess.Client.OracleConnection oracleConnection1; ... this.oracleConnection1.ConnectionString = "Data Source=DB1;" + "User Id=RealUser;" + "Proxy User Id=TechnicalUser; Proxy Password=TechnicalUser"; - DB1 ist das tnsnames.ora Alias RealUser ist der Oracle Datenbank End-User TechnicalUser ist der Technische User (Sammel-User) Damit die Proxy-Authentication funktioniert, sind einige Setup-Schritte nötig, welche nachfolgend beschrieben werden. Erstellen des technischen Users Mit ODP.NET wird der technische User auch „Proxy User“ genannt. Dieser Benutzer wird nur für die Erstellung der Connection benötigt und braucht somit auch nur das CREATE SESSION Privileg: CREATE USER TechnicalUser IDENTIFIED BY TechnicalUser; GRANT CONNECT TO TechnicalUser; Erstellen des End Users Dies stellt den “richtigen” Benutzer dar. Nebst den üblichen Privilegien wie CONNECT braucht er natürlich auch die applikatorischen Rechte, welche hier nicht aufgeführt sind: CREATE USER RealUser IDENTIFIED BY RealUser; GRANT CONNECT TO RealUser; -- GRANT some application roles here Berechtigung für die Proxy Authentication Der technische User (Proxy User) muss schlussendlich die Berechtigung erhalten für den End-User eine Light-Weight Session zu erstellen. Hier gibt es mehrere Varianten. Der End-User kann den technischen User auf einige seiner Rollen einschränken, oder auch verlangen, dass im Connect sein Password bekannt sein muss. Hier ist die Variante aufgeführt, wo der technische User im Namen des End-Users ohne sein Passwort und mit allen seinen Rollen die Light-weight Session erstellen darf: ALTER USER RealUser GRANT CONNECT THROUGH TechnicalUser; Anmeldung und Logging Wenn nun mit ODP.NET die Anmeldung erfolgt this.oracleConnection1.ConnectionString = "Data Source=DB1;" + "User Id=RealUser;" + "Proxy User Id=TechnicalUser; Proxy Password=TechnicalUser"; dann wird die physische Connection mit dem TechnicalUser gemacht. In der Datenbank (z.B. Pseudo-Variable USER oder in v$Session) sieht man jedoch die Connection als RealUser. Das bedeutet aber auch, dass der Benutzer RealUser die nötigen Privilegien in der Datenbank braucht (z.B. INSERT, UPDATE, DELETE auf gewissen Tabellen oder EXECUTE auf Packages). In einer n-Tier Umgebung wird ein Teil der Business-Logik im Application-Server implementiert. Der Benutzer könnte nun dank seinen Privilegien diese Logik einfach umgehen, indem er sich z.B. mit SQL*Plus direkt an der Datenbank anmeldet. Lesen ja, schreiben nein Häufig möchte man dem Benutzer den direkten, lesenden Zugriff erlauben. Änderungen (INSERT, UPDATE, DELETE) sollten jedoch nur über die eigene Applikation (also z.B. nicht mit SQL*Plus) möglich sein. Da mit der ProxyAuthentication ja schlussendlich der End-User in der Datenbank angemeldet ist, kann dies mittels einer Oracle Security-Policy umgesetzt werden. Zuerst wird ein Package erstellt, welches mit SYS_CONTEXT und USERENV herausfindet, ob es sich bei der aktuellen Connection um eine Proxy Authentication handelt. Falls ja, wird auf den zuvor erstellten Oracle User TechnicalUser (Proxy User) geprüft. Im Falle einer Light-Weight Session mit TechnicalUser wird TRUE (1=1) zurückgeschickt. Ansonsten FALSE (1=2). CREATE OR REPLACE PACKAGE proxy_user_security AS FUNCTION isProxyUserConnection (p_schema VARCHAR2, p_tab VARCHAR2) RETURN VARCHAR2; END proxy_user_security; / CREATE OR REPLACE PACKAGE BODY proxy_user_security AS FUNCTION isProxyUserConnection (p_schema VARCHAR2, p_tab VARCHAR2) RETURN VARCHAR2 IS v_predicate VARCHAR2(3); BEGIN IF (SYS_CONTEXT('userenv', 'proxy_user') = 'TECHNICALUSER') THEN v_predicate := '1=1'; ELSE v_predicate := '1=2'; END IF; RETURN (v_predicate); END isProxyUserConnection; END proxy_user_security; / Im letzten Schritt können die Datenbank Objekte mit der erstellten Security Policy geschützt werden. Im nachfolgenden Beispiel wird eine Table Table1 mit der Security Policy und den Operationen INSERT, UPDATE, DELETE verhängt (Parameter statement_types und update_check damit auch INSERT und UPDATE geprüft werden). Das bedeutet, dass berechtigte Benutzer immer mit SELECT auf die Daten zugreifen können. Bei INSERT, UPDATE, DELETE hingegen wird die Security Policy aktiviert, welche nur im Falle einer Proxy Authentication mit dem Benutzer TechnicalUser auch TRUE (1=1) zurückschickt. Das heisst, dass Änderungen nur über das berechtigte Middle-Tier gemacht werden können. BEGIN DBMS_RLS.Add_Policy ( object_schema , object_name , policy_name , function_schema , policy_function , statement_types , update_check , enable , static_policy ); END; => => => => => => => => => 'APPLICATIONOWNER' 'TABLE1' 'isProxyUserPolicy' 'APPLICATIONOWNER' 'PROXY_USER_SECURITY.ISPROXYUSERCONNECTION' 'INSERT, UPDATE, DELETE' TRUE TRUE FALSE Fazit Zusammen mit dem ADO.NET Provider für Oracle von Oracle können einige Oracle spezifische Features genutzt werden. Der Artikel zeigt, wie die häufig gestellte Anforderung von individuellem Login und Connection-Pooling Rechnung getragen werden kann. Quasi als Gratiszugabe kann auch das Reporting-Problem gelöst werden, wo der Benutzer mit irgendeinem Tool lesend auf seine Daten zugreifen darf. Details zu Security Policies finden Sie in unseren Oracle Kursen (www.trivadis.com). Die Trivadis hat im Rahmen von „blended Learning“ auch spezifische Kurse zu .NET und Oracle. Erwähnenswert ist in diesem Zusammenhang auch der Architektur-Kurs MEAP-ADO, welcher n-Tier Architekturen zusammen mit Datenbanken behandelt. Lesen Sie zu Oracle Security Policies auch den Folge-Artikel, der aufzeigt, wie die gleiche Problematik im Java-Umfeld gelöst werden kann. Viel Erfolg mit .NET und Oracle wünscht Urs Meier Trivadis AG Kanalstrasse 5 8152 Glattbrugg Mail: [email protected] Tel: +41 808 70 20 Fax: +41 808 70 21 Internet: http://www.trivadis.com