我有两个webapi 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 实际上获得两个承载身份验证方案
如有任何帮助,请
我还是第一次看到两种认证方案同时存在的事情。具有两个 JWT 承载配置。通常我看到的是 JWT 和 Cookie,但不是两个 JWT。
您可能会注意到的一件事是,A 的身份验证方案与 A 调用 B 的身份验证方案不同。在您的情况下,尽管 A 作为 API,但实际上是请求 B 授权的客户端。从这个角度来看,您有在 A 身份验证上无需执行任何操作即可进入 B。
每次您希望 A 调用 B 上的端点时,您应该使用具有特定流程的 HttpClient 或 TokenClient。
AddAuthentication配置是为了保护A,而不是为了获得B的授权。
其他不同的事情是您需要两个身份提供商 AAD 和 IDS。这应该使用类似于外部身份提供商的东西。
也许我错了或者我没理解你的意思。但我希望我能澄清这个问题。
P.D. Azure Functions Easy Auth 具有类似于“代理”身份提供程序的功能。我认为这与外部身份提供商的想法相同。
我无法说明您的 API 如何验证这样的请求,或者拥有多个身份验证标头(无论是否使用不同的方案)通常是一个好主意。
我在单元测试中完成了此操作,以便检查具有多个身份验证标头的请求的处理,这就是我的做法:
var headerValues = new[] { $"Basic {basicToken}", $"Bearer {bearerToken}" };
var context = new DefaultHttpContext();
context.Request.Headers.Append("Authorization", new StringValues(headerValues));
这将生成一个 auth 标头,其中包含两个可以访问的值。