我在通过托管服务身份向通过AAD保护的Azure应用服务进行身份验证时遇到问题

时间:2019-06-12 14:52:44

标签: c# azure azure-active-directory azure-web-sites

我正在尝试使用HttpClient连接到托管在Azure应用服务中的Web服务,该服务通过AAD使用托管服务标识来保护。 尝试使用AzureServiceTokenProvider从客户端代码连接时,尝试获取令牌时出现AzureServiceTokenProviderException

基本设置:

AAD租户AADX.onmicrosoft.com 包含目标应用程序服务mytest的应用程序注册。它具有应用程序ID XXXXXXXX-XXXX-49e6-a806-5440b00282b1,并根据清单具有标识符URL“ https://AADX.onmicrosoft.com/mytest

已在此AAD下的订阅中创建了一个应用程序服务“ mytest”,因此其网址为https://mytest.azurewebsites.net

在应用程序服务的身份验证设置中,“应用程序服务身份验证”已打开。未验证请求时要采取的操作设置为“使用Azure Active Directory登录”。 AAD身份验证提供程序配置有明确的设置,指向AADX并使用“ mytest”应用程序。

我们在天蓝色的租户内部和外部都需要与该应用程序服务进行对话的资源。天蓝色租户之外的资源通过可管理的订阅密钥,通过API管理将其路由到所需的API特定部分。

RemoteApp中托管的应用程序服务和桌面应用程序需要访问该应用程序下托管的完整服务。已为需要连接的租户内的所有基础架构打开了托管身份。

当我使用下面的代码时,我会得到一个关于未能获得令牌的异常。如果我将请求的资源更改为“ https://login.microsoftonline.com/”,那么我可以获得一个令牌,尽管它不是正确的令牌(实际上是选择我的MS在线登录信息,而不是在选项中选择的帐户)

        private static HttpClient ConnectToClient()
        {
            String BaseUrl = "https://mytest.azurewebsites.net/";
            String AdResource = "https://AADX.onmicrosoft.com/mytest";

            AzureServiceTokenProvider TokenProvider = new AzureServiceTokenProvider();
            String Token = TokenProvider.GetAccessTokenAsync(AdResource).Result;

            HttpClient Client = new HttpClient()
            {
                BaseAddress = new Uri(BaseUrl)
            };

            Client.DefaultRequestHeaders.Accept.Clear();
            Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));


            Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Token);

            return Client;
        }

        private static String GetContent()
        {
            String Output = String.Empty;

            using (HttpClient Client = ConnectToClient())
            {
                HttpResponseMessage ResponseMessage = Client.GetAsync("api/Test/").Result;

                if (ResponseMessage.IsSuccessStatusCode)
                {
                    Output = ResponseMessage.Content.ReadAsStringAsync().Result;
                }
            }

            return Output;
        }

我希望将令牌作为有效值返回,以用作承载令牌。相反,在调用GetAccessTokenAsync时会引发以下异常:

System.AggregateException   HResult = 0x80131500   Message =发生一个或多个错误。 (参数:连接字符串:[未指定连接字符串],资源:https://AADX.onmicrosoft.com/mytest,权限:。异常消息:尝试了以下3种方法来获取访问令牌,但没有一种有效。

参数:连接字符串:[未指定连接字符串],资源:https://AADX.onmicrosoft.com/mytest,权限:。异常消息:尝试使用托管服务身份获取令牌。无法连接到托管服务标识(MSI)端点。请检查您是否正在运行具有MSI安装程序的Azure资源。 参数:连接字符串:[未指定连接字符串],资源:https://AADX.onmicrosoft.com/mytest,权限:。异常消息:尝试使用Visual Studio获取令牌。无法获取访问令牌。 Visual Studio令牌提供者Microsoft.Asal.TokenService.exe的异常:TS003:错误,TS004:无法获取访问令牌。 “无法刷新访问令牌”

2 个答案:

答案 0 :(得分:0)

AzureServiceTokenProvider部署在Azure上时使用托管身份。当不在Azure上时,它确实支持其他身份验证选项。您可以使用在环境变量中指定的显式服务主体凭据,而无需更改代码。请参阅文档here

答案 1 :(得分:0)

每个Visual Studio版本都提供自己的Microsoft.Asal.TokenService.exe版本,并将其反映在%LOCALAPPDATA%.IdentityService \ AzureServiceAuth \ tokenprovider.json配置文件中。请在此处的“路径”中验证扩展文件夹。

例如,对于Visual Studio版本16.4,扩展名位于文件夹“ ys2aolp3.2rs”中:

{ 
  "TokenProviders": [
    { 
      "Path": "c:\\program files (x86)\\microsoft visual studio\\2019\\enterprise\\common7\\ide\\extensions\\ys2aolp3.2rs\\TokenService\\Microsoft.Asal.TokenService.exe",
      "Arguments": [
        "--serviceHubConfig", 
        "\"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\Common7\\servicehub.config.json\""
      ], 
      "Preference": 0
    }
  ]
}