我正在使用 IdentityServer4,我正在尝试使用访问令牌访问同一服务器上的其他 API 端点,总是收到 401

I'm using IdentityServer4 and I'm trying to access additional API endpoints on the same server with an Access token, always receiving 401

我将 .net core 2.2 与 IdentityServer 4 一起使用,尝试使用访问令牌访问同一服务器上的其他 API 端点,总是收到 401。

Startup.cs

        services.AddLocalApiAuthentication();
        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
        })
        .AddJwtBearer(options =>
        {
            options.SaveToken = true;
            options.Authority = "https://localhost:5555";
            options.RequireHttpsMetadata = false;
            options.Audience = LocalApi.ScopeName;
        });

        services.AddIdentityServer(options =>
        {
            options.Caching.ClientStoreExpiration = TimeSpan.FromMinutes(10);
            options.Caching.ResourceStoreExpiration = TimeSpan.FromMinutes(10);
            options.Caching.CorsExpiration = TimeSpan.FromMinutes(10);
            options.IssuerUri = "https://localhost:5555";
        });

配置:

        app.UseHttpsRedirection();
        app.UseIdentityServer();
        app.UseAuthentication();
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller}/{action=Index}/{id?}");
        });

端点:

    [HttpGet]
    [Route("v1/info")]
    [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme, Policy = LocalApi.PolicyName)]
    public async Task<ActionResult> GetAccountInfo()

结果:

  info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[1]
     Authorization was successful.
  info: Microsoft.AspNetCore.Mvc.StatusCodeResult[1]
     Executing HttpStatusCodeResult, setting HTTP status code 401

更新

API 从 IdentityServer 请求访问令牌以访问 IdentityServer 自定义端点 API。 尝试访问身份验证的 IdentityServer 端点 api 时 这个收到的访问令牌,我收到 401

查看源代码后,似乎 AddLocalApiAuthentication 方法利用了自己的身份验证方案,正如我们所见 here and here.

因此,如果我们想保留默认身份验证方案 IdentityServerAuthenticationDefaults.AuthenticationScheme,只需保留启动配置并将操作端点更改为 [Authorize(AuthenticationSchemes = IdentityServerConstants.LocalApi.AuthenticationScheme, Policy = IdentityServerConstants.LocalApi.ScopeName)]

但我只是好奇...如果我是对的,这个配置在我们的身份提供者服务上,那么为什么它应该接受来自其他身份提供者的 Jwt 令牌,因为我们像这样配置它

services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
        })
        .AddJwtBearer(options =>
        {
            options.SaveToken = true;
            options.Authority = "https://localhost:5555"; // Other Identity provider here
            options.RequireHttpsMetadata = false;
            options.Audience = LocalApi.ScopeName;
        });

这有什么特殊原因吗?因为 AFAIK,AddLocalApiAuthentication 的创建包含身份提供者以接受它自己的凭据,而不是来自其他人的凭据。

更新

我只是看看你的link...可能会替换API 1因为客户端可能更合适。

只需像这样更改配置即可

// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    // Some registers...
    services.AddLocalApiAuthentication();
    // No need for services.AddAuthentication(...).AddJwtBearer(...);
    services.AddIdentityServer(); // This one take care of all the AddAuthentication stuff.
    // Some registers...
}

public void Configure(IApplicationBuilder app)
{
    // Some registers...
    app.UseAuthentication();
    // Some registers...
}

// Controller
[HttpGet]
[Route("v1/info")]
[Authorize] // This should be enough, and in case it's still 401, try beblow
//[Authorize(AuthenticationSchemes = IdentityServerConstants.LocalApi.AuthenticationScheme, Policy = IdentityServerConstants.LocalApi.ScopeName)]
public async Task<ActionResult> GetAccountInfo()

确保附加令牌 Authorization header 格式为 Bearer eyskeu...。这适用于 .net 3.1,我暂时没有 2.x 版本