You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OIDC+Identity Server 4环境下AuthenticateAsync的Scheme参数取值疑问

OIDC结合IdentityServer4对接Okta认证的Scheme疑问

我在用OIDC结合IdentityServer4对接Okta做认证,回调方法里调用了var result = await HttpContext.AuthenticateAsync("Identity.External");。一开始选Identity.External当Scheme是因为回调请求里的Cookie叫这个名,但后来在Startup.ConfigureServices()里改了Cookie名称后,这个调用还是正常工作,说明Scheme名称和Cookie名没关系。

由此产生几个疑问:

  • 怎么确定AuthenticateAsync()里该传的Scheme字符串值?有没有可接受的取值列表?
  • 传错Scheme时返回的已注册Scheme列表(比如Identity.Application、Identity.External这些)是不是都是默认注册的?有没有相关文档说明?
  • 调试发现DefaultAuthenticateScheme默认值是Identity.Application,但AuthenticateAsync必须传DefaultSignInScheme对应的Identity.External才有效,这和微软文档描述不符,原因是什么?
  • Duende的示例里用IdentityServerConstants.ExternalCookieAuthenticationScheme作为SignInScheme和AuthenticateAsync的参数,同样和微软文档冲突,该怎么理解?

我的Startup.ConfigureServices()代码如下:

services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; // "Cookies"
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
    options.DefaultSignOutScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
.AddOpenIdConnect("oidc", "OpenIdConnect", options =>
{
    options.Authority = "oktaUrlHere";
    options.ClientId = "clientIdHere";
    options.ClientSecret = "clientSecretHere";
    options.SaveTokens = true;
    options.ResponseType = "code";
    options.Scope.Add("groups");
    options.Scope.Add("email");
    options.Events = new CustomOpenIdConnectEvents
    {
        ...
    };
});

问题解答

1. 确定AuthenticateAsync()的Scheme值

Scheme值是你在注册认证服务时自定义指定的名称,或者框架提供的默认常量:

  • 如果你用AddCookie("MyCustomCookie"),那Scheme就是"MyCustomCookie";
  • 框架自带的常量比如CookieAuthenticationDefaults.AuthenticationScheme(对应"Cookies")、OpenIdConnectDefaults.AuthenticationScheme(对应"OpenIdConnect"),还有IdentityServer4里的IdentityServerConstants.ExternalCookieAuthenticationScheme(对应"Identity.External");
  • 没有固定的可接受值列表,所有你通过AddXXX系列方法注册的Scheme都可以用,比如你代码里的"oidc"也是一个合法的Scheme。

2. 默认注册的Scheme列表

那些默认的Scheme(Identity.Application、Identity.External等)是ASP.NET Core Identity默认注册的,当你调用AddIdentity或AddDefaultIdentity时,框架会自动注册这几个Cookie Scheme:

  • Identity.Application:存储本地用户的认证会话;
  • Identity.External:存储第三方登录后的临时认证信息;
  • Identity.TwoFactorRememberMe、Identity.TwoFactorUserId:用于双因素认证相关场景;
  • 这些默认注册逻辑在ASP.NET Core Identity的源码里有体现,官方文档会在Identity的认证配置章节提及。

3. DefaultAuthenticateScheme和Identity.External的矛盾点

你遇到的情况是因为第三方登录的流程特殊性:

  • 当你通过Okta这类第三方身份提供商登录时,OIDC中间件会先把第三方返回的用户信息存在Identity.External对应的Cookie里(这是IdentityServer4/ASP.NET Core Identity处理外部登录的默认行为);
  • 回调方法里需要先从这个临时Cookie里获取用户信息,再转换为本地的Identity.Application会话;
  • 微软文档里说的DefaultAuthenticateScheme是用于常规请求的默认认证Scheme,而外部登录回调是特殊场景,需要指定存储临时外部用户信息的Scheme,所以必须传Identity.External才能拿到正确的认证结果。

4. Duende示例中IdentityServerConstants.ExternalCookieAuthenticationScheme的使用

IdentityServerConstants.ExternalCookieAuthenticationScheme其实就是"Identity.External"的常量别名,和你之前用的字符串是同一个东西:

  • Duende作为IdentityServer4的后续版本,沿用了这套Scheme命名规则;
  • 之所以看起来和微软文档冲突,是因为微软文档讲的是通用ASP.NET Core认证,而IdentityServer/Duende在外部登录流程上有自己的约定:用专门的外部Cookie存储第三方登录的临时信息,所以回调时必须指定这个Scheme;
  • 本质上和ASP.NET Core Identity的外部登录逻辑一致,只是用了框架提供的常量来代替硬编码字符串,更规范。

内容的提问来源于stack exchange,提问作者David Klempfner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 12:50:32