如何代表流在.Net Core中调用下游API?
Posted
技术标签:
【中文标题】如何代表流在.Net Core中调用下游API?【英文标题】:How to call downstream API in .Net Core using on behalf of flow? 【发布时间】:2021-08-12 19:38:10 【问题描述】:Net 核心应用程序和反应。我有调用我的中间层 api 和中间层 api 调用下游 api 的反应应用程序。我在 azure ad 中注册了三个应用程序。我已经做了所有的配置。在中间层 API 中,我正在验证从反应应用程序收到的令牌并尝试获取下游 api 的令牌,如下所示。
public void ConfigureServices(IServiceCollection services)
services.AddControllers();
services.AddTransient<DownStreamAPIService>();
services.AddHttpClient();
services.AddOptions();
var azureAd = Configuration.GetSection("AzureAd").Get<AzureAd>();
IdentityModelEventSource.ShowPII = true;
services.AddMicrosoftIdentityWebApiAuthentication(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
services.AddAuthentication(x =>
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
)
.AddJwtBearer(options =>
options.SaveToken = true;
options.RequireHttpsMetadata = true;
options.Authority = $"azureAd.Instance/azureAd.TenantId/v2.0";
options.Audience = $"azureAd.ClientId";
options.TokenValidationParameters = new TokenValidationParameters
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuer = true,
ValidateIssuerSigningKey = false,
ValidateActor = false
;
);
services.AddCors(options =>
options.AddPolicy(
"CorsPolicy",
builder =>
builder
.WithOrigins("https://localhost:3000")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
);
);
下面是 DownStreamAPIService 类
public async Task<JArray> GetApiDataAsync()
var client = _clientFactory.CreateClient();
// user_impersonation access_as_user access_as_application .default
var scope = _configuration["DownStreamAPI:ScopeForAccessToken"];
var accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(new[] scope ).ConfigureAwait(false);
client.BaseAddress = new Uri(_configuration["DownStreamAPI:ApiBaseAddress"]);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = await client.GetAsync("weatherforecast").ConfigureAwait(false);
if (response.IsSuccessStatusCode)
var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
var data = JArray.Parse(responseContent);
return data;
throw new ApplicationException($"Status code: response.StatusCode, Error: response.ReasonPhrase");
下面是appsettings.json文件
"AzureAd":
"Instance": "https://login.microsoftonline.com/",
"Domain": "mydomain.onmicrosoft.com",
"TenantId": "c5fff990-0e0a-4bf6-9c04-79ab98e05931",
"ClientId": "43dg8b3c-8743-4d6e-84b4-00fe04d93222"
,
"WebOriginUrl": "https://localhost:3000",
"DownStreamAPI":
"ScopeForAccessToken": "api://723fac69-4038-4e16-92cc-3f57b7cc2381/access_downstream_api_as_user",
"ApiBaseAddress": "https://localhost:44316"
当我运行应用程序时出现以下错误
方案已经存在:Bearer
在我的中间层应用程序中,我正在验证令牌并尝试为下游 API 获取新令牌。我只是对中间层 api 中是否需要天气验证令牌感到困惑。我代表流量使用。如果此设计有任何问题,可以提供帮助。任何帮助,将不胜感激。谢谢
【问题讨论】:
【参考方案1】:当我们使用AddMicrosoftIdentityWebApiAuthentication
配置Azure AD 时,项目将使用Bearer
方案进行身份验证。我们不需要再次配置它。更多详情请参考here和here。所以请删除代码
services.AddAuthentication(x =>
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
)
.AddJwtBearer(options =>
options.SaveToken = true;
options.RequireHttpsMetadata = true;
options.Authority = $"azureAd.Instance/azureAd.TenantId/v2.0";
options.Audience = $"azureAd.ClientId";
options.TokenValidationParameters = new TokenValidationParameters
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuer = true,
ValidateIssuerSigningKey = false,
ValidateActor = false
;
);
如果要验证token,可以使用以下代码
services.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options =>
options.SaveToken = true;
options.RequireHttpsMetadata = true;
options.TokenValidationParameters = new TokenValidationParameters
ValidateAudience = true,
ValidAudiences = new string[] "872ebcec-c24a-4399-835a-201cdaf7d68b", "api://872ebcec-c24a-4399-835a-201cdaf7d68b" ,
ValidateLifetime = true,
ValidateIssuer = true,
ValidateIssuerSigningKey = false,
ValidateActor = false,
ValidIssuers = new string[] "https://sts.windows.net/tenantId", "https://login.microsoftonline.com/tenantId/v2.0"
;
);
【讨论】:
以上是关于如何代表流在.Net Core中调用下游API?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 IdentityServer ASP.NET Core 中使用 Postman 使用 AntiForgeryToken 调用 API
如何在 .net Core API 项目中跨多个线程限制对 HttpClient 的所有传出异步调用
无论用户登录如何,如何保护 Angular / .NET Core 2.0 应用程序中的所有 api 调用