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

使用Microsoft.Identity.Web的Azure B2C授权码流未返回Access/Refresh Token

问题描述

我正尝试将IdentityServer4应用的认证/授权迁移至Azure B2C,但遇到了以下问题:

  • 按照官方指引拦截OnTicketReceived事件以扩展业务域声明,已将ResponseType设置为授权码流的"code id_token",但该设置被忽略,响应仅返回id_token。
  • 查看发送至AAD B2C的OIDC消息,发现scope为"openid profile offline_access",ResponseType为"code",而非我指定的"code id_token"。
  • 从示例来看需在控制器方法中通过注入的ITokenAcquisition API请求access token,我可以重构代码实现这一点,但疑惑为何在Startup类中指定的授权码流完全不生效,是否误解了Microsoft.Identity.Web的工作机制?
原因分析与解决方案

1. Microsoft.Identity.Web的默认行为

Microsoft.Identity.Web针对Web应用场景做了封装,默认会覆盖手动设置的ResponseType:

  • 当仅配置Web应用身份验证(未关联API访问)时,框架默认使用授权码流(ResponseType="code"),且只会获取ID Token用于用户认证,不会自动请求Access Token。
  • 你设置的"code id_token"属于混合流,但Microsoft.Identity.Web在纯Web应用场景下不推荐这种模式,框架内部会自动调整为符合最佳实践的授权码流配置。

2. 关于Scope的问题

默认的"openid profile offline_access"是Web应用认证的基础Scope:

  • openid:表明是OIDC认证流程,必须包含;
  • profile:用于获取用户基本信息;
  • offline_access:用于获取刷新令牌,支持持久化登录。
    若需要获取Access Token访问API,必须显式添加对应的API Scope(比如https://yourtenant.onmicrosoft.com/api/access_as_user)。

3. 让授权码流生效并获取Access Token的正确方式

要在Startup中配置自动获取Access Token,需使用Microsoft.Identity.Web的AddWebAppCallsWebApi扩展方法,而非单纯的AddAuthentication+AddOpenIdConnect:

services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAdB2C"))
    .EnableTokenAcquisitionToCallDownstreamApi(new[] { "your-api-scope" })
    .AddInMemoryTokenCaches();

配置后,框架会自动处理授权码流,获取ID Token和Access Token,同时你仍可在OnTicketReceived事件中扩展用户声明:

services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
    options.Events.OnTicketReceived = context =>
    {
        // 扩展业务域声明逻辑
        var claimsIdentity = context.Principal.Identity as ClaimsIdentity;
        claimsIdentity.AddClaim(new Claim("custom-claim", "custom-value"));
        return Task.CompletedTask;
    };
});

4. 若需使用混合流(不推荐)

如果确实有特殊场景需要使用混合流,需覆盖Microsoft.Identity.Web的默认配置,在AddMicrosoftIdentityWebApp后手动设置:

services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
    options.ResponseType = "code id_token";
    // 同时添加对应的API Scope
    options.Scope.Add("your-api-scope");
});

但这种方式不符合框架设计初衷,易引发后续兼容问题,建议优先使用EnableTokenAcquisitionToCallDownstreamApi的标准方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 13:15:24