c# 如何实现单点登录 sso

来源:这里教程网 时间:2026-02-21 17:40:09 作者:

什么是 SSO,C# 里不直接“实现”而是“接入”

SSO(单点登录)不是某个 C# 类库能一键开启的功能,而是一套跨系统认证协议的协作机制。你在 C# 应用中要做的,是作为 服务提供方(SP) 接入已有的身份提供方(IdP),比如 Azure AD、Okta、Auth0、或自建的 IdentityServer。硬写一套符合 SAML/OIDC 规范的 IdP 在生产环境极不推荐——协议细节多、安全要求高、密钥轮换、签名验证、时钟偏移处理等极易出错。

ASP.NET Core 中最常用的是 OIDC + Microsoft.Identity.Web

现代 C# Web 应用(.NET 6+)基本都走 OpenID Connect(OIDC)路线,配合

Microsoft.Identity.Web
包可快速接入 Azure AD 或其他兼容 OIDC 的 IdP。它封装了 token 获取、验证、用户上下文注入等逻辑,避免手写
OpenIdConnectEvents
处理 redirect_uri、nonce、state 等易错环节。

安装 NuGet 包:
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?用 IdentityServer6(非 .NET 自带)

如果必须自建 IdP(例如统一管理多个内部系统),不要用已停止维护的 IdentityServer4,改用

IdentityServer6
(基于 .NET 6+,开源且持续更新)。它本身是独立服务,C# 客户端只需按 OIDC 标准接入——也就是说,你的业务系统仍是 SP,只是 IdP 换成了你自己的实例。

IdentityServer6 需单独部署(可托管在 Kestrel/IIS/Docker),暴露
/.well-known/openid-configuration
端点
客户端应用仍用
Microsoft.Identity.Web
,但
Instance
改为你的 IdP 地址,
TenantId
改为
common
或具体租户 ID
关键区别:你需要手动在 IdP 侧注册每个客户端(即你的 C# 应用),配置
ClientId
RedirectUris
PostLogoutRedirectUris
、是否启用 PKCE 等
切勿在 IdP 中硬编码用户密码——应对接现有目录(如 LDAP、SQL Server 用户表)或通过
IProfileService
扩展用户声明

常见坑:Cookie 同站策略、HTTPS 强制、时钟偏差

本地开发时最常卡在三类问题,和代码逻辑无关,纯属部署/配置层面:

SameSite=None
+
Secure=true
:Chrome/Firefox 要求跨站 Cookie 必须同时设这两个属性,否则登录后跳回应用时
HttpContext.User
为空。ASP.NET Core 6+ 默认已适配,但若降级或自定义 Cookie 策略需检查
所有回调地址(
RedirectUri
)必须用 HTTPS(生产环境),即使本地用
https://localhost:5001
;HTTP 会被 IdP 拒绝
服务器时间与 NTP 时间偏差超过 5 分钟会导致 JWT 签名验证失败(
exp
/
nbf
检查),错误信息类似:
System.IdentityModel.Tokens.Jwt.SecurityTokenInvalidLifetimeException
IdP 返回的
id_token
若含中文或特殊字符,某些老版本
System.Text.Json
会解析失败,建议显式指定
JsonSerializerOptions.Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping

真正难的从来不是“怎么写那几行代码”,而是理解谁发 token、谁验 token、谁存 session、谁管登出通知——这些角色划分错了,后面所有配置都会指向奇怪的 401 或循环重定向。

相关推荐