SSO(单点登录)是跨系统认证协议协作机制,C#应用作为SP接入IdP(如Azure AD、IdentityServer6),而非自行实现;.NET 6+推荐OIDC+Microsoft.Identity.Web,需正确配置Cookie策略、HTTPS及时间同步。
SSO(单点登录)不是某个 C# 类库能一键开启的功能,而是一套跨系统认证协议的协作机制。你在 C# 应用中要做的,是作为 服务提供方(SP) 接入已有的身份提供方(IdP),比如 Azure AD、Okta、Auth0、或自建的 IdentityServer。硬写一套符合 SAML/OIDC 规范的 IdP 在生产环境极不推荐——协议细节多、安全要求高、密钥轮换、签名验证、时钟偏移处理等极易出错。
现代 C# Web 应用(.NET 6+)基本都走 OpenID Connect(OIDC)路线,配合 Microsoft.Identity.Web 包可快速接入 Azure AD 或其他兼容 OIDC 的 IdP。它封装了 token 获取、验证、用户上下文注入等逻辑,避免手写 OpenIdConnectEvents 处理 redirect_uri、nonce、state 等易错环节。
Microsoft.Identity.Web 和 Microsoft.Identity.Web.UI
Program.cs 中注册服务:
builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration, "AzureAd");
appsettings.json 中的 AzureAd 节点,至少包含:ClientId、ClientSecret(或证书)、Instance(如 https://login.microsoftonline.com/)、TenantId
[Authorize] 即可触发自动重定向到 IdP 登录页如果必须自建 IdP(例如统一管理多个内部系统),不要用已停止维护的 IdentityServer4,改用 IdentityServer6(基于 .NET 6+,开源且持续更新)。它本身是独立服务,C# 客户端只需按 OIDC 标准接入——也就是说,你的业务系统仍是 SP,只是 IdP 换成了你自己的实例。
/.well-known/openid-configuration 端点Microsoft.Identity.Web,但 Instance 改为你的 IdP 地址,TenantId 改为 common 或具体租户 IDClientId、RedirectUris、PostLogoutRedirectUris、是否启用 PKCE 等IProfileService 扩展用户声明本地开发时最常卡在三类问题,和代码逻辑无关,纯属部署/配置层面:
SameSite=None + Secure=true:Chrome/Firefox 要求跨站 Cookie 必须同时设这两个属性,否则登录后跳回应用时 HttpContext.User 为空。ASP.NET Core 6+ 默认已适配,但若降级或自定义 Cookie 策略需检查RedirectUri)必须用 HTTPS(生产环境),即使本地用 https://localhost:5001;HTTP 会被 IdP 拒绝exp/nbf 检查),错误信息类似:System.IdentityModel.Tokens.Jwt.SecurityTokenInvalidLifetimeException
id_token 若含中文或特殊字符,某些老版本 System.Text.Json 会解析失败,建议显式指定 JsonSerializerOptions.Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
真正难的从来不是“怎么写那几行代码”,而是理解谁发 token、谁验 token、谁存 session、谁管登出通知——这些角色划分错了,后面所有配置都会指向奇怪的 401 或循环重定向。