Anmeldung wahlweise ueber OpenID Connect (Authentik)
Neben dem Passwort-Login gibt es jetzt einen zweiten, gleichberechtigten Weg: OpenID Connect gegen einen selbst gehosteten Anmeldedienst. Ohne Konfiguration aendert sich nichts - keine SSO-Knoepfe, Passwort-Login wie bisher. Der Anmeldedienst ist NUR fuer die Anmeldung zustaendig. Danach stellt Vorrania sein eigenes Token aus wie beim Passwort-Login, deshalb bleiben deps.py, die Rollenpruefung und die langlebigen API-Tokens unveraendert. Backend - Anbieter kommen aus der Umgebung (OIDC_PROVIDERS + OIDC_<KUERZEL>_*). Ein zweiter Anbieter ist damit reine Konfiguration, ohne Codeaenderung. - Browser-Weg (vertraulicher Client) und App-Weg (oeffentlicher Client, PKCE) enden beide im selben Token-Schema. - state/nonce/PKCE-Verifier liegen in einer kurzlebigen Tabelle statt in einem Cookie: Starlettes CORS-Schicht spiegelt bei allow_origins=["*"] zusammen mit allow_credentials die Herkunft zurueck, sobald ein Request ein Cookie traegt. Ohne Cookie entsteht diese Wechselwirkung erst gar nicht - und der Ablauf bleibt mit der db-Fixture pruefbar. - Zuordnung ueber die sub des Anbieters; die Erstverknuepfung laeuft ueber die BESTAETIGTE E-Mail-Adresse. Rollen kommen nie aus dem Anbieter, und ein gleichlautender preferred_username uebernimmt nie ein bestehendes Konto. - users.password_hash darf jetzt leer sein (reine SSO-Konten). verify_password faengt das ab, sonst antwortete der Login mit 500 statt 401. Verknuepfen bestehender Konten - Neue Seite "Mein Konto" (fuer alle Benutzer, nicht nur Admins): verknuepfen und wieder loesen. Die Berechtigung stammt aus der laufenden Sitzung, es braucht also weder eine hinterlegte Adresse noch Admin-Rechte. - Der Start laeuft ueber POST, weil eine Seitennavigation das Bearer-Token nicht mitschicken kann. - Die letzte Anmeldemoeglichkeit eines Kontos laesst sich nicht loesen. iOS - AppAuth (erste Paketabhaengigkeit) mit PKCE im System-Browser, nie in einem eingebetteten WebView, und ohne Client-Secret. - offline_access nur im App-Weg: der Browser-Weg braucht kein Refresh-Token und bekaeme sonst einen ueberfluessigen Zustimmungsdialog. - Anmeldezustand je Serverprofil im Keychain; abgelaufene Token erneuert die App still im Hintergrund. Gleichzeitige 401er teilen sich eine Erneuerung. Deployment - docker-compose reicht die ganze .env durch. Einzeln aufzuzaehlen ginge nur mit fest verdrahteten Kuerzeln - genau das soll ein weiterer Anbieter nicht erfordern. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
8d4954610b
commit
3d0ff54bf5
@@ -20,6 +20,7 @@
|
||||
4C486D190D1AB338925D29B5 /* HistoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DACFBB69CB536BA7CBBD484 /* HistoryView.swift */; };
|
||||
4F86620DF8303DB02314DB5A /* CheckInView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0365A16FEAE3F2BEC321E68A /* CheckInView.swift */; };
|
||||
56A5DFAC86DF972B1481A691 /* ItemViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69B59B9F69BC30451D45A3C7 /* ItemViews.swift */; };
|
||||
56C15BE80330E00D82AF3BD1 /* OIDCLogin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C5F87AE1C7EA366862DB22E /* OIDCLogin.swift */; };
|
||||
5A0C3254B45CA13B1C3D9265 /* AssignScanView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76393ADA26304E5BC5AD7E7F /* AssignScanView.swift */; };
|
||||
6816C33381DF52A96E5BB303 /* Models.swift in Sources */ = {isa = PBXBuildFile; fileRef = 314B1BB7220691A7423E8929 /* Models.swift */; };
|
||||
728CF5124D2D5BBF826BCD2C /* ServerFetch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1847E65D41ACEDD01CD108BC /* ServerFetch.swift */; };
|
||||
@@ -40,6 +41,7 @@
|
||||
D70CB183C868FF0143A6A5E7 /* DisplaySettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC97A555856C6C5DD353E25 /* DisplaySettings.swift */; };
|
||||
D7717F44D2CDB75DC2693B59 /* ObjectStockView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5BB49FBEFF88768B0BC902 /* ObjectStockView.swift */; };
|
||||
DFA55EF4ACA34537F445E998 /* Session.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD2F9406BD0D4F0D30FED345 /* Session.swift */; };
|
||||
E216EFADBC6D6AC39C0547DF /* AppAuth in Frameworks */ = {isa = PBXBuildFile; productRef = 31DDA98DEF7F8937A8719C80 /* AppAuth */; };
|
||||
E9EA455CACB6ED5951B114C3 /* LoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A75926511854BB8EE316ED3A /* LoginView.swift */; };
|
||||
ED61DAE4824165D6D87F8C1D /* DateScanView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 717C8EB336170526F5F3E695 /* DateScanView.swift */; };
|
||||
F3F718BFC60BF945CFA32BD2 /* AppDashboards.swift in Sources */ = {isa = PBXBuildFile; fileRef = 660ACEFA22BC77D52FBE736A /* AppDashboards.swift */; };
|
||||
@@ -76,6 +78,7 @@
|
||||
939C7B7C2F2F58927ED5F2F1 /* NotificationSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsView.swift; sourceTree = "<group>"; };
|
||||
9948219CDDC4188EA4298F22 /* VorraniaApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VorraniaApp.swift; sourceTree = "<group>"; };
|
||||
99E56353CB483EFB1CCD09D8 /* CheckInFormView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckInFormView.swift; sourceTree = "<group>"; };
|
||||
9C5F87AE1C7EA366862DB22E /* OIDCLogin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OIDCLogin.swift; sourceTree = "<group>"; };
|
||||
A6785CD9174067EFBB2B9043 /* ListViews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListViews.swift; sourceTree = "<group>"; };
|
||||
A75926511854BB8EE316ED3A /* LoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginView.swift; sourceTree = "<group>"; };
|
||||
AA022A27118BEEEC5912ECDC /* BestBeforeText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BestBeforeText.swift; sourceTree = "<group>"; };
|
||||
@@ -90,6 +93,17 @@
|
||||
EA706060734632DE78FA1073 /* ServerListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerListView.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
6ABD1700B66B20DDD542B777 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E216EFADBC6D6AC39C0547DF /* AppAuth in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
5216EA3D3DA41052FD0202A7 /* Sources */ = {
|
||||
isa = PBXGroup;
|
||||
@@ -121,6 +135,7 @@
|
||||
3731608B8D48960DC98912BC /* NotificationSettings.swift */,
|
||||
939C7B7C2F2F58927ED5F2F1 /* NotificationSettingsView.swift */,
|
||||
7B5BB49FBEFF88768B0BC902 /* ObjectStockView.swift */,
|
||||
9C5F87AE1C7EA366862DB22E /* OIDCLogin.swift */,
|
||||
6F574168AA0F849D46C384EE /* ProductDetailView.swift */,
|
||||
5312AFE88B7284401AA7B0A3 /* ProductPhotoView.swift */,
|
||||
369B9841E43E727ACA2E2A2A /* ProductViews.swift */,
|
||||
@@ -162,6 +177,7 @@
|
||||
buildPhases = (
|
||||
08E03A34841D4B2D2C7E2E81 /* Sources */,
|
||||
049B3FB4A4D974E54814E40C /* Resources */,
|
||||
6ABD1700B66B20DDD542B777 /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@@ -169,6 +185,7 @@
|
||||
);
|
||||
name = Vorrania;
|
||||
packageProductDependencies = (
|
||||
31DDA98DEF7F8937A8719C80 /* AppAuth */,
|
||||
);
|
||||
productName = Vorrania;
|
||||
productReference = 4BF4E4F5524B15728CEEE116 /* Vorrania.app */;
|
||||
@@ -198,6 +215,9 @@
|
||||
);
|
||||
mainGroup = 5612AB3DD4CD09397A8F1BAB;
|
||||
minimizedProjectReferenceProxies = 1;
|
||||
packageReferences = (
|
||||
AA6EA5DEB9627D245AB25D7E /* XCRemoteSwiftPackageReference "AppAuth-iOS" */,
|
||||
);
|
||||
preferredProjectObjectVersion = 77;
|
||||
productRefGroup = 9BD53E938DBCB7F0CF657753 /* Products */;
|
||||
projectDirPath = "";
|
||||
@@ -250,6 +270,7 @@
|
||||
38133EE3EC920B462BDAA29F /* NotificationScheduler.swift in Sources */,
|
||||
4B4A74E8A2964FF8F3D2CE02 /* NotificationSettings.swift in Sources */,
|
||||
17032C3F3B89BAD6CB249443 /* NotificationSettingsView.swift in Sources */,
|
||||
56C15BE80330E00D82AF3BD1 /* OIDCLogin.swift in Sources */,
|
||||
D7717F44D2CDB75DC2693B59 /* ObjectStockView.swift in Sources */,
|
||||
AAF27320D2A67C994C29C26F /* ProductDetailView.swift in Sources */,
|
||||
4AC141151264AF22701079B6 /* ProductPhotoView.swift in Sources */,
|
||||
@@ -452,6 +473,25 @@
|
||||
defaultConfigurationName = Debug;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
|
||||
/* Begin XCRemoteSwiftPackageReference section */
|
||||
AA6EA5DEB9627D245AB25D7E /* XCRemoteSwiftPackageReference "AppAuth-iOS" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/openid/AppAuth-iOS";
|
||||
requirement = {
|
||||
kind = upToNextMajorVersion;
|
||||
minimumVersion = 1.7.6;
|
||||
};
|
||||
};
|
||||
/* End XCRemoteSwiftPackageReference section */
|
||||
|
||||
/* Begin XCSwiftPackageProductDependency section */
|
||||
31DDA98DEF7F8937A8719C80 /* AppAuth */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = AA6EA5DEB9627D245AB25D7E /* XCRemoteSwiftPackageReference "AppAuth-iOS" */;
|
||||
productName = AppAuth;
|
||||
};
|
||||
/* End XCSwiftPackageProductDependency section */
|
||||
};
|
||||
rootObject = B35524A6F4D28034E6687EE2 /* Project object */;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user