首页 > 解决方案 > 请求标头中可能有多个 AuthenticationSchemes?

问题描述

我有两个 webapis A 和 B。我从 A 向 B 发出请求。A 包含来自 identityserver4 的用户信息,我只需要将令牌传递给请求标头。除了身份服务器令牌之外,A 还使用我注册 B 的 AAD(Azure Active Directory)。因此,我还从 A 中检查了我的 AAD,以便我可以从 Azure 检索令牌以发送给 B,这正是 B 可以信任的请求来自受信任的注册源。正如您所了解的,从 A 我有两个令牌,一个用于检查登录用户,另一个用于检查已注册的应用程序。我的 A 启动类如下所示:

public void ConfigureServices(IServiceCollection services)
        {
            Config = services.ConfigureAuthConfig<AuthConfig>(Configuration.GetSection("AuthConfig"));
            services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
            services.AddScoped<ICurrentUser, CurrentUser>();
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
          
           .AddIdentityServerAuthentication(//this coming with identityserver token and user info
                idt =>
                {
                    idt.Authority = "https://gnoauth.se:5005";
                    idt.ApiName = "globalnetworkApi";
                    idt.SaveToken = true;
                    idt.RequireHttpsMetadata = true;
                }
            );

所以这是我的 A httpclienthelper,我在其中设置了要发送到 B 的客户端标头,因为我已经从身份服务器获得了令牌和用户,所以我在这里要做的另一件事是将 B 权限、客户端 ID 和机密发送到 AAD 以进行检索第二个令牌:

var context = new HttpContextAccessor().HttpContext;
var accessTokenFromIdentityserver = await 
                context.GetTokenAsync(OpenIdConnectParameterNames.AccessToken);
var tokenfromAAD = result.AccessToken;

defaultRequestHeaders.Authorization = new 
                AuthenticationHeaderValue("AAD_Authentication", tokenfromAAD);

从这里我实际上拥有了我需要的一切,包括令牌和所有索赔。如您所见,默认请求标头我只能发送一个令牌,但我想将两个令牌都发送给 B,我如何配置请求标头才能做到这一点?

所以这里是 B 启动

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer("AAD_Authentication", opt =>
            {
                opt.Audience = Configuration["AAD:ResourceId"];
                opt.Authority = $"{Configuration["AAD:InstanceId"]}{Configuration["AAD:TenantId"]}";
                opt.RequireHttpsMetadata = true;
            })
            .AddJwtBearer("IDS4_Authentication",
                idt =>
                {
                    idt.Authority = "https://gnoauth.se:5005";
                    idt.Audience = "globalnetworkApi";
                    idt.SaveToken = true;
                    idt.RequireHttpsMetadata = true;
                }
            );

            services.AddAuthorization(options =>
        {
            options.DefaultPolicy = new AuthorizationPolicyBuilder()
                .RequireAuthenticatedUser()
                .AddAuthenticationSchemes("AAD_Authentication", "IDS4_Authentication")
                .Build();

但是我还设置了一个策略,以便从我的一些控制器中我需要像这样授权登录用户和应用程序注册

[Authorize(AuthenticationSchemes = "AAD_Authentication,IDS4_Authentication", Policy = "MyPolicy")]

我一直面临的大问题是如何从 A 发送两个令牌以及如何设置身份验证方案以便 B 实际上获得两个不记名身份验证方案

任何帮助请

标签: c#authenticationidentityserver4dotnet-httpclientbearer-token

解决方案


这是我第一次同时看到两种身份验证方案。有两个 JWT Bearer 配置。通常我用 JWT 和 Cookie 看到它,但不是用两个 JWT。

您可能注意到的一件事是,A 的身份验证方案与 A 调用 B 的身份验证方案不同。在您的情况下,尽管 A 作为 API,但实际上是客户端请求 B 上的授权。从这个角度来看,您什么都没有做 A 认证上 B。

每次您希望 A 调用 B 上的端点时,都应使用具有特定流程的 HttpClient 或 TokenClient。

AddAuthentication 配置是为了保护 A,而不是为了在 B 上获得授权。

其他不同的事情是您想要两个身份提供者 AAD 和 IDS。这应该使用类似于外部身份提供者的东西。

也许我错了,或者我没有理解你。但我希望我能澄清一下这个问题。

PD Azure Functions Easy Auth 有类似“代理”身份提供者的东西。我认为这与外部身份提供者的想法相同。


推荐阅读