HTTP: Anmeldung (Referenz)
Alle Anmeldeverfahren des Dienstes mit ihren Regeln und Antworten, die Selbstbedienung für eigene Schlüssel und die Anmelderichtlinie mit dem zweiten Faktor. Das Modell dahinter erklärt Anmeldung und Weitergabe der Identität.
Syntax
| Angabe | Bedeutung |
|---|---|
X-Api-Key: <Dienstschlüssel oder persönlicher Schlüssel> | erster Faktor; Name der Kopfzeile nach Security:ApiKeyHeader |
Authorization: Negotiate … | Windows-Konto |
Authorization: Basic … | SQL-Anmeldung, oder persönlicher Schlüssel als Kennwort |
X-Wkl-Session: <Sitzung> | zweiter Faktor, zusätzlich zum ersten |
X-Wkl-Role: <Identität> | Wahl der Datenbank-Identität |
POST /auth/v1/totp[/{alias}] | Code gegen Sitzung |
POST /auth/v1/enrol[/{alias}] | zweiten Faktor bei der ersten Anmeldung einrichten |
GET /self/v1/[{alias}/]keys | Selbstbedienung: eigene Schlüssel |
POST /self/v1/[{alias}/]issue-key | Selbstbedienung: Schlüssel ausstellen |
POST /self/v1/[{alias}/]revoke-key | Selbstbedienung: Schlüssel sperren |
Parameter
Anmeldung mit dem Windows-Konto
Neben dem Dienstschlüssel kann sich ein Aufrufer mit seinem Windows-Konto anmelden, über HTTP Negotiate – Kerberos oder, wo Kerberos nicht verfügbar ist, NTLM. Gedacht ist das für Personen: Access über den ODBC-Treiber und Excel oder Power BI melden sich als der Benutzer an, der sie ausführt. Nirgends wird ein Schlüssel oder Kennwort gespeichert, und das Audit nennt die Person statt eines Schlüsselnamens.
"Security": {
"AuthMode": "ApiKey, Windows",
"ApiKeys": [ { "Client": "fachanwendung", "Key": "env:FACHANWENDUNG_SCHLUESSEL" } ],
"WindowsAccounts": [
{ "Account": "FIRMA\\Fachdaten-Leser", "Client": "fachdaten-lesen" },
{ "Account": "FIRMA\\Fachdaten-Pflege", "Client": "fachdaten-pflege" },
{ "Account": "S-1-5-32-545", "Client": "auskunft" }
],
"Clients": [
{ "Id": "fachanwendung", "Databases": [ "fachdaten" ], "Resources": [ "*" ], "Verbs": [ "*" ] },
{ "Id": "fachdaten-lesen", "Databases": [ "fachdaten" ], "Resources": [ "views" ], "Verbs": [ "GET" ], "ReadOnly": true },
{ "Id": "fachdaten-pflege", "Databases": [ "fachdaten" ], "Resources": [ "*" ], "Verbs": [ "*" ] },
{ "Id": "auskunft", "Databases": [ "fachdaten" ], "Resources": [ "views" ], "Verbs": [ "GET" ], "ReadOnly": true }
]
}
| Regel | Grund |
|---|---|
AuthMode nennt die Verfahren durch Komma getrennt: ApiKey, Windows, SqlLogin, PersonalKey in beliebiger Kombination | Dienste behalten ihren Schlüssel, Personen melden sich mit Windows an oder mit einer SQL-Anmeldung |
Ein Eintrag unter WindowsAccounts gibt einem Konto oder einer Gruppe die Regeln eines Aufrufers unter Clients | Rechte hängen an Gruppen, wie sonst in Windows auch; eine Person bekommt sie über ihre Mitgliedschaft |
| Die Rechte mehrerer Einträge addieren sich; eine nur lesende Regel schränkt eine andere nicht ein | So wirken Gruppen überall in Windows. Wer nur lesen soll, gehört in keine Gruppe, die schreiben darf |
| Verglichen wird über die SID; ein Name wird beim Start in sie übersetzt | Eine umbenannte Gruppe behält ihre Rechte. Ein Name, den es nicht gibt, verhindert den Start, statt still nichts zu gewähren |
Eingebaute Gruppen mit ihrer SID angeben (S-1-5-32-545 statt VORDEFINIERT\Benutzer) | Ihre Namen hängen von der Sprache der Windows-Installation ab. Eine SID wird nur auf ihre Form geprüft |
| Ein mitgeschickter Dienstschlüssel entscheidet allein | Ein ausdrücklicher Nachweis wird nicht von einem stillschweigenden überstimmt; ein falscher Schlüssel ergibt 401, auch wenn eine Windows-Anmeldung mitkommt |
| Eine angemeldete Person ohne passenden Eintrag erreicht nichts, wie ein Schlüssel ohne Regel | Das Audit nennt, wer es versucht hat. Ein 401 ließe Office erneut nach Zugangsdaten fragen, die die Person längst vorgelegt hat |
| Gruppen, die Windows nur zum Verweigern führt, zählen nicht | Etwa die Administratorengruppe eines nicht erhöhten Benutzers; sie zu zählen hieße zu gewähren, was Windows vorenthält |
Ohne Anmeldung antwortet der Dienst mit 401 und WWW-Authenticate: Negotiate; erst darauf
meldet sich ein Client mit Windows an. Jede neue Verbindung beginnt deshalb mit einer Anfrage
ohne Anmeldung, die im Audit als anonym … UNAUTHENTICATED (401) steht. Das ist der erste
Schritt des Verfahrens, kein Fehler. Danach gilt die Anmeldung für die ganze Verbindung.
Kerberos setzt einen SPN HTTP/<rechnername> für das Konto voraus, unter dem der Dienst läuft;
fehlt er, weicht Windows auf NTLM aus.
Anmeldung mit einer SQL-Anmeldung (HTTP Basic)
Wer SQL Server bisher mit Name und Kennwort erreicht, meldet sich mit derselben Anmeldung am
Dienst an: über HTTP Basic, also mit Name und Kennwort in der Kopfzeile Authorization. Der
Dienst prüft das Kennwort nicht selbst und speichert keines. Er öffnet mit Name und Kennwort
eine Verbindung zum Server des angesprochenen Alias, und SQL Server entscheidet wie bei einer
direkten Verbindung. Alle Anweisungen der Anfrage laufen danach über Verbindungen dieser
Anmeldung: Berechtigungen, Spaltenvorgaben und Trigger sehen die Anmeldung selbst, auch
ORIGINAL_LOGIN().
"Databases": [
{ "Name": "fachdaten", "Provider": "sqlserver", "ConnectionString": "…",
"AllowSqlLogins": true }
],
"Security": {
"AuthMode": "ApiKey, Windows, SqlLogin",
"SqlLogins": [
{ "Login": "*", "Client": "fachdaten-lesen" },
{ "Login": "pflege1", "Client": "fachdaten-pflege" }
],
"TrustedProxies": [ "10.0.0.5" ]
}
| Regel | Grund |
|---|---|
AuthMode enthält SqlLogin, und ein Alias nimmt SQL-Anmeldungen nur mit AllowSqlLogins an | Welche Datenbank Name und Kennwort prüft, ist eine Entscheidung je Alias. Ein Alias ohne den Schalter antwortet einer SQL-Anmeldung wie einer unbekannten (401); die Antwort verrät nicht, welche Aliasse es gibt |
| Server und Datenbank stammen aus der Verbindungszeichenfolge des Alias; Name und Kennwort ersetzen nur deren Anmeldung | Der Aufrufer wählt die Datenbank nicht, wie überall im Dienst |
Ein Eintrag unter SqlLogins gibt einer Anmeldung (Login: ihr Name oder * für jede) die Regeln eines Aufrufers unter Clients; die Rechte mehrerer Einträge addieren sich | Die Regeln bleiben die äußere Schranke: welche Aliasse, Ressourcenarten und Verben über HTTP erreichbar sind. Innen entscheiden die Rechte der Anmeldung in SQL Server |
| Geprüft wird, bevor Regeln und Katalog befragt werden | Sonst könnte, wer einen Namen, aber nicht das Kennwort kennt, an den Antworten erkennen, welche Objekte es gibt |
Nur über eine geschützte Verbindung: HTTPS, ein Proxy aus TrustedProxies, der X-Forwarded-Proto: https meldet, oder eine Anfrage vom eigenen Rechner. Sonst 403, ohne das Kennwort zu versuchen | Basic schickt das Kennwort mit jeder Anfrage. X-Forwarded-Proto eines beliebigen Clients zählt nicht, und ein vertrauter Proxy auf dem eigenen Rechner macht eine Anfrage von außen nicht zu einer lokalen |
Höchstens 5 Fehlversuche je Anmeldung und Alias und 20 je Herkunft in einer Minute; danach 429, auch mit richtigem Kennwort. Als Fehlversuch zählt auch ein Versuch, auf den der Server keine lesbare Antwort gibt (503) | SQL Server zählt Fehlversuche nur für Anmeldungen mit Kennwortrichtlinie, und die Ratenbegrenzung des Dienstes greift erst nach der Anmeldung. Auch ohne lesbare Antwort kann der Server das Kennwort geprüft haben |
| Das Kennwort erscheint weder im Protokoll noch in der Textform des Aufrufers | Es liegt nur im Speicher der Anfrage und im Verbindungspool; SqlClient führt je Anmeldung einen eigenen Pool |
Ein mitgeschickter Dienstschlüssel entscheidet vor Basic, Basic vor Windows; ein abgewiesenes Kennwort ergibt 401 ohne Rückfall auf Windows | Ein ausdrücklicher Nachweis wird nicht von einem stillschweigenden überstimmt |
Ohne Anmeldung nennt die Antwort 401 jedes eingeschaltete Verfahren: WWW-Authenticate: Negotiate und WWW-Authenticate: Basic realm="Wkl.Data.Gateway", charset="UTF-8" | Ein Client wählt, was er kann; charset sagt ihm, dass Name und Kennwort als UTF-8 gelesen werden |
| Antwort | Bedeutung |
|---|---|
401 „Es wurde keine gültige Anmeldung vorgelegt.“ | Name oder Kennwort falsch, Anmeldung unbekannt oder gesperrt, oder der Alias nimmt keine SQL-Anmeldungen an. Die Antwort unterscheidet das bewusst nicht; das Protokoll nennt die Fehlernummer von SQL Server (etwa 18456) |
403 „SQL-Anmeldungen nimmt der Dienst nur über eine verschlüsselte Verbindung an.“ | Das Kennwort kam ungeschützt von einem anderen Rechner |
403 „Diese Anmeldung hat keinen Zugang zur Datenbank des Alias.“ | SQL Server hat die Anmeldung angenommen, die Datenbank des Alias aber nicht geöffnet (4060) |
403 „Die Datenbank verweigert dieser Anmeldung den Vorgang.“ | Der Anmeldung fehlt eine Berechtigung (Fehler 229, 230, 262, 297, 300 oder 916) |
429 „Zu viele fehlgeschlagene Anmeldungen; bitte später erneut versuchen.“ | Die Grenze für Fehlversuche ist erreicht |
Persönliche Schlüssel
Ein persönlicher Schlüssel gehört einer Person, nicht einem Dienst. Er setzt keine Domäne,
kein SQL-Kennwort und keine Infrastruktur voraus und funktioniert damit überall, wo der Dienst
erreichbar ist. Personen und Schlüssel stehen im Verwaltungsspeicher;
das Verfahren braucht ihn und wird mit PersonalKey eingeschaltet:
"Security": { "AuthMode": "ApiKey, PersonalKey" },
"Store": { "Path": "store/dbgwsvc.db", "MasterKey": "env:WKL_GW_MASTER_KEY", "MaxKeyLifetimeDays": 365 }
Der Schlüssel kommt in dieselbe Kopfzeile wie ein Dienstschlüssel (X-Api-Key, siehe
ApiKeyHeader). Jeder Client, der einen Dienstschlüssel schicken kann – der ODBC-Treiber mit
APIKEY/APIKEYENV, ein Skript, ein Berichtswerkzeug –, schickt ohne Änderung einen
persönlichen. Das Präfix unterscheidet beide. Ebenso gilt ein persönlicher Schlüssel als
Kennwort von HTTP Basic (der Name wird nicht geprüft; empfohlen ist pkuser, siehe unten): Excel
und Power BI legen solche Anmeldedaten (Anmeldeart „Standard“) in ihrer eigenen Anmeldeverwaltung ab,
während eine Kopfzeile in die Abfrage – und damit in jede Mappe – geschrieben werden müsste. Die Form des Schlüssels unterscheidet
ihn vom Kennwort einer SQL-Anmeldung.
<a id=„benutzername-pkuser“></a>Benutzername pkuser (Konvention). Wer einen persönlichen Schlüssel als
Kennwort einträgt, gibt als Benutzernamen pkuser an (personal key user). Pflicht ist das nicht:
Der Dienst erkennt den Schlüssel an seiner Form (wkl_…), nicht am Namen, und nimmt jeden Namen an.
Der einheitliche Name hat trotzdem Vorteile:
- In den Anmeldeverwaltungen von Excel, Power BI und Windows sieht man auf einen Blick, dass hier ein persönlicher Schlüssel steht und keine SQL-Anmeldung.
- Am Telefon genügt „Benutzername
pkuser, Kennwort Ihr Schlüssel“, ohne Erklärung, welcher Name gemeint ist. - Niemand trägt den Namen eines anderen Systems ein und hält ihn dann für einen Teil des Zugangs.
Legen Sie in SQL Server keine Anmeldung pkuser an: Ein Kennwort ohne die Form eines Schlüssels prüft
der Dienst als SQL-Anmeldung dieses Namens.
| Eigenschaft | Festlegung | Grund |
|---|---|---|
| Form | wkl_ + 43 Zeichen Zufall (256 Bit, Buchstaben und Ziffern) + 6 Prüfzeichen, zusammen 53 Zeichen | Feste Vorsilbe und Länge findet ein Geheimnis-Scanner in Quelltext und Protokollen; die Prüfzeichen erkennen einen Tippfehler ohne Nachschlagen |
| Ablage | nur SHA-256 des Schlüssels, eine öffentliche Kennung (k + 8 Zeichen) und die letzten 4 Zeichen | Eine Kopie der Datei öffnet keine Anfrage. Bei 256 Bit Zufall genügt SHA-256; ein langsames Kennwortverfahren kostete jede Anfrage Zeit und schützte nichts |
| Anzeige | einmal, beim Ausstellen | Danach gibt es ihn nur noch beim Inhaber |
| Rechte | die Regeln (Clients), die der Person zugeordnet sind; der Schlüssel schränkt ein und gewährt nie selbst: Aliasse, nur lesen, Netze (From/ExceptFrom) | Ein Schlüssel für Excel auf einem fremden Rechner bekommt nur, was er braucht, ohne eigene Regel |
| Laufzeit | Ablaufdatum je Schlüssel; ohne Angabe die Höchstlaufzeit Gateway:Store:MaxKeyLifetimeDays (Vorgabe 365, 0 = ohne Ablauf); länger wird abgelehnt | Ein vergessener Schlüssel auf einem alten Rechner hört von selbst auf zu wirken |
| Sperre | Schlüssel sperren oder Person abschalten wirkt ab der nächsten Anfrage, ohne Neuladen und ohne Neustart | Der Schlüssel wird bei jeder Anfrage im Speicher nachgeschlagen (ein Indexzugriff auf die lokale Datei); es gibt keinen Zwischenspeicher, aus dem ein gesperrter Schlüssel weiterwirken könnte |
| Mehrere je Person | ja, je Gerät oder Zweck mit Bezeichnung | Ein verlorener Laptop kostet einen Schlüssel, nicht alle |
| Nachweis | Audit: Person (Kennung); „zuletzt benutzt“ mit Zeit und Herkunft je Schlüssel | Wer gehandelt hat und welcher Schlüssel zu sperren ist |
| Identität in SQL Server | Hat die Person eine eigene Anmeldung (--login) und der Alias Persons: Impersonate (das Windows in AuthMode voraussetzt), läuft die Anfrage unter ihr (EXECUTE AS LOGIN, DenyImpersonate gilt). Sonst unter der Anmeldung des Alias. In beiden Fällen steht die Person schreibgeschützt im Sitzungskontext: SESSION_CONTEXT(N'wkl.person'), SESSION_CONTEXT(N'wkl.key') | Trigger, Spaltenvorgaben und Sichten können fragen, wer gehandelt hat, auch ohne eigene Anmeldung. Der Verbindungspool setzt den Kontext vor der nächsten Anfrage zurück |
| Dienstschlüssel | wechseln nie die Identität | Ein Dienst ist keine Person |
„Zuletzt benutzt“ wird gesammelt und alle 60 Sekunden sowie beim Beenden geschrieben, nicht je Anfrage: Jeder Schreibvorgang in die Datei ließe den Dienst sie erneut lesen. Ein Absturz kostet höchstens diese Minute an Statistik, nie eine Berechtigung. Schreibvorgänge, die die Betriebsdaten nicht ändern (Benutzung, Schlüssel, Personen), übernimmt der Dienst nicht als neue Fassung und meldet sie nicht.
Personen und Schlüssel verwalten – über die Verwaltungsschnittstelle
oder auf dem Rechner des Dienstes mit den Befehlen save-person, issue-key, revoke-key und
list-keys; sie laufen mit Konfiguration und Umgebung des Dienstes, auch während er läuft. Aufruf,
Optionen und Rückgabewerte stehen unter
Befehle am Server: Personen und Schlüssel. Diese Befehle
schreiben nicht ins Änderungsprotokoll (wer sie ausführt, hat ohnehin Zugriff auf die Datei); die
Befehle zur Rettung init-admin, reset-totp und remove-sign-in-rule dagegen schon, mit dem
Akteur „Konsole (Rechner, Konto)“.
| Antwort | Bedeutung |
|---|---|
401 „Der persönliche Schlüssel ist unbekannt.“ | Kein solcher Schlüssel oder Tippfehler |
401 „Persönliche Schlüssel sind an diesem Dienst nicht eingerichtet.“ | PersonalKey ist in AuthMode nicht eingeschaltet |
403 „Die Person zu dieser Anmeldung ist gesperrt.“ | Windows-Konto oder SQL-Anmeldung gehören einer gesperrten Person. Gehört dasselbe Konto mehreren Personen, prüft der Dienst das nicht |
401 „… ist abgelaufen.“ / „… ist gesperrt.“ / „… ruht; er gilt nur, solange die Verwaltung ihn freigeschaltet hat.“ / „Die Person zu diesem Schlüssel ist gesperrt.“ | Zustand des Schlüssels oder der Person. Diese Unterscheidung erfährt nur, wer den Schlüssel hat; einen zu erraten ist aussichtslos |
403 „Dieser persönliche Schlüssel gilt nicht für diese Herkunft.“ | Der Schlüssel nennt Netze, und die Anfrage kommt von außerhalb – oder ihre Herkunft ist nicht feststellbar |
403 „Der Zugriff auf diese Ressource ist nicht freigegeben.“ | Regeln der Person oder Einschränkung des Schlüssels (Alias, nur lesen) |
403 „Die SQL-Server-Anmeldung dieser Person gibt es nicht.“ | --login nennt eine Anmeldung, die SQL Server nicht kennt; kein Rückfall auf die Anmeldung des Alias |
Schlüssel auf Abruf
Ein Schlüssel kann so ausgestellt werden, dass er ruht, bis die Verwaltung ihn für eine Zeit freischaltet – etwa ein nur lesender Schlüssel ohne zweiten Faktor, den eine Person in Power BI für Vorführungen vor dem Vorstand hinterlegt. Der Schlüssel selbst bleibt über alle Freischaltungen derselbe; Power BI muss also nicht neu eingerichtet werden. Außerhalb einer Freischaltung öffnet er nichts, auch wenn er in einem Bericht, auf einem Laptop oder in einer Mail liegen geblieben ist.
| Schritt | Wie |
|---|---|
| Ausstellen | issue-key mit "onDemand": true; der Schlüssel ruht ab der Ausstellung |
| Freischalten | activate-key { "id", "hours" }; endet von selbst. Eine neue Freischaltung ersetzt die laufende |
| Vorzeitig beenden | deactivate-key { "id" }; wirkt mit der nächsten Anfrage |
| Höchstdauer | max_activation_hours (Menge Settings), sonst Gateway:Store:MaxActivationHours, Vorgabe 12, 1 bis 168. Nie über das Ablaufdatum des Schlüssels hinaus |
Freischalten darf nur die Verwaltung, nicht die Person selbst; beides steht mit Akteur und Ende
im Änderungsprotokoll. Die Höchstlaufzeit des Schlüssels (MaxKeyLifetimeDays) gilt weiter: Nach
ihr braucht es einen neuen Schlüssel.
Selbstbedienung
Eine Person, die sich anders anmelden kann – mit ihrem Windows-Konto oder ihrer SQL-Anmeldung –, stellt sich persönliche Schlüssel selbst aus, etwa für Excel auf dem Laptop, und sperrt sie wieder. Die Verwaltung muss dafür nichts tun außer die Selbstbedienung einmal freizuschalten.
| Adresse | Rumpf | Antwort |
|---|---|---|
GET /self/v1/keys | – | 200 { person, keys: [...], maximumDays }; je Schlüssel Kennung, Bezeichnung, letzte 4 Zeichen, nur lesen, Aliasse, Ausstellung, Ablauf, Sperre, letzte Benutzung – nie der Schlüssel |
POST /self/v1/issue-key | { "label", "expiresAt"?, "readOnly"?, "databases"? } | 201 mit key, einmal; Cache-Control: no-store |
POST /self/v1/revoke-key | { "id" } | 200; einen fremden oder schon gesperrten Schlüssel beantwortet der Dienst mit 404, ohne zu verraten, ob es ihn gibt |
…/self/v1/{alias}/… | wie oben | dasselbe für eine SQL-Anmeldung: Ihr Kennwort prüft SQL Server an einer Datenquelle, daher nennt die Adresse sie |
| Regel | Grund |
|---|---|
Nur mit Windows-Konto oder SQL-Anmeldung, zugeordnet über das eigene Konto bzw. die eigene Anmeldung der Person (Persons.WindowsAccount, Persons.SqlLogin); eine Gruppe ist keine Person | Ein persönlicher Schlüssel stellt keine Schlüssel aus: Ein gestohlener könnte sich sonst über seinen Ablauf und seine Sperre hinaus selbst erneuern. Ein Dienstschlüssel gehört keiner Person |
Aus, bis die Verwaltung die Einstellung self_service_key_days (Menge Settings) oder Gateway:Store:SelfServiceKeyDays auf mehr als 0 setzt | Ob Personen sich selbst Zugänge schaffen dürfen, entscheidet die Verwaltung |
Ein selbst ausgestellter Schlüssel läuft immer ab: ohne Angabe nach self_service_key_days, höchstens nach dem kürzeren aus diesem Wert und MaxKeyLifetimeDays | Schlüssel ohne Ablauf stellt nur die Verwaltung aus |
Einschränkbar auf nur lesen und auf Aliasse; Netze und die Ausnahme vom zweiten Faktor nicht (400) | Beides ist eine Entscheidung der Verwaltung |
| Die Rechte sind die Regeln der Person, wie bei jedem persönlichen Schlüssel | Selbstbedienung erweitert nichts |
Die Anmelderichtlinie wertet die Selbstbedienung als Verwaltung (Bereich Admin); ein neuer Speicher verlangt dort einen zweiten Faktor | Wer Zugänge ausstellt, verwaltet – den eigenen Zugang. Mit der Vorgaberegel braucht die Person einen eingerichteten zweiten Faktor und eine Sitzung (/auth/v1/totp, für eine SQL-Anmeldung /auth/v1/totp/{alias}) |
Nur über eine geschützte Verbindung, wie die Verwaltung; Ausstellen und Sperren stehen im Änderungsprotokoll als Person (Selbstbedienung) | Die Antwort trägt einen Schlüssel |
Die „WklGatewayClient – VBA-Klasse für den Datendienst“ (Dokumentation der Verwaltungsanwendung) bietet dafür OwnKeys, IssueOwnKey und
RevokeOwnKey.
Anmelderichtlinie und zweiter Faktor
Die Anmelderichtlinie legt fest, welches Anmeldeverfahren für welchen Teil des Dienstes
von welchen Netzen oder Ländern einen zweiten Faktor braucht oder abgelehnt wird – etwa
„persönliche Schlüssel aus dem Firmennetz ohne, von außen nur mit TOTP“, „SQL-Anmeldungen nie von
außen“ oder „Datenzugriff nur aus Deutschland“. Sie steht im
Verwaltungsspeicher und wird über die Mengen SignInRules,
SignInRuleItems, SignInRuleExceptions, SignInRuleExceptionItems und Settings der
Verwaltungsschnittstelle gepflegt; ohne Speicher sind nur Ablehnungen
möglich (Gateway:Security:SignInRules in der Konfigurationsdatei).
| Feld einer Regel | Werte | Bedeutung |
|---|---|---|
Scope | All (Vorgabe), Data, Admin | Teil: Datenoberflächen oder Verwaltung |
Method | Any (Vorgabe), ApiKey, PersonalKey, Windows, SqlLogin | Anmeldeverfahren des Aufrufers |
Effect | RequireTotp (Vorgabe), Deny | Zweiter Faktor nötig, oder Ablehnung |
From / ExceptFrom | Netze wie 10.0.0.0/8 oder der Name eines eigenen Netzes aus `Gateway:SignInLog:Networks` | Herkunft; leer = jede. Ein Name steht für alle dort unter ihm geführten Netze; ein unbekannter Name hält den Start an. Eine Herkunft, die sich nicht feststellen lässt, liegt im Bereich jeder Regel |
Persons / ExceptPersons | Personen (Name; im Speicher die Id, Merkmal person/except_person) | Nur für diese Personen bzw. nicht für sie; leer = jeder Aufrufer. Braucht den Verwaltungsspeicher |
WindowsGroups / ExceptWindowsGroups | Windows-Gruppen (Name oder SID) | Nur für Mitglieder bzw. nicht für sie; nur bei Anmeldung mit dem Windows-Konto bekannt. Eine unbekannte Gruppe hält den Start an |
Countries / ExceptCountries | Ländercodes nach ISO 3166-1 alpha-2 wie DE, TH (Groß- und Kleinschreibung gleich) | Nur für Anfragen aus diesen Ländern bzw. nicht für sie; leer = jedes Land. Ein Land, das sich nicht feststellen lässt, liegt im Bereich der Regel. Ein Code, der nicht aus zwei Buchstaben besteht, hält den Start an |
Operators / ExceptOperators | Netzbetreiber als autonomes System wie AS3320 (auch 3320) | Nur für Anfragen aus den Netzen dieser Betreiber bzw. nicht für sie; leer = jeder. Ein Betreiber, der sich nicht feststellen lässt, liegt im Bereich der Regel (siehe Nach Netzbetreiber, Programm und Zeit) |
Clients / ExceptClients | Programmart wie Power Query, WinHTTP, Browser, PowerShell | Nur für Anfragen, die dieses Programm angeben, bzw. nicht für sie; leer = jedes. Vom Client behauptet; eine Anfrage ohne User-Agent liegt im Bereich der Regel |
Hours / ExceptHours | Zeitfenster wie Mon-Fri 06:00-20:00, Sat,Sun, 22:00-06:00 | Nur zu diesen Zeiten bzw. nicht zu ihnen; leer = jederzeit. Uhr des Dienstes, Zone von Gateway:SignInLog:TimeZone. Ein unlesbares Fenster hält den Start an |
Exceptions | Liste von Ausnahmen (siehe unten) | Anfragen, die alle Merkmale einer Ausnahme zugleich erfüllen, sind von der Regel befreit, auf Wunsch bis zu einem Ende |
Label | Text | Notiz, ohne Wirkung |
Mode | Enforce (Vorgabe), Report | Durchsetzen oder nur erproben. Eine Regel in Probe wird bei jeder Anmeldung mit beurteilt, ändert aber keine Entscheidung; das Anmeldeereignis hält fest, was sie getan hätte (siehe Regel erproben) |
Für einzelne Personen oder Gruppen. Eine Regel kann auf Personen oder Windows-Gruppen
beschränkt werden oder sie ausnehmen – etwa „von außen niemand, außer Frank Mustermann“:
{ Scope: Data, Effect: Deny, ExceptFrom: [10.0.0.0/8], ExceptPersons: [Frank Mustermann] }.
Eine Person erkennt der Dienst an ihrem persönlichen Schlüssel, ihrem eigenen Windows-Konto oder
ihrer SQL-Anmeldung; eine Gruppe nur bei einer Windows-Anmeldung. Ein Aufrufer, der keiner Person
zugeordnet ist (Dienstschlüssel), fällt unter keine solche Regel und unter keine Ausnahme. Was eine
Regel für eine Person bedeutet, zeigt explain-sign-in der
Verwaltungsschnittstelle.
Nach Land. Das Land einer Anfrage liest der Dienst aus der Geodatenbank des Anmeldeprotokolls – im Arbeitsspeicher, ohne Netzzugriff, und nur, wenn eine Regel Länder nennt. Kein Land hat eine Anfrage, wenn keine Geodatenbank geladen ist, wenn sie von diesem Rechner, aus einem eigenen Netz (`Gateway:SignInLog:Networks`) oder einem privaten Netz kommt oder wenn die Datenbank die Adresse nicht kennt. Ein solches unbekanntes Land liegt im Bereich jeder Regel: „Datenzugriff nur aus Deutschland“ lehnt es ab. Die eigenen Netze nehmen Sie deshalb über ihre Adressen aus, nicht über ein Land:
{ "Scope": "Data", "Effect": "Deny", "Label": "nur Deutschland",
"ExceptCountries": [ "DE" ], "ExceptFrom": [ "10.0.0.0/8" ] }
Wichtig: Ein Land, das aus einer Adresse abgeleitet ist, ist ein Hinweis, kein Beweis. Ein VPN, ein Proxy oder ein Mobilfunknetz verlegt die Herkunft in ein anderes Land, und Geodatenbanken irren bei einzelnen Netzen. Regeln nach Land sind eine zusätzliche Schicht neben Schlüsseln, Netzen und dem zweiten Faktor; sie ersetzen keine davon.
Nach Netzbetreiber, Programm und Zeit
Eine Regel kann außerdem nach dem Netzbetreiber der Herkunft, nach dem Programm und nach der Uhrzeit fragen. Die drei Merkmale sind unterschiedlich verlässlich:
| Merkmal | Herkunft des Werts | Verlässlichkeit | Unbekannt, wenn |
|---|---|---|---|
| Netzbetreiber | ASN-Datei der Geodatenbank des Anmeldeprotokolls, nur gelesen, wenn eine Regel Betreiber nennt | beobachtet: Der Dienst leitet ihn aus der Adresse ab; meist zuverlässig, ein VPN verlegt ihn | keine ASN-Datei geladen, eigene oder private Adresse, Adresse unbekannt |
| Programm | User-Agent der Anfrage, zusammengefasst wie im Anmeldeprotokoll (Power Query, WinHTTP, Browser, PowerShell, sonst das erste Wort) | behauptet: Jedes Programm kann jeden Text senden; Excel und Power BI Desktop senden denselben | kein User-Agent (der ODBC-Treiber sendet keinen) |
| Zeit | Uhr des Dienstes, in der Zone von Gateway:SignInLog:TimeZone (leer: Zone des Servers) | beobachtet | nie |
Ein unbekannter Betreiber oder ein fehlendes Programm liegt wie ein unbekanntes Land im Bereich der Regel und erfüllt kein Merkmal einer Ausnahme. Ein behauptetes Programm taugt deshalb, um einzuschränken („die Verwaltung nur aus WinHTTP“ lehnt einen Browser ab). Als Ausnahme allein befreit es jeden, der den Text sendet; verbinden Sie es dort mit Personen, Netzen oder einem Ende.
Ein Zeitfenster schreiben Sie als [Tage] [hh:mm-hh:mm]:
- Tage
Mon,Tue,Wed,Thu,Fri,Sat,Sunals Liste (Sat,Sun) oder Bereich (Mon-Fri, auchFri-Mon); ohne Tage gilt jeder Tag. - Uhrzeiten mit ausschließlichem Ende;
24:00ist das Tagesende; ohne Uhrzeit gilt der ganze Tag. - Ein Fenster über Mitternacht (
Mon-Fri 22:00-06:00) gehört zu dem Tag, an dem es beginnt: Freitag 22 Uhr bis Samstag 6 Uhr liegt darin, Montag 3 Uhr nicht.
„SQL-Anmeldung nur Montag bis Freitag, 6 bis 20 Uhr“:
{ "Method": "SqlLogin", "Effect": "Deny", "Label": "SQL nur Bürozeit",
"ExceptHours": [ "Mon-Fri 06:00-20:00" ] }
„Von fremden Netzbetreibern nur mit zweitem Faktor, aus Werk 3 nie“:
{ "Scope": "Data", "Effect": "RequireTotp", "Label": "fremde Netze mit Code",
"ExceptOperators": [ "AS3320" ], "ExceptFrom": [ "Werk 3" ] }
Eigene und private Netze haben keinen Netzbetreiber. Ohne ExceptFrom verlangte die Regel den Code
deshalb auch im Werk.
Das Anmeldeereignis nennt in Signals den beurteilten Netzbetreiber (operator), das Programm
(client) und unter trust je Signal, wie verlässlich es ist (observed, claimed, verified).
Befristete Ausnahmen. Die Listen ExceptPersons, ExceptCountries und ExceptFrom nehmen je
für sich und auf Dauer aus: ExceptPersons: [Frank Mustermann] befreit Frank aus jedem Land. Eine
Ausnahme in Exceptions befreit dagegen nur, wenn alle ihre Merkmale zugleich zutreffen – etwa
„Frank Mustermann aus Thailand bis zum 2. November“:
{ "Scope": "Data", "Effect": "Deny", "Label": "nur Deutschland",
"ExceptCountries": [ "DE" ], "ExceptFrom": [ "10.0.0.0/8" ],
"Exceptions": [ { "Persons": [ "Frank Mustermann" ], "Countries": [ "TH" ],
"Until": "2026-11-02T00:00:00Z", "Label": "Urlaub" } ] }
| Feld einer Ausnahme | Werte | Bedeutung |
|---|---|---|
Persons | Personen (Name; im Speicher die Id) | Der Aufrufer ist eine davon; leer = jeder |
WindowsGroups | Windows-Gruppen (Name oder SID) | Der Aufrufer ist Mitglied einer davon; leer = jeder |
Countries | Ländercodes wie oben | Die Anfrage kommt aus einem davon; leer = jedes Land |
From | Netze wie 203.0.113.0/24 oder Namen eigener Netze | Die Herkunft liegt in einem davon; leer = jede |
Operators | Netzbetreiber wie AS3320 | Die Herkunft gehört zu einem davon; leer = jeder |
Clients | Programmart wie oben | Die Anfrage gibt eines davon an; leer = jedes. Behauptet |
Hours | Zeitfenster wie oben | Die Anfrage fällt in eines davon; leer = jederzeit |
Until | Zeitpunkt in UTC, etwa 2026-11-02T00:00:00Z | Ab diesem Zeitpunkt befreit die Ausnahme niemanden mehr; leer = ohne Ende. Ein Wert ohne Zeitzone gilt als UTC |
Label | Text | Notiz, ohne Wirkung |
- Mindestens ein Merkmal oder ein Ende. Eine Ausnahme ohne beides befreite jeden auf Dauer; die Startprüfung und die Verwaltungsschnittstelle lehnen sie ab.
- Nichtwissen befreit nie. Ein unbekanntes Land, eine unbekannte Herkunft, ein unbekannter Netzbetreiber, ein fehlendes Programm oder ein Aufrufer, der keiner Person zugeordnet ist, erfüllt kein Merkmal, das danach fragt. Fehlt die Geodatenbank, schließt eine Ausnahme nach Land also, statt die Regel zu öffnen.
- Das Ende wirkt sofort. Der Dienst vergleicht es bei jeder Anfrage mit seiner Uhr; dafür ist keine Änderung nötig. Bemerkt er den Ablauf, schreibt er ihn einmal ins Änderungsprotokoll (
Entityexception-lapsed, AkteurDienst (Ablauf), vorher Regel, Notiz und Ende). Eine abgelaufene Ausnahme bleibt stehen, bis sie entfernt wird.
Vorsicht beim Anlegen einer Ablehnung. Eine Regel wirkt, sobald sie gespeichert ist. Wer eine
Ablehnung für alle Bereiche zuerst ohne Ausnahmen anlegt und die Merkmale danach ergänzt, sperrt
sich in diesem Moment selbst aus. Ablehnungen deshalb mit save-sign-in-rule der
Verwaltungsschnittstelle anlegen, der Regel und Ausnahmen in einer
Änderung speichert; ist es passiert, hilft remove-sign-in-rule am Server.
Jede zutreffende Regel zählt, eine Ablehnung vor allem anderen; die Reihenfolge bedeutet nichts.
Ausnahme: Den Austausch eines Codes und das Einrichten des Faktors (/auth/v1/totp, /auth/v1/enrol)
beurteilt der Dienst nur nach Regeln mit Bereich All; eine Ablehnung nur für Data oder Admin
verhindert dort keinen Versuch. Und eine SQL-Anmeldung prüft SQL Server, bevor die Richtlinie
urteilt: Von einer abgelehnten Herkunft antwortet ein falsches Kennwort 401, ein richtiges 403 –
ein Angreifer erfährt also, ob ein Kennwort stimmt, begrenzt nur durch die Fehlversuchsgrenze.
Trifft keine Regel, entscheiden allein die Rechte. Nicht beurteilt wird der unangemeldete Betrieb
der Entwicklungsumgebung; eine Richtlinie, die die Verwaltung ausgesperrt hat, reparieren die
Befehle am Server. Ein neuer Speicher beginnt mit der Regel
„Verwaltung nur mit zweitem Faktor“ (Scope: Admin, Effect: RequireTotp); sie lässt sich wie jede
andere ändern oder löschen. Unabhängig davon verlangt die feste Untergrenze
Gateway:Store:RequireAdminTotp (Vorgabe true) den zweiten Faktor für die Verwaltung und die
Selbstbedienung, bei jedem Anmeldeverfahren und jeder Herkunft; auch ein Schlüssel mit TotpExempt
hebt sie nicht auf. Abschalten lässt sie sich nur in der Konfigurationsdatei. Die Startprüfung lehnt RequireTotp für Dienstschlüssel ab – ein
Dienst ist keine Person und hat keinen zweiten Faktor; dafür Deny schreiben.
Zweiter Faktor (TOTP). Zeitbasierte Codes nach RFC 6238 (6 Stellen, 30 Sekunden), wie jede
Authenticator-App sie erzeugt. Der Faktor gehört einer Person: Ein persönlicher Schlüssel nennt
sie; ein Windows-Konto und eine SQL-Anmeldung finden sie über ihr eigenes Konto (WindowsAccount)
bzw. ihre eigene Anmeldung (SqlLogin); verglichen wird nur der Name der Anmeldung, ohne Groß- und
Kleinschreibung, über alle Aliasse und Server hinweg, und eine so eröffnete Sitzung gilt nicht nur für
den Alias, an dem der Code getauscht wurde. Eine Gruppe ist keine Person; eine Anmeldung, die zu keiner
oder zu zwei Personen passt, erhält 403, wenn ein zweiter Faktor verlangt wird. Eingerichtet wird er
von der Verwaltung (enroll-totp), am besten als Einmal-Link: Die Seite zeigt die otpauth://-Adresse
als QR-Code und daneben den Schlüssel für die manuelle Eingabe. Das Geheimnis steht versiegelt im
Speicher (eigener Zweck, eigener Hauptschlüssel-Wechsel über reseal-store).
Einrichten bei der ersten Anmeldung. Hat eine Person noch keinen zweiten Faktor, verlangt die Richtlinie aber einen, darf sie ihn eine Zeit lang selbst einrichten – mit ihrem ersten Faktor, der bis dahin nur dafür gilt:
POST /auth/v1/enrol[/{alias}] erster Faktor wie beim Tausch eines Codes
Rumpf: { } 200: { "person", "secret", "uri", "qrPng", "openUntil" }
Rumpf: { "code": "123456" } 201: wie beim Tausch - der Faktor ist eingerichtet, eine Sitzung eröffnet
- Wann. Innerhalb von
totp_enrol_hours(MengeSettings, sonstGateway:Security:TotpEnrolHours, Vorgabe 24, höchstens 168,0schaltet das Einrichten bei der Anmeldung ab) nach dem Ausstellen des Schlüssels, mit dem die Anfrage kommt; für eine Person ohne Schlüssel (Windows-Konto) bis zu der Zeit, dieinit-adminoderreset-totpam Server gesetzt hat. - Warum eine Frist. Bis der Faktor eingerichtet ist, steht der Schlüssel allein für die Person. Wer ihn in dieser Zeit abfängt, könnte seine eigene Authenticator-App binden. Die Frist hält diese Zeit kurz; ein Schlüssel, der zu lange gewartet hat, muss neu ausgestellt werden.
- Einmal. Die Bestätigung beendet die Frist und steht im Änderungsprotokoll; einer Person mit Faktor wird die Einrichtung nicht mehr angeboten. Hat jemand anderes zuerst eingerichtet, merkt der rechtmäßige Inhaber es daran. Einen neuen Faktor richtet dann die Verwaltung ein.
- Zwei Schritte. Ohne Code zieht der Dienst ein Geheimnis und antwortet mit Adresse, Schlüssel zum Abtippen und QR-Code als PNG; versiegelt gespeichert wird es erst mit dem ersten passenden Code. Ein neuer Aufruf ohne Code ersetzt das gezogene Geheimnis.
- Jede andere Anfrage der Person beantwortet der Dienst bis dahin mit
401undWWW-Authenticate: Wkl-Totp realm="Wkl.Data.Gateway", enrol="/auth/v1/enrol". Die Verwaltungsanwendung zeigt dann die Einrichtungskarte; die VBA-KlasseWklGatewayClientmeldetgwErrEnrolmentRequiredund bietetBeginTotpEnrolment/ConfirmTotpEnrolment.
Code gegen Sitzung. Ein Code lebt 30 Sekunden; ein Treiber, der durch eine Tabelle blättert,
kann nicht mit jeder Anfrage einen erfragen. Der Code wird deshalb einmal gegen eine Sitzung
getauscht, die danach jede Anfrage in der Kopfzeile X-Wkl-Session begleitet:
POST /auth/v1/totp erster Faktor: persönlicher Schlüssel oder Windows-Konto
POST /auth/v1/totp/{alias} erster Faktor: SQL-Anmeldung (Basic), geprüft an diesem Alias
Rumpf: { "code": "123456" } wahlweise mit "role": "vertrieb"
201: { "session": "…", "id": "t…", "person": "…", "header": "X-Wkl-Session", "expiresAt": "…" }
Nennt der Rumpf role, ist die Sitzung an diese Datenbank-Identität
gebunden: Eine Anfrage ohne eigene Wahl läuft unter ihr. Geprüft wird die Wahl bei jeder Anfrage,
nicht beim Tausch.
- Die Sitzung ist keine Anmeldung. Jede Anfrage trägt weiter ihren ersten Faktor; die Sitzung gilt nur für die Person, das Verfahren und – bei einem Schlüssel – den Schlüssel, mit dem sie eröffnet wurde. Ein gestohlenes Token allein öffnet nichts. Deshalb eine eigene Kopfzeile statt
Authorization: Bearer: Diese trägt bei Windows und Basic schon den ersten Faktor. - Laufzeit
totp_session_hours(MengeSettings, sonstGateway:Security:TotpSessionHours), Vorgabe 10 Stunden, 1 bis 168. - Ende: Ablauf;
RevokedinSessionTokens; Sperren des Schlüssels; Abschalten der Person; neues Einrichten oder Entfernen ihres zweiten Faktors. Nachgeschlagen wird bei jeder Anfrage. - Ein Code gilt einmal (sein Zeitschritt muss nach dem zuletzt angenommenen liegen) und einen Schritt (30 Sekunden) vor oder nach der Uhr des Dienstes; diese Toleranz ist fest und nicht einstellbar. Fünf falsche Codes je Person bzw. zwanzig je Herkunft in 15 Minuten führen zu
429. Die Zähler liegen im Arbeitsspeicher: Ein Neustart setzt sie zurück, und wer einen Namen kennt, kann die Person mit falschen Versuchen eine Zeit lang aussperren. - Der Austausch nur über eine geschützte Verbindung (HTTPS, vertrauter Proxy mit
https, eigener Rechner).
Clients ohne Dialog – Power BI, Excel, Skripte – können keinen Code erfragen. Für sie gibt es
Schlüssel mit TotpExempt: von einem verlangten zweiten Faktor ausgenommen, nicht von einer
Ablehnung, und nur als nur lesender Schlüssel zulässig. Mit Rechten, die die Person auf
freigegebene Sichten beschränken, und auf Wunsch einer Netzbindung ist das der eng begrenzte Zugang
für Berichte.
| Antwort | Bedeutung |
|---|---|
401 mit WWW-Authenticate: Wkl-Totp realm="Wkl.Data.Gateway", endpoint="/auth/v1/totp" | Zweiter Faktor nötig: keine oder keine gültige Sitzung. Bei einer SQL-Anmeldung nennt endpoint den Alias (/auth/v1/totp/{alias}). Der ODBC-Treiber fragt den Code in einem Dialog ab und hält die Sitzung für den Prozess |
401 „Der Code ist falsch oder wurde schon benutzt.“ | Austausch abgelehnt |
403 „Die Anmelderichtlinie lässt dieses Anmeldeverfahren von dieser Herkunft nicht zu.“ | Regel Deny. Die Antwort nennt kein Land; das Anmeldeprotokoll führt eine Ablehnung, die allein auf Regeln mit Ländern beruht, mit dem Grund deniedByCountry, sonst denied |
401 mit WWW-Authenticate: Wkl-Totp realm="Wkl.Data.Gateway", enrol="/auth/v1/enrol" | Zweiter Faktor nötig, aber noch nicht eingerichtet; die Person darf ihn jetzt einrichten |
403 „… gehört zu keiner Person“ / „… ist keiner eingerichtet, und die Frist … ist abgelaufen.“ | Zweiter Faktor verlangt, aber nicht möglich |
403 „Ein zweiter Faktor wird nur über HTTPS oder vom eigenen Rechner angenommen.“ | Austausch über ungeschützte Verbindung |
429 | Zu viele falsche Codes |
Regel erproben
Eine neue Regel – vor allem eine Ablehnung – erproben Sie zuerst mit Mode = Report. Die Regel wird
dann bei jeder Anmeldung wie eine durchgesetzte beurteilt, ändert aber nichts: Wer ohne sie
zugelassen wäre, bleibt zugelassen. Das Anmeldeereignis nennt sie in Rules mit "mode": "report";
SignInRuleReports zählt je Regel und Version, wie viele Anmeldungen sie getroffen hätte, von wie
vielen Personen und Herkünften, und welche eine Ausnahme befreit hätte (siehe
Verwaltung). explain-sign-in zeigt sie
getrennt unter tried.
Passt das Ergebnis, schalten Sie die Regel mit save-sign-in-rule und "mode": "Enforce" scharf; ab
dann wirkt sie. Die Umschaltung steht im Änderungsprotokoll und ändert die Version der Regel, so dass
Ereignisse aus der Probe und aus dem Betrieb unterscheidbar bleiben. Die Untergrenze der Verwaltung
(RequireAdminTotp) ist keine Regel und lässt sich nicht erproben.