我有一个 API 应用程序在网关主机上运行良好,现在网关主机已被弃用,我正在尝试遵循Migration Guide。我已经使用 2.8.1 SDK 重新部署了我的服务,并且可以使用 AAD 或 Microsoft 帐户使用浏览器登录该服务,并使用 Swagger 测试该服务。但是,我试图让客户端使用 ClientId 和 Secret 访问服务。该代码能够从 AAD 获取访问令牌,但每当我尝试访问其中一项服务资源时,我总是会收到 401 错误。
当我调试服务时,我在日志中看到以下内容:
Microsoft.Azure.AppService.Authentication Verbose: 0 : Received request: GET https://[myService].azurewebsites.net/api/[myResource]
Microsoft.Azure.AppService.Authentication Warning: 0 : JWT validation failed: IDX10214: Audience validation failed. Audiences: 'https://[myService].azurewebsites.net/'. Did not match: validationParameters.ValidAudience: '[AAD ClientId]' or validationParameters.ValidAudiences: 'http://[myService].azurewebsites.net'.
Microsoft.Azure.AppService.Authentication Information: 0 : Sending response: 401.71 Unauthorized
The thread 0x3b00 has exited with code 0 (0x0).
问题似乎是请求的受众是 https,但 validParameters.ValidAudiences 集合仅包含 http。
我看不到任何配置受众的方式,并且似乎在 Visual Studio 2015 创建应用服务时正在设置基于 http 的受众。有没有手动编辑 ValidAudience 集合的方法?
作为参考,我的客户代码是:
private static void Main(string[] args)
{
string app_id_url = "https://[myService].azurewebsites.net/";
string authority = "https://login.windows.net/[myDirectory].onmicrosoft.com/";
string clientId = "[AAD ClientId]";
string clientSecret = "[AAD Client Secret]";
string apiBaseUrl = "https://[myService].azurewebsites.net/";
string aadToken = GetTokenForApplication(authority, clientId, clientSecret, app_id_url);
var apiClient = new HttpClient { BaseAddress = new Uri(apiBaseUrl) };
apiClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", aadToken);
var apiResponse = apiClient.GetAsync(apiBaseUrl + @"api/[myResource]").Result;
string apiResponseContent = apiResponse.Content.ReadAsStringAsync().Result;
Console.WriteLine(apiResponseContent);
}
public static string GetTokenForApplication(string authority, string clientId, string clientSecret, string resourceUrl)
{
AuthenticationContext authenticationContext = new AuthenticationContext(authority, false);
ClientCredential clientCred = new ClientCredential(clientId, clientSecret);
AuthenticationResult authenticationResult = authenticationContext.AcquireToken(resourceUrl, clientCred);
string token = authenticationResult.AccessToken;
return token;
}