【问题标题】:Got JWT Token from Azure AD B2C but getting 401 error in ASP.NET Core app从 Azure AD B2C 获得 JWT 令牌,但在 ASP.NET Core 应用程序中出现 401 错误
【发布时间】:2018-10-25 18:38:42
【问题描述】:

我正在一个新的 ASP.NET Core 2.1 应用中实施 Azure AD B2C。

我已经创建了 Azure AD B2C 租户并注册了我的应用等。

登录后,我被重定向到我指定的 URL,我在 URL 中看到了令牌,但我收到一条错误消息,指出应用程序需要身份验证 - 见下文:

我看到了一些类似的帖子,我收集到的是令牌由中间件自动验证。不是这样吗?

此时我需要做什么?

我的应用中包含的代码如下:

ConfigureServices()方法中:

services.AddAuthentication(options => {
   options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(jwtOptions => {
   jwtOptions.Authority = $"https://login.microsoftonline.com/tfp/{Configuration["AzureAdB2C:Tenant"]}/{Configuration["AzureAdB2C:Policy"]}/v2.0/";
   jwtOptions.Audience = Configuration["AzureAdB2C:ClientId"];
   jwtOptions.Events = new JwtBearerEvents
   {
       OnAuthenticationFailed = AuthenticationFailed
   };
});

Startup.csConfigure() 方法中,我只有app.UseAuthentication();

在我的控制器中,我还使用[Authorize] 来确保我的操作不对匿名用户开放。

我错过了什么?如何验证令牌并获取声明?

【问题讨论】:

  • 在我写答案之前要问您一个问题:您的应用是 API 还是带有用户交互界面的应用?因为您将 JWT Bearer 身份验证(用于 API)与交互式身份验证返回的 id 令牌(由交互式应用程序使用)混合在一起。
  • 这是一个带有 ASP.NET Core API 后端的 ReactJs SPA 应用程序,因此只有一个页面可以下载所有前端的 JS 文件。剩下的就是 API。我只想使用 JWT 身份验证——即使是索引页面——以保持简单。
  • 好吧,这是另一种常见的模式。 JWT 身份验证中间件不会读取片段中的 id 令牌。您将不得不使用 MSAL.JS(或其他支持的 OIDC 库)在客户端对用户进行身份验证,然后将 id 令牌作为访问令牌附加到每个请求的标头中。
  • 那我的索引页面呢?这是我的前端应用程序的入口点,我想确保只将它提供给经过身份验证的用户。
  • 目前还不能直接使用。我想您可以以某种方式制作一些东西来验证片段中的 id 令牌,但通常应用程序的静态文件不被认为是有价值的。

标签: asp.net asp.net-core jwt azure-ad-b2c


【解决方案1】:

结合我们在这里的讨论作为答案。

此类应用的典型做法是允许未经身份验证的客户端下载 HTML、JS 和其他静态内容。

然后前端可以使用 MSAL.JS 对用户进行身份验证。 前端 SPA 将获得一个 Id 令牌,它告诉前端用户是谁。 MSAL.JS 还允许您获取访问令牌以调用 API。 它使用隐藏的 iframe + 隐式授权流程来执行此操作。 然后需要将该访问令牌作为标头 (Authorization: Bearer token-goes-here) 附加到对 API 的请求。

MSAL.JS 将使用会话或本地存储来存储令牌(这是可配置的)。 因此,此设置中不使用任何 cookie。

然后后端 API 应该验证它在标头中收到的访问令牌。 您所拥有的已经足以验证令牌。

services.AddAuthentication(options => {
   options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(jwtOptions => {
   jwtOptions.Authority = $"https://login.microsoftonline.com/tfp/{Configuration["AzureAdB2C:Tenant"]}/{Configuration["AzureAdB2C:Policy"]}/v2.0/";
   jwtOptions.Audience = Configuration["AzureAdB2C:ClientId"];
   jwtOptions.Events = new JwtBearerEvents
   {
       OnAuthenticationFailed = AuthenticationFailed
   };
});

JWT Bearer 身份验证处理程序将在启动时从此处配置的权限加载 OpenId Connect 元数据文档。 这允许它获取 B2C 租户的公共签名密钥等。 此信息允许处理程序在访问令牌进入时验证访问令牌,而无需以任何方式与 B2C 交互。 它检查签名是否有效、颁发者是否有效以及令牌中的受众是否已配置。

授权当然不是由身份验证处理程序处理的,因此您还必须检查调用用户实际上是否被允许访问他们正在访问的资源。 用户 ID 在访问令牌中可用。

MSAL.JS 可能也对令牌进行了一些验证(我现在不记得是否做过),但是在前端进行验证是任何人都可以控制的事情用户的浏览器。 API 端的验证是最重要的部分。

【讨论】:

  • 一直遇到问题,所以我使用 VS 2017 中的内置模板创建了一个带有 React 前端的全新 ASP.NET Core 2.1 应用程序,但我仍然收到 401 错误。删除了我现有应用程序的所有复杂性,以确保没有其他问题导致问题。在这里发布了一个包含所有必要代码的新问题:stackoverflow.com/questions/50418406/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-02-01
  • 1970-01-01
  • 2020-11-16
  • 2018-07-21
  • 1970-01-01
  • 2017-05-17
  • 2018-10-22
相关资源
最近更新 更多