Identity-Methoden
Seit System.Identity 2.29.0 deklariert das Modell die sicherheitskritischen Operationen von Benutzern, Gruppen, Clients und
Datenberechtigungen als CK-Methoden. Eine Methode hat einen festen Vertrag - Parameter,
Ergebnis, deklarierte Fehlercodes und die Rollen, die sie aufrufen dürfen -, damit ein Aufrufer sie im Tenant-Schema findet und der
Identity Service genau diesen Vertrag implementiert.
Version 2.29.0 deklariert die Methoden. Der Identity Service bedient sie mit Handlern, die Story für Story folgen:
User.ChangePassword ist der erste (siehe User.ChangePassword), User.ResetPassword der zweite (siehe
User.ResetPassword), danach die Rollen-Methoden SetRoles, AddRole und RemoveRole des Benutzers (siehe
Benutzerrollen); danach die Methoden für Gruppen und Datenberechtigungen (siehe Gruppen und Datenberechtigungen) und die Client-Secret-Methoden (siehe Client-Secrets); danach User.CreateUser und User.Merge; damit hat jede deklarierte Methode einen Handler. Eine deklarierte Methode ohne
Handler antwortet mit METHOD_HANDLER_NOT_AVAILABLE. Die REST-API des Identity Service und octo-cli funktionieren unverändert
weiter. Der Identity Service wird erst mit dem neuen Modell ausgeliefert, wenn die Handler enthalten sind.
Benutzer
| Methode | Art | Wer darf aufrufen | Parameter | Deklarierte Fehler |
|---|---|---|---|---|
ChangePassword-1 | Instanz | der Benutzer selbst (allowSelf) | currentPassword, newPassword (beide sensibel) | PASSWORD_POLICY_VIOLATION, CURRENT_PASSWORD_INVALID, USER_LOCKED_OUT, SHADOW_USER_PASSWORD_NOT_ALLOWED |
ResetPassword-1 | Instanz | UserManagement | newPassword (sensibel) | PASSWORD_POLICY_VIOLATION, SHADOW_USER_PASSWORD_NOT_ALLOWED |
SetRoles-1 | Instanz | UserManagement | roleNames (Liste) | ROLE_NOT_FOUND |
AddRole-1 | Instanz | UserManagement | roleName | ROLE_NOT_FOUND, ROLE_ALREADY_ASSIGNED |
RemoveRole-1 | Instanz | UserManagement | roleName | ROLE_NOT_FOUND, ROLE_NOT_ASSIGNED |
Merge-1 | Instanz | UserManagement | sourceUserName | SOURCE_USER_NOT_FOUND, CANNOT_MERGE_INTO_ITSELF, MERGE_FAILED |
DisableTwoFactor-1 | Instanz | UserManagement | keine | keine (seit System.Identity 2.30.0, siehe unten) |
CreateUser-1 | statisch | UserManagement | userName, email, firstName, lastName (optional), password (optional, sensibel) | USER_NAME_RESERVED, USER_ALREADY_EXISTS, PASSWORD_POLICY_VIOLATION |
ChangePassword ist für den angemeldeten Benutzer und braucht das aktuelle Passwort; eine Administratorin oder ein Administrator
verwendet ResetPassword. Die statische Anlage-Methode heißt CreateUser, weil die Namen Create, Update und Delete für die
generischen Mutationen reserviert sind. CreateUser ist neben der REST-API der einzige Weg, einen Benutzer anzulegen, siehe
unten. Das Modell kennzeichnet die Methode noch nicht mit replacesGenericCreate (das wäre eine Major-Änderung
des Modells); die Plattform setzt dieselbe Regel durch.
Gruppe
| Methode | Wer darf aufrufen | Parameter | Deklarierte Fehler |
|---|---|---|---|
AddMember-1 | UserManagement | memberKind (User oder Client), memberId (rtId des Benutzers, Client-Id des Clients) | MEMBER_NOT_FOUND, MEMBER_ALREADY_IN_GROUP |
RemoveMember-1 | UserManagement | memberKind, memberId | MEMBER_NOT_FOUND, MEMBER_NOT_IN_GROUP |
SetRoles-1 | UserManagement | roleNames (Liste) | ROLE_NOT_FOUND |
Client
| Methode | Wer darf aufrufen | Parameter | Ergebnis | Deklarierte Fehler |
|---|---|---|---|---|
AddSecret-1 | TenantManagement, UserManagement | description, expirationDate (beide optional) | das erzeugte Secret (sensibel, einmalig sichtbar) | CLIENT_SECRET_NOT_REQUIRED |
RemoveSecret-1 | TenantManagement, UserManagement | secretValue (sensibel) | - | SECRET_NOT_FOUND |
Datenberechtigung
| Methode | Wer darf aufrufen | Parameter | Deklarierte Fehler |
|---|---|---|---|
GrantToRole-1 | UserManagement | roleName | ROLE_NOT_FOUND, PERMISSION_ALREADY_GRANTED |
RevokeFromRole-1 | UserManagement | roleName | ROLE_NOT_FOUND, PERMISSION_NOT_GRANTED |
Regeln für alle Methoden
- Rollen: Die Rollen sind die der REST-API (
UserManagement; für Client-Secrets zusätzlichTenantManagement). Ein Methodenaufruf braucht außerdem den Scopeocto_api; ohne passende Rolle wird der Aufruf abgewiesen, bevor der Ziel-Datensatz gelesen wird. - Sensible Werte: Jeder Parameter, der ein Passwort oder ein Secret trägt, ist als
sensitivedeklariert, ebenso das Ergebnis vonAddSecret. Solche Werte erscheinen nie in Logs, Audit-Einträgen oder Traces. Ein sensibler Parameter kann nicht von einer Pipeline behandelt werden. - Datenzugriff: Jede Methode deklariert
dataAccess: Write: Der Aufrufer braucht eine Schreibberechtigung auf dem Ziel-Datensatz (Methoden-Autorisierung). - Generisches Anlegen bleibt erhalten für Gruppen, Clients und Datenberechtigungen: Das Blueprint
System.Identity.Bootstraplegt sie an, und ein ersetztes generisches Anlegen ließe das Bootstrap jedes neuen Tenants scheitern. - Versionierung: Das Hinzufügen der Methoden ist eine additive Änderung, eine Minor-Version (
2.28.0zu2.29.0).
Wie der Identity Service Methoden bedient
Der Identity Service betreibt seine Methoden als Remote-Handler am Message-Bus: Das Gateway des Asset Repository leitet einen Aufruf
mit dem Access-Token des Aufrufers weiter, der Identity Service prüft dieses Token erneut (Aussteller, Signatur, Ablauf, Tenant
und den Scope octo_api, gegen seine eigene Authority) und führt erst dann den Handler aus. Ein Aufruf ohne gültiges Token wird mit
METHOD_FORBIDDEN beantwortet. Jeder Handler läuft im Tenant des Aufrufs und schreibt pro Aufruf (Erfolg oder Fehler) einen Eintrag in
das Ereignisprotokoll des Tenants; der Eintrag enthält Kennungen und den Ergebniscode, nie einen Parameterwert.
Schalter für Methoden mit Passwort oder Secret
| Einstellung | Standard | Bedeutung |
|---|---|---|
Methods:Identity:EnablePasswordMethods (Umgebungsvariable OCTO_Methods__Identity__EnablePasswordMethods) | false | Registriert die Handler von Methoden mit sensiblem Parameter oder Ergebnis (User.ChangePassword, User.ResetPassword, Client.AddSecret, Client.RemoveSecret, User.CreateUser). |
Mit dem Standardwert kündigt der Identity Service diese Methoden nicht an und das Gateway antwortet mit
METHOD_HANDLER_NOT_AVAILABLE; die REST-API ist nicht betroffen. Der Schalter wird beim Start gelesen, der Dienst muss nach einer
Änderung neu gestartet werden.
Die Methoden-Queues transportieren die Parameter. Auf staging-1, prod-1 und prod-2 darf keine Methode mit Passwort oder Secret
aktiviert werden, bevor der eingeschränkte Broker-Benutzer (B0) ausgerollt ist. Lokale Umgebungen und test-2 dürfen sie mit
Testkonten aktivieren. Im Helm-Deployment wird der Wert als Umgebungsvariable des Identity Service gesetzt
(OCTO_Methods__Identity__EnablePasswordMethods=true); sonst bleibt er ungesetzt.
User.ChangePassword
Ein angemeldeter Benutzer ändert sein eigenes Passwort. Der Aufruf braucht das aktuelle Passwort (currentPassword) und das neue
(newPassword).
| Situation | Antwort |
|---|---|
| Erfolg | das Passwort ist geändert, der Security Stamp rotiert und alle Refresh-Tokens und Autorisierungen des Benutzers in diesem Tenant werden widerrufen (andere Sitzungen enden) |
| das Ziel ist ein anderer Benutzer, auch bei Administrator oder Service-Token | METHOD_FORBIDDEN (reason = not-self); die Antwort ist gleich, ob das Ziel existiert oder nicht. Administratoren verwenden ResetPassword. |
| falsches aktuelles Passwort | CURRENT_PASSWORD_INVALID; zählt wie eine fehlgeschlagene Anmeldung für die Sperre |
| der Benutzer ist gesperrt | USER_LOCKED_OUT (auch bei richtigem aktuellem Passwort) |
| das neue Passwort verletzt die Richtlinie | PASSWORD_POLICY_VIOLATION mit einem Detail je verletzter Regel (nur der Code, zum Beispiel PasswordTooShort, PasswordRequiresDigit); nie das Passwort |
| Cross-Tenant-Schattenbenutzer | SHADOW_USER_PASSWORD_NOT_ALLOWED (das Passwort wird im Heimat-Tenant geändert) |
Die Richtlinie ist die von ASP.NET Core Identity (Mindestlänge 6, Ziffer, Klein-, Großbuchstabe, Sonderzeichen); ein Client
verzweigt auf den Detail-code, nicht auf einen Text.
Benutzerrollen
SetRoles, AddRole und RemoveRole ändern die direkten Rollen eines Benutzers. Sie folgen den Regeln der REST-Endpunkte
(PUT /users/{user}/roles, PUT und DELETE /users/{user}/roles/{role}) und erlauben nie mehr als REST: Wer eine Rolle über REST
nicht ändern darf, darf sie auch mit einer Methode nicht ändern. Rollen, die ein Benutzer von einer Gruppe erbt, werden weder
gelesen noch geschrieben. Diese Methoden tragen kein Passwort und kein Secret, stehen daher nicht hinter dem Schalter oben und
sind verfügbar, sobald der Identity Service läuft.
| Methode | Wirkung | Antworten |
|---|---|---|
SetRoles (roleNames) | ersetzt die direkten Rollen durch die angegebene Liste; eine leere Liste entfernt alle direkten Rollen | ROLE_NOT_FOUND, wenn ein Name unbekannt ist: dann wird nichts geändert |
AddRole (roleName) | fügt eine Rolle hinzu | ROLE_NOT_FOUND, ROLE_ALREADY_ASSIGNED |
RemoveRole (roleName) | entfernt eine Rolle | ROLE_NOT_FOUND, ROLE_NOT_ASSIGNED |
Die Regeln im Vergleich mit REST:
| Regel | REST | Methode |
|---|---|---|
der Aufrufer braucht die Tenant-Rolle UserManagement und den Scope octo_api (der Nur-Lesen-Scope genügt nicht) | 403 | METHOD_FORBIDDEN; der Identity Service prüft das am validierten Access-Token erneut, eine gefälschte Nachricht auf dem Bus wird ebenfalls abgewiesen |
| der Benutzer muss existieren | 404 | METHOD_TARGET_NOT_FOUND |
| die Rolle muss existieren (Namen sind nicht groß-/kleinschreibungsabhängig) | 404 | ROLE_NOT_FOUND, der Parameter roleName nennt die Rolle |
| eine bereits zugewiesene Rolle kann nicht hinzugefügt werden | 400 | ROLE_ALREADY_ASSIGNED |
| eine nicht zugewiesene Rolle kann nicht entfernt werden | 400 | ROLE_NOT_ASSIGNED |
| Service-Clients werden nach ihren Client-Rollen beurteilt | erlaubt mit UserManagement | erlaubt mit UserManagement |
REST und die Methoden teilen auch die Regeln gegen Rechteausweitung, die bei den Rollen in
Benutzer und Rollen beschrieben sind. Ein abgelehnter
Aufruf antwortet mit METHOD_FORBIDDEN und dem Parameter reason (es wird kein weiterer Fehlercode deklariert, das Modell bleibt
unverändert):
reason | Bedeutung | REST |
|---|---|---|
role-required | dem Aufrufer fehlt die Rolle UserManagement oder der Scope octo_api | 403 |
self-grant | der Aufrufer wollte seinem eigenen Benutzer eine direkte Rolle hinzufügen | 403, code = self-grant |
role-not-held | der Aufrufer wollte eine eingebaute Rolle vergeben, die er nicht hält; der Parameter roleNames nennt die Rollen | 403, code = role-not-held, roleNames |
last-administrator | die Änderung ließe den Tenant ohne Benutzer mit UserManagement zurück | 409, code = last-administrator |
SetRoles wird anhand der Differenz zu den aktuellen direkten Rollen beurteilt. Ein unbekannter Rollenname ändert in beiden
Transporten nichts (ROLE_NOT_FOUND; REST antwortet mit 404).
Wie bei REST beendet eine Rollenänderung keine laufenden Sitzungen: Das nächste Token des Benutzers trägt die neuen Rollen. Jeder
Aufruf, auch jede Abweisung, schreibt einen Eintrag in das Ereignisprotokoll des Tenants (Kategorie Identity.Method) mit dem
aufrufenden Benutzer, dem Ziel, dem Ergebnis (bei einer Abweisung auch reason und die abgelehnten roleNames) und den direkten Rollen vor und nach dem Aufruf.
User.DisableTwoFactor
Ein Benutzeradministrator (Rolle UserManagement) schaltet den zweiten Faktor eines Benutzers ab, zum Beispiel wenn der
Benutzer die Authenticator-App verloren hat oder der Authenticator-Schlüssel eine Wiederherstellung nicht überstanden hat. Deklariert
seit System.Identity 2.30.0. Die Methode trägt kein Passwort und kein Geheimnis und wird daher unabhängig von
Methods:Identity:EnablePasswordMethods bedient. Der REST-Endpunkt POST {tenantId}/v1/users/{userName}/disableTwoFactor tut
dasselbe und antwortet mit { "twoFactorWasEnabled": true|false }.
| Situation | Antwort |
|---|---|
| Erfolg | Authenticator-Schlüssel und Wiederherstellungscodes sind entfernt, TwoFactorEnabled ist false, der Security Stamp wird erneuert und alle Refresh Tokens und Autorisierungen des Benutzers in diesem Tenant werden widerrufen. Der Benutzer meldet sich mit dem Passwort an und kann in den Kontoeinstellungen einen neuen Authenticator einrichten. Ein Benutzer ohne zweiten Faktor wird genauso behandelt. |
der Aufrufer hat die Rolle UserManagement (oder den Scope octo_api) nicht | METHOD_FORBIDDEN; die Antwort ist gleich, ob das Ziel existiert oder nicht |
| das Ziel existiert nicht (nur für berechtigte Aufrufer) | METHOD_TARGET_NOT_FOUND |
| ein Schreibvorgang oder der Widerruf schlägt fehl | METHOD_HANDLER_FAILED; nie ein Erfolg, solange der Schlüssel oder alte Refresh Tokens bestehen |
Audit. Jeder Aufruf schreibt einen Eintrag in das Ereignisprotokoll des Tenants (Kategorie Identity.Method) mit Aufrufer, Ziel,
Ergebnis und twoFactorWasEnabled, und der Identity Service schreibt eine Logzeile mit Tenant, Benutzer, Aufrufer und Pfad. Schlüssel,
Wiederherstellungscodes und Tokens werden nie protokolliert. TwoFactorEnabled über eine generische GraphQL-Mutation oder einen Import
zu setzen, wird abgewiesen, siehe Felder, die nur der Identity Service schreibt.
User.CreateUser
Eine Benutzeradministratorin oder ein Benutzeradministrator (Rolle UserManagement) legt einen Benutzer an, mit
Anfangspasswort oder als Einladung ohne Passwort. Statische Methode: Sie wird auf dem Typ aufgerufen, nicht auf einem Benutzer.
Die Methode hat einen sensiblen Parameter (password) und wird daher nur bedient, wenn
Methods:Identity:EnablePasswordMethods true ist, auch für eine Einladung
ohne Passwort; mit dem Standardwert false antwortet das Gateway mit METHOD_HANDLER_NOT_AVAILABLE. Der REST-Endpunkt
POST {tenantId}/v1/users macht dasselbe; beide sind die einzigen Wege, einen lokalen Benutzer anzulegen (siehe
Benutzer erstellen).
| Situation | Antwort |
|---|---|
| Erfolg | Der Benutzer wird über den User-Manager des Identity Service angelegt: Passwortrichtlinie (geprüft, bevor der Benutzer gespeichert wird), normalisierter Benutzername und normalisierte E-Mail-Adresse, neuer Security-Stamp. Mit password kann sich der Benutzer sofort anmelden und erhält die Bestätigung der E-Mail-Adresse; ohne Passwort (oder mit einem leeren) erhält er die Willkommens-Mail mit einem Link, um ein Passwort zu setzen. Das Ergebnis ist die Id (rtId) des neuen Benutzers, als einfache Zeichenkette in result ("result": "6ae7c66ccc5a608ccf779df9"). |
der Benutzername beginnt mit xt_ (reserviert für tenantübergreifende Benutzer) | USER_NAME_RESERVED |
| ein Benutzer mit diesem Namen (in beliebiger Schreibweise) oder dieser E-Mail-Adresse existiert | USER_ALREADY_EXISTS mit dem Parameter field = userName oder email. Der REST-Endpunkt POST {tenantId}/v1/users wendet dieselbe Regel an (409, code: USER_ALREADY_EXISTS, field: userName oder email; vor Release 3.5.0 antwortete ein doppelter Benutzername mit 400), auch wenn ein bestehender Benutzer umbenannt wird oder auf die Adresse wechselt (PUT {tenantId}/v1/users/{userName}). |
| das Passwort verletzt die Passwortrichtlinie | PASSWORD_POLICY_VIOLATION; die Details nennen die verletzten Regeln (zum Beispiel PasswordTooShort), nie den Wert. Es wird nichts gespeichert. |
| der Benutzername fehlt oder enthält Zeichen, die der Identity Service nicht annimmt, oder die E-Mail-Adresse ist ungültig | METHOD_VALIDATION_FAILED mit dem Parameter field |
dem Aufrufer fehlt die Rolle UserManagement (oder der Scope octo_api) | METHOD_FORBIDDEN (das Gateway weist den Aufruf vorher ab; der Identity Service prüft noch einmal) |
Audit. Jeder Aufruf schreibt einen Eintrag in das Ereignisprotokoll des Tenants (Kategorie Identity.Method) mit dem Aufrufer,
dem Ergebnis, dem Benutzernamen, ob ein Passwort übergeben wurde (withPassword) und bei Erfolg der Id des neuen Benutzers. Das
Passwort wird nie protokolliert, auditiert oder in einem Fehler zurückgegeben.
Generisches Anlegen. Ein GraphQL-Create (generisch, typisiert oder eine Zeile einer Runtime-Query), ein MCP-Create, ein
Pipeline-Insert, ein vom Benutzer gestarteter ImportRt und die Seed-Daten eines Blueprints weisen einen neuen Benutzer mit
GENERIC_CREATE_REPLACED_BY_METHOD und der Methoden-Id System.Identity/User.CreateUser-1 ab; ein bestehender Benutzer lässt sich
weiterhin ändern (im Rahmen von Felder, die nur der Identity Service schreibt).
User.Merge
Eine Benutzeradministratorin oder ein Benutzeradministrator (Rolle UserManagement) führt einen doppelten Benutzer mit einem
anderen zusammen, zum Beispiel ein lokales Konto und das Konto, das eine externe Anmeldung für dieselbe Person angelegt hat. Die
Methode wird auf dem Benutzer aufgerufen, der bleibt (dem Ziel), und nennt das Duplikat in sourceUserName. Sie trägt kein Passwort
und kein Secret und wird daher unabhängig von Methods:Identity:EnablePasswordMethods bedient. Der REST-Endpunkt
POST {tenantId}/v1/users/{userName}/merge (Body { "sourceUserName" }) führt denselben Code aus und hinterlässt denselben Zustand
(siehe Doppelte Benutzer zusammenführen).
| Situation | Antwort |
|---|---|
| Erfolg | Die externen Anmeldungen des Quellbenutzers (zum Beispiel Google oder Microsoft) gehen auf den Zielbenutzer über, alle Refresh-Tokens, Autorisierungen und Browser-Sitzungen des Quellbenutzers in diesem Tenant werden widerrufen, und der Quellbenutzer wird gelöscht. Die nächste Anmeldung mit einer übertragenen Anmeldung findet den Zielbenutzer. Rollen, Gruppenmitgliedschaften, Claims und tenantübergreifende Mappings des Quellbenutzers werden nicht übertragen; sie verschwinden mit dem Quellbenutzer, ein Zusammenführen gibt dem Zielbenutzer also nie eine Rolle. |
| der Quellbenutzer existiert nicht, oder der Aufrufer darf ihn nicht lesen (Datenberechtigungen) | SOURCE_USER_NOT_FOUND |
| Quelle und Ziel sind derselbe Benutzer | CANNOT_MERGE_INTO_ITSELF |
sourceUserName fehlt | METHOD_VALIDATION_FAILED |
| der Aufrufer darf den Quellbenutzer lesen, aber nicht ändern (Datenberechtigungen) | METHOD_FORBIDDEN mit dem Parameter reason = data-permission |
der Quellbenutzer ist der letzte Benutzer mit UserManagement | METHOD_FORBIDDEN mit reason = last-administrator (REST: 409), siehe Regeln für das Ändern der Rollen eines Benutzers |
dem Aufrufer fehlt die Rolle UserManagement (oder der Scope octo_api) | METHOD_FORBIDDEN; die Antwort ist gleich, ob das Ziel existiert oder nicht |
| das Ziel existiert nicht (nur für berechtigte Aufrufer) | METHOD_TARGET_NOT_FOUND |
| eine Anmeldung konnte nicht übertragen oder der Quellbenutzer nicht gelöscht werden | MERGE_FAILED mit dem Parameter step (removeLogin, addLogin oder deleteSource), loginProvider bei den Anmelde-Schritten und den Fehlercodes des User-Managers als Details |
Ein abgewiesener Aufruf ändert nichts.
Audit. Jeder Aufruf schreibt einen Eintrag in das Ereignisprotokoll des Tenants (Kategorie Identity.Method) mit dem Aufrufer,
dem Ziel, dem Ergebnis, dem Quellbenutzer (sourceUserName, sourceRtId) und nach einem Zusammenführen der Zahl der übertragenen
Anmeldungen (transferredLogins) und der widerrufenen Tokens (revokedTokens); eine Abweisung ergänzt reason. Der Identity
Service schreibt außerdem eine Logzeile zum Widerruf mit Tenant, Quellbenutzer und Aufrufer. Ein Token wird nie protokolliert oder
auditiert.
User.ResetPassword
Ein Benutzeradministrator (Rolle UserManagement) setzt ein neues Passwort ohne das aktuelle, auch für einen Benutzer, der nach zu
vielen fehlgeschlagenen Anmeldungen gesperrt ist. Der Aufruf braucht nur das neue Passwort (newPassword). Wie jede Methode mit
Passwort wird sie nur bedient, wenn Methods:Identity:EnablePasswordMethods auf
true steht; mit dem Standard (false) antwortet das Gateway METHOD_HANDLER_NOT_AVAILABLE.
| Situation | Antwort |
|---|---|
| Erfolg | das Passwort ist geändert, der Security Stamp rotiert, alle Refresh-Tokens und Autorisierungen des Benutzers in diesem Tenant werden widerrufen (jede Sitzung endet) und eine aktive Sperre wird aufgehoben (LockoutEnd ist leer, der Zähler fehlgeschlagener Anmeldungen ist 0). Der Benutzer kann sich sofort mit dem neuen Passwort anmelden. |
der Aufrufer hat nicht die Rolle UserManagement (auch ein Benutzer, der sein eigenes Passwort zurücksetzt, oder ein gefälschter Aufruf auf dem Bus) | METHOD_FORBIDDEN; die Antwort ist gleich, ob das Ziel existiert oder nicht |
| das Ziel existiert nicht (nur für berechtigte Aufrufer) | METHOD_TARGET_NOT_FOUND |
| das neue Passwort verletzt die Richtlinie | PASSWORD_POLICY_VIOLATION mit einem Detail je verletzter Regel (nur der Code, zum Beispiel PasswordTooShort); nie das Passwort. Es wird nichts geändert, eine Sperre bleibt bestehen. |
| Cross-Tenant-Schattenbenutzer | SHADOW_USER_PASSWORD_NOT_ALLOWED (das Passwort wird im Heimat-Tenant geändert) |
Audit. Jeder Aufruf schreibt einen Eintrag in das Ereignisprotokoll des Tenants (Kategorie Identity.Method), bei Erfolg und bei
jedem Fehler: den Tenant, den Aufrufer (callerSubject: Benutzer- oder Client-Id), das Ziel (targetRtId), das Ergebnis (SUCCESS
oder den Fehlercode) und lockoutLifted (true, wenn der Aufruf eine aktive Sperre aufgehoben hat, sonst false). Das Passwort ist nie Teil
einer Logzeile, eines Audit-Eintrags oder eines Traces.
Unterschied zum REST-Endpunkt. POST system/v1/users/ResetPassword hebt eine Sperre nicht auf: der Benutzer bleibt gesperrt,
bis die Sperrzeit abgelaufen ist, und der Endpunkt sendet dem Benutzer ein zweites Reset-Token per E-Mail. Die Methode hebt die
Sperre auf und sendet keine E-Mail; eine Benachrichtigung des Benutzers ist noch nicht Teil der Methode. Der REST-Endpunkt bleibt unverändert.
Gruppen
Der Identity Service bedient Group.AddMember, Group.RemoveMember und Group.SetRoles mit den Regeln der REST-Endpunkte
system/v1/groups/{group}/members/... und .../roles, nie mit mehr. Sie werden unabhängig von
EnablePasswordMethods bedient: sie tragen kein Passwort und kein Secret.
| Methode | Was sie tut | Antworten |
|---|---|---|
AddMember (memberKind, memberId) | fügt einen Benutzer oder einen Client zur Gruppe hinzu | MEMBER_NOT_FOUND, MEMBER_ALREADY_IN_GROUP |
RemoveMember (memberKind, memberId) | entfernt einen Benutzer oder einen Client aus der Gruppe | MEMBER_NOT_FOUND, MEMBER_NOT_IN_GROUP |
SetRoles (roleNames) | ersetzt die Rollen der Gruppe durch die angegebene Liste; eine leere Liste entfernt alle Rollen | ROLE_NOT_FOUND, wenn ein Name unbekannt ist: dann wird nichts geändert |
memberId ist die Id des Benutzers oder des Clients (der Routenparameter von REST); bei einem Client wird auch die OAuth-Client-Id
akzeptiert. SetRoles nimmt Rollennamen (Groß-/Kleinschreibung egal); REST nimmt Rollen-Ids.
Die Regeln neben REST:
| Regel | REST | Methode |
|---|---|---|
der Aufrufer braucht die Tenant-Rolle UserManagement und den Scope octo_api | 403 | METHOD_FORBIDDEN (reason = role-required); wird am validierten Access-Token erneut geprüft, eine gefälschte Nachricht auf dem Bus wird abgewiesen |
| die Gruppe muss existieren | 404 | METHOD_TARGET_NOT_FOUND |
| Mitglied oder Rolle müssen existieren, und der Aufrufer muss sie lesen dürfen | ein unbehandelter Engine-Fehler | MEMBER_NOT_FOUND, ROLE_NOT_FOUND |
| ein Mitglied kann nicht zweimal hinzugefügt, ein Nicht-Mitglied nicht entfernt werden | stilles No-op | MEMBER_ALREADY_IN_GROUP, MEMBER_NOT_IN_GROUP |
| ein Aufrufer kann sich selbst keine Rolle geben (auch nicht über eine Gruppe, der er angehört) | 403, code = self-grant | METHOD_FORBIDDEN, reason = self-grant |
| ein Aufrufer kann keine eingebaute Rolle vergeben, die er selbst nicht hat | 403, code = role-not-held | METHOD_FORBIDDEN, reason = role-not-held, roleNames |
die Änderung darf den Tenant nicht ohne einen Benutzer zurücklassen, der UserManagement hält (beurteilt über direkte Rollen, Gruppen, verschachtelte Gruppen und Mappings) | 409, code = last-administrator | METHOD_FORBIDDEN, reason = last-administrator |
| das Entfernen eines Clients wird nicht beurteilt (ein Client gibt niemandem etwas) | erlaubt | erlaubt |
Die Regeln gegen Rechteausweitung sind derselbe Code wie bei den Rollen eines Benutzers, siehe Benutzer und Rollen. Wie bei REST beendet
eine Änderung keine laufenden Sitzungen: das nächste Token des Mitglieds trägt die Rollen der Gruppe, wie sie dann sind. Jeder Aufruf,
auch jede Ablehnung, schreibt einen Eintrag in das Ereignisprotokoll des Tenants (Kategorie Identity.Method) mit dem aufrufenden Benutzer, der
Gruppe, dem Ergebnis, memberKind und memberId (bei SetRoles die Rollennamen davor und danach, bei einer Ablehnung auch der reason).
Datenberechtigungen
DataPermission.GrantToRole und DataPermission.RevokeFromRole erteilen oder entziehen einer Rolle eine Datenberechtigung über den
Rollennamen (Groß-/Kleinschreibung egal), mit den Regeln von POST und DELETE system/v1/dataPermissions/{permissionId}/roles/{roleName}.
Die Datenberechtigung ist das Ziel des Aufrufs.
| Situation | Antwort |
|---|---|
| Erfolg | die Rolle hält die Berechtigung (oder nicht mehr) |
dem Aufrufer fehlt die Rolle UserManagement oder der Scope octo_api | METHOD_FORBIDDEN (reason = role-required) |
| die Datenberechtigung existiert nicht | METHOD_TARGET_NOT_FOUND (REST: ein unbehandelter Fehler) |
| die Rolle existiert nicht, oder der Aufrufer darf sie nicht lesen | ROLE_NOT_FOUND |
| der Aufrufer darf die Rolle lesen, aber nicht ändern | METHOD_FORBIDDEN (reason = data-permission) |
GrantToRole für eine Rolle, die die Berechtigung schon hält | PERMISSION_ALREADY_GRANTED (REST: No-op) |
RevokeFromRole für eine Rolle, die sie nicht hält | PERMISSION_NOT_GRANTED (REST: No-op) |
Eine Datenberechtigung gibt Zugriff auf Daten, keine Rollen: Wie REST wenden die Methoden darauf keine Regeln gegen Rechteausweitung an. Die Rolle wird
mit den Datenberechtigungen des Aufrufers geprüft; solange keine Policy den Rollentyp schützt, ist die Prüfung offen, wie bei REST. Jeder Aufruf
schreibt einen Eintrag in das Ereignisprotokoll des Tenants (Kategorie Identity.Method) mit permissionId und roleName.
Client-Secrets
Client.AddSecret erzeugt ein neues Secret für einen Client und gibt es einmal als Ergebnis des Aufrufs zurück;
Client.RemoveSecret entfernt ein Secret wieder. Ziel des Aufrufs ist der Client (seine Datensatz-Id). Beide tragen ein Secret und
werden daher nur bedient, wenn Methods:Identity:EnablePasswordMethods auf
true steht; mit dem Standardwert (false) antwortet das Gateway METHOD_HANDLER_NOT_AVAILABLE. Sie folgen den REST-Endpunkten
POST und POST system/v1/apiSecrets/client/{clientId}/delete (gespeicherter Hash im Request-Body), die unverändert bleiben.
| Methode | Was sie tut | Antworten |
|---|---|---|
AddSecret (description, expirationDate, beide optional) | erzeugt ein Secret aus 256 Zufallsbits (URL-sicheres Base64), speichert nur seinen SHA-256-Hash und gibt das Secret zurück | CLIENT_SECRET_NOT_REQUIRED für einen öffentlichen Client (er meldet sich nie mit einem Secret an); METHOD_VALIDATION_FAILED für ein Ablaufdatum in der Vergangenheit (field = expirationDate) oder die reservierte Beschreibung octo:mirror-own-secret (field = description) |
RemoveSecret (secretValue) | entfernt das Secret; secretValue ist entweder der gespeicherte Wert, wie ihn die Liste der Secrets zeigt, oder das Secret selbst | SECRET_NOT_FOUND, wenn der Client kein solches Secret hat (die Antwort wiederholt den Wert nie) |
- Nur einmal sichtbar. Das Ergebnis von
AddSecretist die einzige Stelle, an der das Secret erscheint. Es ist alssensitivedeklariert: Das Gateway gibt es an den Aufrufer weiter, schreibt es aber nie in ein Log, einen Audit-Eintrag oder einen Trace. Speichern Sie es sofort (zum Beispiel in einem Vault); geht es verloren, legen Sie ein neues Secret an und entfernen das alte. - Wirkung. Ein Client, der für den Client-Credentials-Grant eingerichtet ist, kann mit dem neuen Secret sofort Tokens anfordern
(
AddSecretändert die erlaubten Grant-Typen nicht). NachRemoveSecretschlägt eine Token-Anfrage mit dem entfernten Secret sofort fehl. Andere Secrets des Clients funktionieren weiter, so lässt sich ein Secret ohne Unterbrechung tauschen: neues anlegen, den Aufrufer umstellen, altes entfernen. - Spiegel. Bei einem Client, der in untergeordnete Tenants gespiegelt wird, wird die Änderung nach dem Schreiben in die Spiegel übernommen. Schlägt diese Übernahme fehl, ist der Aufruf trotzdem erfolgreich (die Änderung ist gespeichert); jede Instanz des Identity Service repariert die Spiegel bei ihrer nächsten regelmäßigen Prüfung, standardmäßig innerhalb von 5 Minuten, danach wird ein entferntes Secret auch in den untergeordneten Tenants abgelehnt (Gespiegelte Clients).
- Aufrufer. Der Aufrufer braucht den Scope
octo_apiund die Tenant-RolleTenantManagementoderUserManagement, wie bei REST. Der Identity Service prüft das auf dem validierten Access Token erneut; ohne sie wird der Aufruf mitMETHOD_FORBIDDEN(reason=role-required) abgelehnt, mit derselben Antwort, ob der Client existiert oder nicht. Ein unbekannter Client ergibtMETHOD_TARGET_NOT_FOUND. - Audit. Jeder Aufruf, der den Identity Service erreicht, auch jede Ablehnung dort, schreibt einen Eintrag in das
Ereignisprotokoll des Tenants (Kategorie
Identity.Method) mit dem Aufrufer, dem Ziel (targetRtId) und dem Ergebnis; sobald der Client gefunden wurde zusätzlichclientId, nach einem SchreibvorgangsecretCountund beiRemoveSecretremovedCount. Einen Aufruf, den das Gateway schon vor der Weiterleitung ablehnt, protokolliert das Gateway (Method.Invocation), nicht dieser Eintrag. Secret, Hash und Beschreibung sind nie Teil eines Eintrags.