【问题标题】:How to get the token returned from Azure AD B2C in ASP Core 2.0?如何在 ASP Core 2.0 中获取从 Azure AD B2C 返回的令牌?
【发布时间】:2018-10-15 04:49:15
【问题描述】:

我使用 Azure B2C 创建了一个带有用户帐户身份验证的默认 .NET Core 2.0 MVC Web 应用程序。我已经能够使用我的 B2C 策略成功登录。

我希望获取用户的访问令牌,该令牌将被转发到另一个 API。 我关注了this post,但在第二步中返回的 access_token 是空事件,尽管 id_token 不是。

我尝试通过添加“令牌”来更改我的 OpenIdConnection 的 ResponseType 选项以获取“id_token 代码令牌”(如 here 所示),但出现错误

消息包含错误:'invalid_request',error_description: 'AADB2C90055:请求中提供的范围'openid profile'必须 指定一个资源,例如“https://example.com/calendar.read”。

只有当 ResponseType 中包含“令牌”时,我才会收到错误消息。

如何解决此错误?我需要设置资源还是更改范围?我要以正确的方式获取 access_token 吗?

更多信息: 我使用 Azure 的用户帐户身份验证创建了一个默认的 .NET Core 应用程序。我一直在修改自动生成的 AzureAdB2cAuthenticationBuilderExtension.cs。

我修改了配置函数:

public void Configure(string name, OpenIdConnectOptions options)
{
    options.ClientId = _azureOptions.ClientId;
    options.Authority = $"{_azureOptions.Instance}/{_azureOptions.Domain}/{_azureOptions.SignUpSignInPolicyId}/v2.0";
    options.UseTokenLifetime = true;
    options.CallbackPath = _azureOptions.CallbackPath;

    // Added 'token' here so I can retrieve the access token
    options.ResponseType = "code id_token token";
    options.TokenValidationParameters = new TokenValidationParameters { NameClaimType = "name" };

    options.Events = new OpenIdConnectEvents
    {
        OnRedirectToIdentityProvider = OnRedirectToIdentityProvider,
        OnRemoteFailure = OnRemoteFailure,

        //Added this so I can store the access_token in the cache
        OnAuthorizationCodeReceived = OnAuthorizationCodeReceived,

    };
}

然后我添加了以下函数,以便我可以存储并稍后从 TokenCache 检索访问令牌

public async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext context)
{
    // Use MSAL to swap the code for an access token
    // Extract the code from the response notification
    var code = context.ProtocolMessage.Code;
    string signedInUserID = context.Principal.FindFirst(ClaimTypes.NameIdentifier).Value;

    TokenCache userTokenCache = new MSALSessionCache(signedInUserID, context.HttpContext).GetMsalCacheInstance();
    ConfidentialClientApplication cca = new ConfidentialClientApplication(_azureOptions.ClientId, _azureOptions.Authority, _azureOptions.RedirectUri, new Microsoft.Identity.Client.ClientCredential(_azureOptions.ClientSecret), userTokenCache, null);
    try
    {
        Microsoft.Identity.Client.AuthenticationResult result = await cca.AcquireTokenByAuthorizationCodeAsync(code, _azureOptions.ApiScopes.Split(' '));
        context.HandleCodeRedemption(result.AccessToken, result.IdToken);
    }
    catch (Exception ex)
    {
        //TODO: Handle
        throw;
    }
}

【问题讨论】:

  • 您没有通过请求中的范围。你能分享一些你是如何提出请求的吗?
  • 您发布的第一个答案应该是正确的。它使用代码授权流程来交换代码以获取令牌。您发布的第二个博客应该是针对 AAD,而不是 AAD B2C,它使用隐式流,其响应类型应该是 id_token token ,不包含 code
  • 我关注了this 的帖子。添加“代码”触发了 OnAuthorizationCodeReceived,其中将令牌添加到缓存中。这可能是错误的做法。

标签: azure-ad-b2c


【解决方案1】:

您正在做的是请求“令牌”(=access_token),但没有定义您想要“令牌”的范围。您需要发布 API 范围,并在 Azure B2C 门户中为调用应用程序授予范围权限。

然后在登录调用应用程序(通常是 UI 应用程序)时,您可以通过定义您感兴趣的范围在登录时请求“令牌”(access_token)。如果您被正确分配了调用权限UI 应用程序通过范围发布的 API 应用程序,您将在“scp”声明中看到匹配的范围。

【讨论】:

  • 即使只有一个单个应用注册(例如本机客户端),也需要这样做。只需添加一个 default 范围,然后将应用权限授予此范围 - 如果需要,请不要忘记授予权限(对于管理员类型的同意)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-21
  • 1970-01-01
  • 2018-09-03
  • 2021-10-26
  • 2021-03-03
  • 2019-10-07
  • 1970-01-01
相关资源
最近更新 更多