不记名错误 - invalid_token - 未找到签名密钥

Pat*_*ick 16 c# jwt azure-active-directory asp.net-core angular

我有一个与 .Net Core 2.2 API 后端接口的 Angular 7 应用程序。这是与 Azure Active Directory 的接口。

在 Angular 7 方面,它正在使用 AAD 正确进行身份验证,并且我在jwt.io上得到了一个有效的 JWT 验证。

在 .Net Core API 方面,我创建了一个简单的测试 API [Authorize]

当我从 Angular 调用此方法时,在添加不记名令牌后,我得到(如 Chrome 调试工具、网络选项卡、“标题”中所示):

WWW-Authenticate: Bearer error="invalid_token", error_description="未找到签名密钥"

使用HTTP/1.1 401 Unauthorized

简单的测试 API 是:

    [Route("Secure")]
    [Authorize]
    public IActionResult Secure() => Ok("Secure works");
Run Code Online (Sandbox Code Playgroud)

Angular 调用代码也很简单:

    let params : any = {
        responseType: 'text',
        headers: new HttpHeaders({
            "Authorization": "Bearer " + token,
            "Content-Type": "application/json"
        })
    }

    this.http
        .get("https://localhost:5001/api/azureauth/secure", params)
        .subscribe(
            data => { },
            error => { console.error(error); }
        );
Run Code Online (Sandbox Code Playgroud)

如果我删除该[Authorize]属性并仅将其称为GET来自 Angular的标准请求,它就可以正常工作

我的 Startup.cs 包含:

        services
            .AddAuthentication(AzureADDefaults.AuthenticationScheme)
            .AddAzureADBearer(options => this.Configuration.Bind("AzureAd", options));
Run Code Online (Sandbox Code Playgroud)

这些选项都在 appsettings.json 中正确设置(例如 ClientId、TenantId 等),options这里按预期填充。

4e *_* 6b 7

我有一个独特的场景,希望这会对某人有所帮助。

我正在构建一个启用了 Windows Negotiate 身份验证的 API(.NET Core 5.0,从 IIS 运行),并使用CustomWebApplicationFactory请参阅 CustomWebApplicationFactory 的文档)通过不支持 Negotiate 身份验证的 XUnit 对 API 进行单元测试。

出于单元测试的目的,我告诉CustomWebApplicationFactory使用“UnitTest”环境(ASPNETCORE_ENVIRONMENT变量)并将专门编码的逻辑放入我的应用程序 Startup.cs 文件中,以便仅为“UnitTest”环境添加 JWT 身份验证。

我遇到此错误是因为我的 Startup.cs 配置没有用于创建令牌的签名密钥(IssuerSigningKey如下)。

if (_env.IsEnvironment("UnitTest"))
{
  // for unit testing, use a mocked up JWT auth, so claims can be overridden
  // for testing specific authentication scenarios
  services.AddAuthentication()
    .AddJwtBearer("UnitTestAuth", opt =>
    {
      opt.Audience = "api://local-unit-test";
      opt.RequireHttpsMetadata = false;
      opt.TokenValidationParameters = new TokenValidationParameters()
      {
        ClockSkew = TokenValidationParameters.DefaultClockSkew,
        ValidateAudience = true,
        ValidateIssuer = true,
        ValidateIssuerSigningKey = true,
        ValidAudience = "api://local-unit-test",
        ValidIssuer = "unit-test",
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("abcdefghijklmnopqrstuvwxyz123456"))
      };
    });
} else {
  // Negotiate configuration here...
}
Run Code Online (Sandbox Code Playgroud)

无论是ValidateIssuerSigningKeyor truefalse我仍然收到“invalid_token”401响应,与OP相同。我什至尝试指定一个自定义IssuerSigningKeyValidator委托来始终覆盖结果,但也没有运气。

WWW-Authenticate:承载错误=“invalid_token”,error_description=“未找到签名密钥”

当我添加IssuerSigningKeyTokenValidationParameters对象时(当然与我在单元测试中生成令牌时使用的密钥相匹配),一切都按预期工作。


Muh*_*aaz 6

我面临着同样的问题。我错过了权限..确保权限和api名称正确,现在启动文件中配置服务中的这段代码对我有用:

services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
                .AddIdentityServerAuthentication( x =>
                {
                    x.Authority = "http://localhost:5000"; //idp address
                    x.RequireHttpsMetadata = false;
                    x.ApiName = "api2"; //api name
                });
Run Code Online (Sandbox Code Playgroud)


Mar*_*arc 0

我的核心 API 使用不同的服务配置(并且它有效:)):

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
  .AddJwtBearer(options =>
  {
    Configuration.Bind("JwtBearer", options);
  }
Run Code Online (Sandbox Code Playgroud)

您确定要传递访问令牌而不是 id_token?令牌中存在的声明是否与您的 API 配置的clientidaud完全相同?您可能需要在选项中添加一些事件,以查看您收到的内容以及验证失败的位置。