对于更复杂的SSO场景,我们通常需要利用IdentityServer4的JWT令牌,还需要利用Auth0的JWT令牌来授权对asp.net core 2.0 Web api的访问。

来自Startup.cs ConfigureServices的此代码段尝试为Auth0和IdentityServer4处理注册身份验证处理程序,但显然失败,并显示InvalidOperationException:“方案已存在:Bearer”

        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        })
        .AddJwtBearer(options =>
        {
            options.Audience = Configuration["Auth0:ApiIdentifier"];
            options.Authority = $"https://{Configuration["Auth0:Domain"]}/";
        })
        .AddIdentityServerAuthentication(options =>
        {
            options.Authority = "http://localhost:5000";
            options.RequireHttpsMetadata = false;
            options.ApiName = "api1";
        });


我假设如何基于令牌中的发行者来进行某种类型的单独处理,才能最好地实现?

最佳答案

事实证明,正如上面的Muqeet Khan所暗示的,这些方案的名称必须不同,如下所示。

    services.AddAuthentication()
    .AddJwtBearer("Auth0", options =>
    {
        options.Audience = Configuration["Auth0:ApiIdentifier"];
        options.Authority = $"https://{Configuration["Auth0:Domain"]}/";
    })
    .AddIdentityServerAuthentication("IdSrv", options =>
    {
        options.Authority = "http://localhost:5000";
        options.RequireHttpsMetadata = false;
        options.ApiName = "api1";
    });


但是,默认的[Authorize]属性仅调用默认的AuthenticationScheme。我没有为每个授权都指定两个方案,而是这样在全局范围内注册了它们:

    services.AddMvcCore()
      .AddAuthorization()
      .AddJsonFormatters()
      .AddMvcOptions(options =>
      {
        var policy = new AuthorizationPolicyBuilder("IdSrv", "Auth0")
          .RequireAuthenticatedUser()
          .Build();
        options.Filters.Add(new AuthorizeFilter(policy));
      });

09-26 11:06