使用来自 Azure AD 的不记名令牌保护 ASP.Net Core 3.1 API
Secure ASP.Net Core 3.1 API with Bearer Tokens from Azure AD
我有一个 .net core 3.1 网站 API。我想使用来自 Azure AD 的不记名令牌来保护端点。
我关注了This guide。我为 API 注册了一个应用程序,为客户端注册了一个应用程序。
在我的 API 中,我添加了 jwt 的注册(如代码中所述)
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(opt =>
{
opt.Audience = Configuration["AzureAd:ResourceId"];
opt.Authority = $"{Configuration["AzureAd:Instance"]}{Configuration["AzureAd:TenantId"]}";
});
我的 API 配置部分看起来像这样
"AzureAd": {
"ResourceId": "api://<client-id-guid>",
"Instance": "https://login.microsoftonline.com/",
"TenantId": "<tenant-id-guid>"
}
其中 client-id-guid
是 api 应用程序的客户端 ID(使用 api:// 地址的默认配置)。
然后,对于我的客户,我在一个新的解决方案中实施了一个测试,以获取令牌并调用安全端点。
AadConfiguration config = AadConfiguration.ReadFromJsonFile("appsettings.json");
IConfidentialClientApplication app;
app = ConfidentialClientApplicationBuilder.Create(config.ClientId)
.WithClientSecret(config.ClientSecret)
.WithAuthority(new Uri(config.Authority))
.Build();
string[] ResourceIds = new string[] {config.ResourceID};
var token = await app.AcquireTokenForClient(ResourceIds)
.ExecuteAsync();
Assert.IsFalse(string.IsNullOrWhiteSpace(token.AccessToken));
var request = new RestRequestBuilder("https://my-api-staging.azurewebsites.net/api")
.WithSegments("health-check", "auth")
.WithBearerToken(token.AccessToken)
.Build();
try
{
var response = await _restHelper.GetJsonAsync<dynamic>(request);
Assert.IsFalse(string.IsNullOrEmpty(response?.serverTime?.ToString()));
}
catch (RestException e)
{
Assert.IsFalse(true, e.ResponseContent);
}
以及本次测试的配置
{
"Instance": "https://login.microsoftonline.com/{0}",
"TenantId": "<tenant-id-guid>",
"ClientId": "<client-id-guid>",
"ClientSecret": "<client-secret>",
"ResourceId": "api://<api-client-id-guid>/.default"
}
租户 ID 是 API 和测试应用程序
的销售
client ID是客户端app注册的client id,它的secret
资源 ID 是 API 的应用程序 ID,即 api:// 和 api 的客户端 ID
我可以很好地检索访问令牌。但是,当我使用获得的访问令牌调用端点时,出现以下错误:
Couldn't find a valid certificate with subject 'CN=TODO.azurewebsites.net' on the 'CurrentUser\My'
当我按照文档中的步骤操作时,我不确定为什么我的身份验证失败了。
I can retrieve the access token just fine. However, when I call an endpoint using the access token I am given, I get the following error:
我遵循 guide 并在我的网站上进行了测试,效果非常好。
获得access token后,可以尝试在postman中使用它向core发送请求api。虽然核心 api 是 3.1 版本,所以它没有 /api
来路由它。
并且可以使用HttpClient
调用核心网api。
var token = await app.AcquireTokenForClient(ResourceIds).ExecuteAsync();
var accesstoken = token.AccessToken;
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accesstoken);
var requestURl = new Uri($"https://xxxx.azurewebsites.net/weatherforecast");
var response = client.GetAsync(requestURl).Result;
string result = response.Content.ReadAsStringAsync().Result;
}
我有一个 .net core 3.1 网站 API。我想使用来自 Azure AD 的不记名令牌来保护端点。
我关注了This guide。我为 API 注册了一个应用程序,为客户端注册了一个应用程序。
在我的 API 中,我添加了 jwt 的注册(如代码中所述)
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(opt =>
{
opt.Audience = Configuration["AzureAd:ResourceId"];
opt.Authority = $"{Configuration["AzureAd:Instance"]}{Configuration["AzureAd:TenantId"]}";
});
我的 API 配置部分看起来像这样
"AzureAd": {
"ResourceId": "api://<client-id-guid>",
"Instance": "https://login.microsoftonline.com/",
"TenantId": "<tenant-id-guid>"
}
其中 client-id-guid
是 api 应用程序的客户端 ID(使用 api:// 地址的默认配置)。
然后,对于我的客户,我在一个新的解决方案中实施了一个测试,以获取令牌并调用安全端点。
AadConfiguration config = AadConfiguration.ReadFromJsonFile("appsettings.json");
IConfidentialClientApplication app;
app = ConfidentialClientApplicationBuilder.Create(config.ClientId)
.WithClientSecret(config.ClientSecret)
.WithAuthority(new Uri(config.Authority))
.Build();
string[] ResourceIds = new string[] {config.ResourceID};
var token = await app.AcquireTokenForClient(ResourceIds)
.ExecuteAsync();
Assert.IsFalse(string.IsNullOrWhiteSpace(token.AccessToken));
var request = new RestRequestBuilder("https://my-api-staging.azurewebsites.net/api")
.WithSegments("health-check", "auth")
.WithBearerToken(token.AccessToken)
.Build();
try
{
var response = await _restHelper.GetJsonAsync<dynamic>(request);
Assert.IsFalse(string.IsNullOrEmpty(response?.serverTime?.ToString()));
}
catch (RestException e)
{
Assert.IsFalse(true, e.ResponseContent);
}
以及本次测试的配置
{
"Instance": "https://login.microsoftonline.com/{0}",
"TenantId": "<tenant-id-guid>",
"ClientId": "<client-id-guid>",
"ClientSecret": "<client-secret>",
"ResourceId": "api://<api-client-id-guid>/.default"
}
租户 ID 是 API 和测试应用程序
的销售client ID是客户端app注册的client id,它的secret
资源 ID 是 API 的应用程序 ID,即 api:// 和 api 的客户端 ID
我可以很好地检索访问令牌。但是,当我使用获得的访问令牌调用端点时,出现以下错误:
Couldn't find a valid certificate with subject 'CN=TODO.azurewebsites.net' on the 'CurrentUser\My'
当我按照文档中的步骤操作时,我不确定为什么我的身份验证失败了。
I can retrieve the access token just fine. However, when I call an endpoint using the access token I am given, I get the following error:
我遵循 guide 并在我的网站上进行了测试,效果非常好。
获得access token后,可以尝试在postman中使用它向core发送请求api。虽然核心 api 是 3.1 版本,所以它没有 /api
来路由它。
并且可以使用HttpClient
调用核心网api。
var token = await app.AcquireTokenForClient(ResourceIds).ExecuteAsync();
var accesstoken = token.AccessToken;
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accesstoken);
var requestURl = new Uri($"https://xxxx.azurewebsites.net/weatherforecast");
var response = client.GetAsync(requestURl).Result;
string result = response.Content.ReadAsStringAsync().Result;
}