Weitergabe der Identität und Datenbank-Identitäten (Referenz)
Regeln und Antworten, wenn der Dienst Anweisungen unter der Anmeldung einer Person (Impersonate) oder
einer zugeordneten Sammelanmeldung ausführt. Das Modell erklärt
Anmeldung und Weitergabe der Identität.
Syntax
"Databases": [
{ "Name": "fachdaten", "Provider": "sqlserver", "ConnectionString": "…",
"Persons": "Impersonate", // Service | Impersonate; Vorgabe Service
"DenyImpersonate": [
{ "Logins": [ "sa", "FIRMA\\Datenbankbetrieb" ] }, // nie
{ "Roles": [ "sysadmin" ], "ExceptFrom": [ "192.168.0.0/16" ] } // Sysadmins nur aus dem eigenen Netz
] }
],
"Security": {
"AuthMode": "ApiKey, Windows",
"TrustedProxies": [ "10.0.0.5" ] // nur von hier wird X-Forwarded-For geglaubt
}
Die Anmeldung des Alias braucht dazu in SQL Server:
GRANT IMPERSONATE ANY LOGIN TO [<Anmeldung des Alias>]; -- zusätzlich möglich, siehe unten: DENY IMPERSONATE ON LOGIN::[sa] TO [<Anmeldung des Alias>];
Parameter
Regeln der Weitergabe
| Regel | Grund |
|---|---|
Die Regeln des Dienstes (Clients) bleiben eine äußere Schranke; innen entscheidet SQL Server | Der Dienst bestimmt, welche Aliasse, Ressourcenarten und Verben über HTTP überhaupt erreichbar sind; die Berechtigungen für die einzelnen Objekte kennt SQL Server |
EXECUTE AS LOGIN, nicht EXECUTE AS USER | Die Person tritt in SQL Server mit ihrer Anmeldung auf wie bei einer direkten Verbindung – serverweit, nicht nur in einer Datenbank, und mit einer Anmeldung je Person statt einem Benutzer je Person und Datenbank |
EXECUTE AS mit Cookie, am Ende jeder Anfrage zurückgenommen; scheitert die Rücknahme, werden die Verbindungen des Alias verworfen | Eine Verbindung aus dem Pool darf den Kontext einer Person nicht in die nächste Anfrage tragen – SQL Server beendet eine solche Sitzung bei ihrer nächsten Verwendung, und die Anfrage, die sie zieht, scheitert (596). Das Cookie verhindert, dass eine durchgereichte Anweisung per REVERT zur Anmeldung des Alias zurückspringt |
ORIGINAL_LOGIN() nennt weiter die Anmeldung des Alias | Das ist die Verbindung, die wirklich besteht; im Audit von SQL Server erkennt man daran den Dienst |
| Eigene Anweisungen laufen mit den Berechtigungen der Person | wie bei einer direkten Verbindung |
| Die Anmeldung findet der Dienst über die SID der Windows-Anmeldung | So findet er sie auch, wenn ihr Name nicht mehr zum Konto passt. Wechseln kann SQL Server zu ihr dann aber nicht: Er löst den gespeicherten Namen über Windows auf und scheitert (15404, Windows-Code 0x534, auch als Sysadmin). Nach dem Umbenennen eines Windows-Kontos ist die Anmeldung deshalb mit umzubenennen: ALTER LOGIN [FIRMA\alt] WITH NAME = [FIRMA\neu] |
Ein Windows-Konto ohne eigene Anmeldung wird abgewiesen, nicht auf Service zurückgestuft | Ein stiller Rückfall gäbe ihm die Berechtigungen des Dienstkontos. Ausnahme: Eine Person mit persönlichem Schlüssel, der keine SQL-Anmeldung eingetragen ist, läuft unter der Anmeldung des Alias, mit ihrem Namen im Sitzungskontext |
Fehlt der Person eine Berechtigung, antwortet der Dienst mit 403 | So wie SQL Server es einer direkten Verbindung verweigert. Unter Service bleibt eine fehlende Berechtigung 422: Dort ist es eine Lücke im Aufbau des Dienstes, nicht die Entscheidung über eine Person |
Auf welche Anmeldung der Dienst nicht wechselt, entscheidet allein die Liste DenyImpersonate des Alias. Sie gilt für jeden Wechsel (EXECUTE AS), nicht für die Anmeldung mit einer SQL-Anmeldung per HTTP Basic: Dort öffnet der Dienst eine eigene Verbindung mit Name und Kennwort, und SQL Server allein entscheidet. Wer etwa sa dort ausschließen will, nennt in SqlLogins nur bestimmte Anmeldungen statt * oder sperrt sie in SQL Server | Sie steht in der Konfiguration und ist die eine Stelle, an der das festgelegt wird. Sie gilt an jedem Alias, auch unter Service: Eine Datenbank-Identität wechselt dort ebenfalls auf eine Anmeldung. Ein Eintrag nennt Anmeldungen (Name, wie SQL Server ihn führt, oder SID) oder Serverrollen, dazu optional Netze, aus denen er nicht gilt (ExceptFrom) oder aus denen allein er gilt (From). Was kein Eintrag trifft, wird angenommen wie bei einer direkten Verbindung, auch mit hohen Rechten; eine verborgene Regel daneben gibt es nicht |
Trifft ein Eintrag zu, wird abgewiesen (403); die Reihenfolge entscheidet nichts | Ausnahmen stehen im Eintrag selbst, nicht in eigenen Erlaubnis-Einträgen – sonst hinge das Ergebnis an der Reihenfolge, was der Rest der Konfiguration aus demselben Grund vermeidet |
| Namen und SIDs werden vor dem Wechsel geprüft, Rollen danach im neuen Kontext | Die Rollen einer Anmeldung zeigt verlässlich erst ihr Kontext (IS_SRVROLEMEMBER). Trifft ein Rollen-Eintrag zu, wird sofort zurückgenommen und abgewiesen |
Die Herkunft ist die Adresse des Gegenübers; X-Forwarded-For zählt nur, wenn es von einer Adresse aus Security:TrustedProxies kommt | Sonst schreibt jeder eine Adresse aus dem eigenen Netz hinein. Gelesen wird vom nächsten Glied aus: Die erste Adresse, die selbst kein vertrauter Proxy ist, gilt – ein Eintrag, den der Client vorn selbst einträgt, zählt damit nicht. Eine unlesbare Angabe macht die Herkunft unbekannt, und eine unbekannte Herkunft hebt keine Sperre auf. IPv4-Adressen in IPv6-Schreibweise (::ffff:192.168.1.5) werden auf IPv4 zurückgeführt. „Internet“ kennt der Dienst nicht, nur „außerhalb der genannten Netze“ |
| Netze werden streng gelesen: Eine IPv4-Adresse braucht vier Dezimalteile ohne führende Null, und hinter der Präfixlänge dürfen keine Bits gesetzt sein | .NET liest 192.168 als 192.0.0.168, 0x7f.0.0.1 als 127.0.0.1, 017.0.0.1 als 15.0.0.1 und macht aus 192.168.1.5/16 stillschweigend 192.168.0.0/16. Jede dieser Lesarten änderte unbemerkt, was eine Regel erfasst; die Startprüfung weist sie deshalb ab. Die Regel gilt gleich für TrustedProxies, From, ExceptFrom, die Einschränkungen persönlicher Schlüssel und setup-host --networks |
Außerhalb des Dienstes zusätzlich möglich: DENY IMPERSONATE in SQL Server für dieselben Anmeldungen | Das hält auch dann, wenn der Dienst selbst kompromittiert ist: Mit IMPERSONATE ANY LOGIN kann seine Anmeldung sonst jede Anmeldung annehmen, auch eine Sysadmin-Anmeldung; das DENY sperrt es |
Die Antworten bei einer Abweisung nennen keine Regel; welcher Eintrag griff, für wen und von welcher Herkunft, steht als Warnung im Protokoll unter der Korrelationskennung.
Antwort (403) | Bedeutung |
|---|---|
| „Fuer dieses Windows-Konto gibt es in SQL Server keine eigene Anmeldung.“ | Die Person hat keine eigene Anmeldung, nur Zugang über eine Gruppe, oder gar keinen |
| „Diese Anmeldung darf ueber den Dienst nicht verwendet werden.“ | Ein Eintrag von DenyImpersonate trifft zu – über Name, SID oder Rolle |
| „Der Dienst kann diese Anmeldung in SQL Server nicht annehmen.“ | SQL Server lehnt den Wechsel ab: etwa IMPERSONATE ANY LOGIN fehlt, die Anmeldung ist deaktiviert, oder das Windows-Konto wurde umbenannt (15404) |
| „Die Datenbank verweigert dieser Anmeldung den Vorgang.“ | Der Person fehlt eine Berechtigung (Fehler 229, 230, 262, 297, 300 oder 916) |
Datenbank-Identitäten (Sammelanmeldungen)
In vielen Installationen haben Personen in der Datenbank keine eigenen Berechtigungen. Sie arbeiten über
eine gemeinsame Anmeldung je Abteilung, etwa vertrieb oder marketing, deren Kennwort alle
kennen. Wer zu welcher Anmeldung gehört, entscheidet der Kunde. Der Dienst bildet es im
Verwaltungsspeicher ab: Jede Person meldet sich als sie selbst an, und
der Dienst wechselt für sie auf die gemeinsame Anmeldung. Das Kennwort der gemeinsamen Anmeldung
braucht dabei niemand.
Zwei Mengen der Verwaltungsschnittstelle:
| Menge | Inhalt |
|---|---|
DatabaseIdentities | Je Datenquelle die Identitäten, unter denen eine Anfrage laufen darf, jede unter einem Namen, mit dem die Person wählt (ROLE= des Treibers). Der Name ist je Datenquelle eindeutig. Kind legt fest, als wen die Anfrage läuft: Login wechselt mit EXECUTE AS LOGIN auf die Sammelanmeldung in Login; Own wechselt auf die eigene Anmeldung der Person (Windows-Anmeldung ihres Kontos bzw. SqlLogin ihres Eintrags); Alias bleibt bei der Anmeldung der Datenquelle |
IdentityAssignments | Wer eine Identität annehmen darf: genau eine Quelle je Zeile – eine Person (PersonId), ein Windows-Konto oder eine Windows-Gruppe (WindowsAccount, beim Speichern zur SID aufgelöst) oder ein einzelner persönlicher Schlüssel (KeyId) |
Identität und Zuordnung haben je einen Schalter Enabled. Eine Person hat zusätzlich eine
Vorgabe (DefaultRole in Persons).
Welche Identität gilt – je Anfrage, sobald der Alias feststeht:
| Lage | Ergebnis |
|---|---|
| Keine Zuordnung trifft die Anmeldung | Die Einstellung Persons des Alias entscheidet |
Die Anfrage wählt (Kopfzeile X-Wkl-Role, sonst die an die Sitzung des zweiten Faktors gebundene Identität) | Die gewählte, wenn sie zugeordnet ist; sonst 403 mit der Liste der möglichen |
| Genau eine zugeordnet | diese |
| Mehrere, keine Wahl, Vorgabe der Person ist darunter | die Vorgabe |
| Mehrere, keine Wahl, keine passende Vorgabe | 403; die Antwort listet die möglichen Identitäten in X-Wkl-Roles und in der Meldung |
Eine Zuordnung trifft über die Person, zu der die Anmeldung gehört (über den Schlüssel oder ihr
eigenes Windows-Konto), über den Schlüssel selbst oder über das Windows-Konto und jede seiner
Gruppen. Namen in X-Wkl-Role und X-Wkl-Roles sind prozentkodiertes UTF-8
(Au%C3%9Fendienst); die Liste ist durch Kommas getrennt.
| Regel | Grund |
|---|---|
| Bei mehreren Identitäten gibt es keinen Rang; ohne Wahl und Vorgabe lehnt der Dienst ab | Eine geratene Identität ließe Anweisungen mit Berechtigungen laufen, die die Person nicht gewählt hat |
Jede Wahl wird bei jeder Anfrage gegen die Zuordnungen geprüft; eine fremde Wahl ist 403 | Die Wahl ist keine Berechtigung, nur die Auswahl unter erteilten |
| Ein Dienstschlüssel und eine SQL-Anmeldung per Basic nehmen keine Identität an; eine Wahl wird abgewiesen | Ein Dienstschlüssel ist keine Person; eine SQL-Anmeldung verbindet sich als sie selbst |
DenyImpersonate gilt für Sammelanmeldungen wie für Personen | Die Liste ist die eine Stelle, die eine Anmeldung aus der Reichweite des Dienstes nimmt |
Die Person bleibt sichtbar: SESSION_CONTEXT(N'wkl.person') nennt sie, SESSION_CONTEXT(N'wkl.role') die gewählte Identität, wkl.key den Schlüssel | USER_NAME() und SUSER_SNAME() nennen die Sammelanmeldung, ORIGINAL_LOGIN() die Anmeldung der Datenquelle. Für eine Windows-Anmeldung ohne Personeneintrag steht das Konto in wkl.person |
Der Audit-Strom nennt beide: Zugriff GET fachdaten/dbo.Auftrag durch Erika Muster (k…) als vertrieb | Wer gehandelt hat und unter welcher Identität. Die Ratenbegrenzung zählt je Aufrufer: je persönlichem Schlüssel (nicht je Person), je Windows-Konto, je SQL-Anmeldung in der Schreibweise der Anfrage; nicht je Identität |
| Zuordnungen werden bei jeder Anfrage nachgeschlagen | Ausschalten oder Löschen wirkt mit der nächsten Anfrage |
Eine Person ohne eigene Anmeldung, die Own wählt, wird abgewiesen | Kein stiller Rückfall auf die Anmeldung der Datenquelle |
Prüfung beim Speichern. Eine eingeschaltete Identität der Art Login speichert der Dienst
erst nach einem Probewechsel: Er öffnet eine Verbindung der Datenquelle, wechselt auf die
Anmeldung und nimmt den Wechsel sofort zurück. Abgewiesen wird mit 422 und einer Meldung für
die Verwaltung, wenn die Anmeldung fehlt (oder eine Windows-Gruppe ist), wenn ein Eintrag von
DenyImpersonate sie nennt – beim Speichern zählt jeder Eintrag, auch einer mit Netzbedingung –,
wenn sie einer dort genannten Serverrolle angehört, wenn sie keinen Zugang zur Datenbank der
Datenquelle hat oder wenn SQL Server den Wechsel verweigert (etwa weil IMPERSONATE fehlt).
Die Anmeldung der Datenquelle braucht dafür in SQL Server:
GRANT IMPERSONATE ON LOGIN::[vertrieb] TO [<Anmeldung der Datenquelle>]; -- je Sammelanmeldung
Die Sammelanmeldungen selbst und ihre Berechtigungen legt der Kunde in SQL Server an; der Dienst verwaltet sie nicht. Eine Sammelanmeldung, die sich Personen per Basic mit einem geteilten Kennwort teilen, ist nicht empfohlen: Der Dienst kann die Personen dann nicht unterscheiden.
Clients. Der ODBC-Treiber für OData (Wkl.Data.OData.Odbc) wählt
mit dem Schlüsselwort ROLE= oder – wo die Anwendung einen Dialog erlaubt – mit einer
Auswahlliste, die die Liste aus X-Wkl-Roles zeigt. Access und DAO teilen eine Verbindung
zwischen allen Verknüpfungen eines Prozesses mit gleichem DATABASE-Wert, auch wenn sich ihre
ROLE= unterscheiden: Dort gilt die Identität der ersten Verbindung für alle diese
Verknüpfungen. Eine zweite Identität in derselben Access-Sitzung braucht einen eigenen
DATABASE-Wert in ihrer Verbindungszeichenfolge; die Regel beschreibt die
Dokumentation des Treibers (Verbindungsschlüsselwörter).
Siehe auch
- „So richten Sie Datenbank-Identitäten ein“ (Dokumentation der Verwaltungsanwendung, Administrator-Handbuch)