A6tm.Core6.Sso 1.0.0
A6tm.Core6.Sso
SSO multi-tenant OpenID Connect générique pour les applications bâties sur le socle 6tm. Provider-agnostique : Azure Entra ID, Keycloak, Google… ne sont que des configurations — aucune dépendance verrouillée à un fournisseur.
En bref
- Flux Authorization Code + PKCE (S256), validation anti-CSRF du
state. - Multi-tenant : résolution par
AppTenantIdexplicite → host (exact /*.domaine/ sous-domaine) → tenant par défaut. - Raccourci Azure Entra ID (converti automatiquement en OpenID Connect).
- Découverte automatique via
.well-known/openid-configuration. - Un seul point d'extension applicatif :
ISsoUserAuth. - Cible net8.0 / net9.0 / net10.0.
- Dépendances :
A6tm.Core6.Abstractions(attributs partagés du socle — installée automatiquement).
Installation
dotnet add package A6tm.Core6.Sso
Démarrage rapide
// 1. Implémenter ISsoUserAuth (logique métier : utilisateur + session + redirection)
public class AppUserSsoAuth : ISsoUserAuth
{
public Task<SsoLoginResult> HandleSsoLoginAsync(SsoUserInfoDto info)
=> Task.FromResult(SsoLoginResult.Redirect($"/auto-connect/{/* token applicatif */}"));
}
// 2. Câbler (Program.cs) — fournir un SsoSettings dont ClientSecret est DÉJÀ déchiffré (cf. Instruction §6)
var ssoSettings = builder.Configuration.GetSection("Sso").Get<SsoSettings>() ?? new SsoSettings();
// … déchiffrer ssoSettings.Tenants[].(AzureEntraId|OpenIdConnect).ClientSecret — voir Instruction §6 …
builder.Services.AddScoped<AppUserSsoAuth>();
builder.Services.AddSsoServices(ssoSettings, sp => sp.GetRequiredService<AppUserSsoAuth>());
builder.Services.AddControllers().AddSsoControllers();
// 3. appsettings.json
"Sso": {
"Enabled": true,
"DefaultAppTenantId": "mon-tenant",
"Tenants": [{
"AppTenantId": "mon-tenant",
"DisplayName": "Connexion SSO",
"Enabled": true,
"Hosts": [ "localhost:3000" ],
"AzureEntraId": { "TenantId": "…", "ClientId": "…", "ClientSecret": "cipher-…", "AdditionalScopes": [ "User.Read" ] }
}]
}
Important
- Le package ne déchiffre pas le
ClientSecret(la config est portée par TONappSettings). Deux cas, détaillés dans A6tm.Core6.Sso.Instruction.md §6 : (1) app qui chiffre → leSsoSettingsdu package porte déjà[Encrypted](deA6tm.Core6.Abstractions) : imbrique-le dans tonAppSettingset tonConfigureAndDecryptle déchiffre en cascade, puisAddSsoServices(SsoSettings, …)— plus de DTO miroir ; (2) app sans chiffrement → injection directe (AddSsoServices(ssoUserAuth, IConfiguration)). ⚠️ Ne lie pas une config chiffrée viaIConfiguration: elle n'est pas déchiffrée. - SSO « server-centric » : pas de MSAL côté SPA, la redirection se fait via
GET /sso/signin/{appTenantId}. - Dev local avec SSO : la SPA et l'API étant sur des ports
localhostdistincts, un reverse-proxy de dev (origine HTTPS commune + en-têteForwarded, lu automatiquement par le package) est nécessaire pour que le flux OIDC fonctionne. Guide +web.configd'exemple fournis dans le template (docs/reverse-proxy/). En production, aucun proxy requis (API servie en sous-site de la SPA).
Documentation
Embarquée dans le .nupkg (dossier docs/ du package, présent dans le cache NuGet après restore) :
- A6tm.Core6.Sso.Instruction.md — guide d'intégration détaillé (pas à pas, pièges, contrat front, flux complet).
- docs/AZURE_ENTRA_ID.md — guide de configuration Azure Entra ID (app registration, redirect URIs, secret, scopes).
- CHANGELOG.md — versions et changements (dont breaking changes). (dans le package :
docs/CHANGELOG.md)
Dans le dépôt uniquement (git.6tm.eu/6tm/a6tm.core.6) :
- docs/ARCHITECTURE.md — architecture interne (résolution de tenant, fabrique de providers, flux OIDC + PKCE/state).
- docs/COMPARISON-microsoft-identity-web.md — rationale de conception : SSO server-centric custom vs Microsoft.Identity.Web.
Endpoints exposés
| Endpoint | Rôle |
|---|---|
GET /sso/config/{appTenantId?} |
Config SSO du tenant (+ URL d'auth si AutoRedirect) |
GET /sso/tenants |
Liste des tenants disponibles |
GET /sso/signin/{appTenantId?} |
Démarre l'authentification (redirection) |
GET /sso/oidc/callback/{appTenantId?} |
Callback OIDC (échange code → session) |
POST /sso/logout/{appTenantId} |
URL de déconnexion |
GET /sso/metadata/{appTenantId} |
Métadonnées Service Provider |
GET /sso/{appTenantId?}/.well-known/openid-configuration |
Document de découverte |
Licence
Package interne 6tm.
No packages depend on A6tm.Core6.Sso.
1.0.0 — Première version stable (regroupe les jalons 0.3.1/0.3.2 non publiés). Packaging et dépendances
uniquement : A6tm.Core6.Abstractions référencé en PackageReference versionnée 1.0.0 (restore depuis le
feed — publier Abstractions avant Sso), icône et métadonnées d'identité du package (Authors, Tags,
ProjectUrl…), publication CI basculée sur le feed NuGet V3, README embarqué complété (Installation,
dépendances, licence). Aucun changement de code ni de comportement runtime.
0.3.0 — Documentation embarquée corrigée/complétée : déchiffrement direct du SsoSettings via [Encrypted]
(fin du « DTO miroir »), nouvelle section « Contrat SPA (types TS) » pour les projets hors socle,
note de génération TS conditionnelle, guide Azure Entra ID embarqué (docs/) et section « Modes de
déploiement ». Aucun changement de code ni de comportement.
0.2.0 — Référence A6tm.Core6.Abstractions : DTO front (SsoTenantConfigDto, ESsoType) exposés à la
génération TypeScript des apps, et ClientSecret annoté [Encrypted] (déchiffrement par l'app hôte).
0.1.0 — Version initiale : SSO OpenID Connect multi-tenant, multi-tenant, PKCE, ISsoUserAuth.
Détail complet dans le CHANGELOG.md (inclus dans docs/).
.NET 10.0
- A6tm.Core6.Abstractions (>= 1.0.0)
.NET 8.0
- A6tm.Core6.Abstractions (>= 1.0.0)
.NET 9.0
- A6tm.Core6.Abstractions (>= 1.0.0)