来自Blazor的API在Azure API管理背后使用Validate-JWT的呼叫
在Azure API管理的后面,我有一堆API。我所有的应用程序都使用身份服务器4来验证和身份验证用户和应用程序。当对API的请求到来时,我喜欢在继续前进之前验证jwt
令牌。
因此,在API管理中,在“安全性”部分下,我选择了OpenID Connect
,然后选择了我的身份服务器。
在API的设计中,我添加了验证-jwt
,策略就是这样。
<policies>
<inbound>
<validate-jwt header-name="Authorization"
failed-validation-httpcode="401" require-scheme="Bearer"
output-token-variable-name="jwt">
<openid-config url="https://idsrv4/.well-known/openid-configuration" />
</validate-jwt>
<cors>
<allowed-origins>
<origin>*</origin>
</allowed-origins>
<allowed-methods preflight-result-max-age="300">
<method>GET</method>
<method>POST</method>
</allowed-methods>
<allowed-headers>
<header>*</header>
</allowed-headers>
<expose-headers>
<header>*</header>
</expose-headers>
</cors>
<base />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
然后,在我的jullazor webAssembly的program.cs
中,我最终添加了以下代码
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");
string apiEndpoint = builder.Configuration["Api:EndpointsUrl"];
string apiScope = builder.Configuration["Api:Scope"];
builder.Services.AddScoped<APIService>();
#region Configure HTTP Client
builder.Services.AddHttpClient("companiesAPI", cl =>
{
cl.BaseAddress = new Uri(apiEndpoint);
})
.AddHttpMessageHandler(sp =>
{
var handler = sp.GetService<AuthorizationMessageHandler>()
.ConfigureHandler(
authorizedUrls: new[] { "https://localhost:7241" },
scopes: new[] { "220005_api" }
);
return handler;
});
builder.Services.AddScoped(sp => sp.GetService<IHttpClientFactory>().CreateClient("companiesAPI"));
#endregion
#region Configure Authentication and Authorization
builder.Services.AddOidcAuthentication(options =>
{
builder.Configuration.Bind("oidc", options.ProviderOptions);
options.UserOptions.RoleClaim = "role";
})
.AddAccountClaimsPrincipalFactory<MultipleRoleClaimsPrincipalFactory<RemoteUserAccount>>();
builder.Services.AddAuthorizationCore();
#endregion
await builder.Build().RunAsync();
,在API服务中,我阅读了API。
public class APIService
{
private readonly HttpClient _httpClient;
private readonly JsonSerializerOptions _options;
public APIService(HttpClient httpClient)
{
_httpClient = httpClient;
_options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
}
public async Task<APIResponse> GetAttributeAsync(APIRequest apirequest)
{
try
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, $"typing");
var content =
new StringContent(JsonSerializer.Serialize(apirequest),
Encoding.UTF8, "application/json");
request.Content = content;
HttpResponseMessage responseMessage;
responseMessage = await _httpClient.SendAsync(request);
responseMessage.EnsureSuccessStatusCode();
if (responseMessage.IsSuccessStatusCode)
{
var responseContent = await responseMessage.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<APIResponse>(responseContent, _options);
}
else
return new APIResponse() { Success = false };
}
catch (Exception ex)
{
return new APIResponse() { Success = false };
}
}
}
现在,如果我调用API,我有以下错误:
TypeError:无法获取
,则无法获取validate-jwt
,该应用程序调用API并在没有问题的情况下接收答案。
API管理的正确配置是什么?通过jwt
令牌的大火项目中的正确代码是什么?
Behind an Azure API Management I have a bunch of APIs. All my applications are using an Identity Server 4 to validate and authenticate users and applications. When a request to the API comes, I like to validate the jwt
token before proceeding.
For this reason , in the API Management, under the Security section, I selected OpenID connect
and then my Identity Server.
In the design of the APIs, I added the validation-jwt
and the policy is like that
<policies>
<inbound>
<validate-jwt header-name="Authorization"
failed-validation-httpcode="401" require-scheme="Bearer"
output-token-variable-name="jwt">
<openid-config url="https://idsrv4/.well-known/openid-configuration" />
</validate-jwt>
<cors>
<allowed-origins>
<origin>*</origin>
</allowed-origins>
<allowed-methods preflight-result-max-age="300">
<method>GET</method>
<method>POST</method>
</allowed-methods>
<allowed-headers>
<header>*</header>
</allowed-headers>
<expose-headers>
<header>*</header>
</expose-headers>
</cors>
<base />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
Then, in the Program.cs
of my Blazor WebAssembly, I added the following code
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");
string apiEndpoint = builder.Configuration["Api:EndpointsUrl"];
string apiScope = builder.Configuration["Api:Scope"];
builder.Services.AddScoped<APIService>();
#region Configure HTTP Client
builder.Services.AddHttpClient("companiesAPI", cl =>
{
cl.BaseAddress = new Uri(apiEndpoint);
})
.AddHttpMessageHandler(sp =>
{
var handler = sp.GetService<AuthorizationMessageHandler>()
.ConfigureHandler(
authorizedUrls: new[] { "https://localhost:7241" },
scopes: new[] { "220005_api" }
);
return handler;
});
builder.Services.AddScoped(sp => sp.GetService<IHttpClientFactory>().CreateClient("companiesAPI"));
#endregion
#region Configure Authentication and Authorization
builder.Services.AddOidcAuthentication(options =>
{
builder.Configuration.Bind("oidc", options.ProviderOptions);
options.UserOptions.RoleClaim = "role";
})
.AddAccountClaimsPrincipalFactory<MultipleRoleClaimsPrincipalFactory<RemoteUserAccount>>();
builder.Services.AddAuthorizationCore();
#endregion
await builder.Build().RunAsync();
Finally, in the API service, I read the API.
public class APIService
{
private readonly HttpClient _httpClient;
private readonly JsonSerializerOptions _options;
public APIService(HttpClient httpClient)
{
_httpClient = httpClient;
_options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
}
public async Task<APIResponse> GetAttributeAsync(APIRequest apirequest)
{
try
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, quot;typing");
var content =
new StringContent(JsonSerializer.Serialize(apirequest),
Encoding.UTF8, "application/json");
request.Content = content;
HttpResponseMessage responseMessage;
responseMessage = await _httpClient.SendAsync(request);
responseMessage.EnsureSuccessStatusCode();
if (responseMessage.IsSuccessStatusCode)
{
var responseContent = await responseMessage.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<APIResponse>(responseContent, _options);
}
else
return new APIResponse() { Success = false };
}
catch (Exception ex)
{
return new APIResponse() { Success = false };
}
}
}
Now, if I call the API, I have the following error:
TypeError: Failed to fetch
If from the API Management, I remove the validate-jwt
, the application calls the API and receives the answer with no issues.
What is the correct configuration for the API Management? What is the correct code in the Blazor project to pass the jwt
token?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
获得这样的JWT
在您的应用程序代码中,您应该在apim =&gt中 ;在入站中,您缺少所需的索赔
在
请查看此问题以获取更多代码详细信息。代码很好!
如何在具有Microsoft Identity平台(AAD)的Blazor Server应用中获取JWT来进行外部API管理调用并授权使用JWT
In your application code you should get the JWT like this
In the APIM => In the Inbound you are missing the required claims
Check your JWT over here to set the right claim for 'aud' in your APIM
Have a look at this question for more code details. The code is GOOD!
How do I get the JWT in a Blazor Server App with Microsoft Identity Platform (AAD) to make external API-Management call and authorize with the jwt