C# OpenID Connect实现方法 C#如何集成IdentityServer进行身份认证

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

IdentityServer 6 是当前主流选择,.NET 6+ 应优先用它替代已废弃的 IdentityServer4

IdentityServer4 自 2022 年底已停止维护,

IdentityServer6
是官方推荐的继任者,基于 ASP.NET Core 6+ 原生构建,不再依赖 OWIN。如果你项目还在用
IdentityServer4
,升级不是可选项——是安全必需项。

关键区别在于:

IdentityServer6
使用
AddIdentityServer()
+
UseIdentityServer()
注册中间件,配置全在
Program.cs
中完成
不再需要
IdentityServerOptions
的复杂嵌套配置,而是通过
ConfigureServices
中的强类型 builder(如
services.AddIdentityServer().AddInMemoryClients(...)
)分层设置
默认启用 PKCE,且强制要求
redirect_uri
必须显式注册,否则会返回
invalid_request

客户端(MVC/Web API)用 Microsoft.Identity.Web 实现 OIDC 认证最省事

.NET 5+ 官方推荐用

Microsoft.Identity.Web
包替代手写
AddOpenIdConnect
,它自动处理 token 刷新、作用域协商、跨平台重定向等细节。

典型配置(以 ASP.NET Core MVC 为例):

builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration, "AzureAd")
    .EnableTokenAcquisitionToCallDownstreamApi(new string[] { "api://your-api-scope" })
    .AddInMemoryTokenCaches();

注意几个易错点:

"AzureAd"
appsettings.json
中配置节名,不是硬编码字符串;节内必须包含
Instance
Domain
ClientId
ClientSecret
(或证书)、
CallbackPath
若对接自建
IdentityServer6
,把
Instance
换成你的地址(如
https://localhost:5001
),
ClientId
必须与 IdentityServer 中
Client
ClientId
完全一致
CallbackPath
默认是
/signin-oidc
,IdentityServer 的
RedirectUris
列表里必须包含完整 URL(如
https://localhost:7001/signin-oidc
),少一个斜杠都会报
unauthorized_client

IdentityServer6 中 Client 配置必须显式声明 AllowedGrantTypes 和 RedirectUris

常见错误是只配了

ClientId
ClientName
,结果登录后跳回客户端时报
invalid_redirect_uri
unsupported_grant_type
。这是因为 IdentityServer6 默认拒绝所有未明确定义的行为。

最小可行的

Client
配置示例(内存模式):

new Client
{
    ClientId = "mvc-client",
    ClientName = "MVC Client",
    AllowedGrantTypes = GrantTypes.Code, // 必须指定,不能留空
    ClientSecrets = { new Secret("secret".Sha256()) },
    RedirectUris = { "https://localhost:7001/signin-oidc" },
    PostLogoutRedirectUris = { "https://localhost:7001/signout-callback-oidc" },
    AllowedScopes = { "openid", "profile", "api1" }
}

特别注意:

GrantTypes.Code
对应 Authorization Code Flow(含 PKCE),这是 Web 应用唯一推荐方式;
GrantTypes.Hybrid
已不推荐,
GrantTypes.Implicit
在 IdentityServer6 中默认禁用
AllowedScopes
必须包含
openid
,否则 OpenID Connect 协议不成立;若要获取用户信息,还得加
profile
如果客户端是 Blazor WASM,
RedirectUris
要写成
https://localhost:7001/authentication/login-callback
,且需额外配置
RequirePkce = true

调试 OIDC 流程时,先看 /connect/authorize 返回的 HTML 是否含 error 参数

OIDC 登录失败往往卡在重定向链第一环:

/connect/authorize
。直接访问这个地址(带原始请求参数),浏览器会返回带错误提示的 HTML 页面,比如:

error=unauthorized_client&error_description=Invalid+client_id+or+redirect_uri

比抓包或查日志更快定位问题。常见触发条件:

客户端发来的
client_id
在 IdentityServer 的 Clients 列表中不存在
redirect_uri
不在该 Client 的
RedirectUris
集合中(注意协议、端口、路径、末尾斜杠都要完全匹配)
请求中带了
scope=offline_access
,但 Client 未配置
AllowOfflineAccess = true
用了
response_type=code id_token
(Hybrid Flow),但 Client 的
AllowedGrantTypes
没包含
GrantTypes.Hybrid

真正难排查的是 HTTPS 与开发环境混合时的证书问题:本地用

https://localhost:5001
但没信任开发证书,导致 HttpClient 内部调用失败,错误却静默吞掉。这时候得在 IdentityServer 的
Startup
中临时启用
options.RequireHttpsMetadata = false
(仅限开发)。

相关推荐