使用AAD对Azure API App进行身份validation时出现401错误

我有一个API应用程序,与网关主机一起工作正常,现在网关主机已被弃用我正在尝试遵循迁移指南 。 我使用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。

我看不到配置Audience的任何方式,并且在Visual Studio 2015创建App Service时,似乎正在设置基于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; } 

您的问题与有效受众有关。 您可以有两个选择:

选项1.尝试使用WebAPI客户端ID作为AcquireToken方法’resource’参数获取令牌,而不是其Uri。

选项2.如果以前的方法不起作用,则必须使用Azure资源资源管理器修改App Service API的身份validation设置。 导航到您的Web API,在config节点下找到authSettings JSON文档,并修改(在更改为读/写模式后)数组allowedAudiences以满足您的需求。 在您的情况下,您可能需要将http更改为https

在我的ASP.NET 4.5 Web应用程序中,我发现必须指定有效的受众,以避免抛出运行时exception。

 public partial class Startup { private static string _aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"]; private static string _tenant = ConfigurationManager.AppSettings["ida:Tenant"]; private static string _realm = ConfigurationManager.AppSettings["ida:Wtrealm"]; private static string _metadataAddress = string.Format("{0}/{1}/federationmetadata/2007-06/federationmetadata.xml", _aadInstance, _tenant); private static string _authority = String.Format(CultureInfo.InvariantCulture, _aadInstance, _tenant); public void ConfigureAuth(IAppBuilder app) { app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); app.UseCookieAuthentication(new CookieAuthenticationOptions()); app.UseWsFederationAuthentication( new WsFederationAuthenticationOptions { Wtrealm = _realm, MetadataAddress = _metadataAddress, TokenValidationParameters = new TokenValidationParameters { ValidAudiences = new string[] { "spn:" + _realm } } } ); } }