如何获取针对特定用户分配的Azure App Service托管服务标识的令牌? [英] How to get a token for specific user assigned managed service identity for Azure App Service?

查看:77
本文介绍了如何获取针对特定用户分配的Azure App Service托管服务标识的令牌?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试获取特定用户定义身份的msi令牌.我们的应用程序服务具有2个用户定义的身份,我想要代表用户分配的身份之一的令牌.

这是代码:

  HttpWebRequest req =(HttpWebRequest)WebRequest.Create("http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/&object_id=<ObjectId>&client_id=< clientId>);req.Headers ["Metadata"] ="true";req.Method ="GET";尝试{//调用/token端点HttpWebResponse响应=(HttpWebResponse)req.GetResponse();//将响应流管道传输到StreamReader,并提取访问令牌StreamReader streamResponse =新的StreamReader(response.GetResponseStream());字符串stringResponse = streamResponse.ReadToEnd();字典< string,string>清单=JsonConvert.DeserializeObject< Dictionary< string,string>>(stringResponse);字符串accessToken = list ["access_token"];System.IO.File.WriteAllText(@.\ Log.txt",accessToken);}捕获(异常e){字符串errorText = String.Format("{0} \ n \ n {1}",e.Message,e.InnerException!= null?e.InnerException.Message:获取令牌失败");System.IO.File.WriteAllText(@.\ Log.txt",errorText);扔;} 

它已部署在azure应用程序服务中.当我点击此部分时,我看到此错误:尝试以其访问权限禁止的方式访问套接字

我尝试使用kudu控制台连接到

我确实尝试使用Microsoft.Azure.Services.AppAuthentication中的AzureServiceTokenProvider生成msi令牌,但是找不到有关如何将其用于多个用户分配的身份的任何文档.

更新1:

我尝试使用MSI_ENDPOINT环境变量中的端点,而不是169.254.169.254.但是,当我运行应用程序服务时,似乎未设置MSI_ENDPOINT值.这是我尝试过的代码:

  var端点= Environment.GetEnvironmentVariable("MSI_ENDPOINT");字符串apiVersion ="2018-02-01";字符串资源="https://management.azure.com/";字符串objectId =< objectid>";字符串clientId =< clientId>";//建立请求以获取Azure资源令牌的托管身份//HttpWebRequest req =(HttpWebRequest)WebRequest.Create(//"http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/&object_id=4aef1720-b3b1-4935-8d68-e330508907fa& client_id = 558ecc75-8697-4419-bab9-aa2c87043cfd);HttpWebRequest req =(HttpWebRequest)WebRequest.Create(String.Format("{0}?resource = {1}& api-version = {2}& object_id = {3}& client_id = {4}",端点,资源,apiVersion,objectId,clientId));req.Headers ["Metadata"] ="true";req.Method ="GET";尝试{//调用/token端点HttpWebResponse响应=(HttpWebResponse)req.GetResponse();//将响应流管道传输到StreamReader,并提取访问令牌StreamReader streamResponse =新的StreamReader(response.GetResponseStream());字符串stringResponse = streamResponse.ReadToEnd();字典< string,string>清单=JsonConvert.DeserializeObject< Dictionary< string,string>>(stringResponse);字符串accessToken = list ["access_token"];System.IO.File.WriteAllText(@.\ Log.txt",accessToken);}捕获(异常e){字符串errorText = String.Format("{0} \ n \ n {1}",e.Message,e.InnerException!= null?e.InnerException.Message:获取令牌失败");字符串日志="MSI_ENDPOINT:" +端点+"\ n";log + =("ErrorText:" + errorText +"\ n");System.IO.File.WriteAllText(@.\ Log.txt",errorText);扔;} 

解决方案

首先,此链接

  • 与使用的所有参数相关的文档截图

  • I am trying to get a msi token for a specific User defined identity. Our app service has 2 user defined identities and I want a token on behalf of one of the user assigned identity.

    Here is the code:

            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(
                "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/&object_id=<ObjectId>&client_id=<clientId>");
    
            req.Headers["Metadata"] = "true";
            req.Method = "GET";
    
            try
            {
                // Call /token endpoint
                HttpWebResponse response = (HttpWebResponse)req.GetResponse();
    
                // Pipe response Stream to a StreamReader, and extract access token
                StreamReader streamResponse = new StreamReader(response.GetResponseStream());
                string stringResponse = streamResponse.ReadToEnd();
                Dictionary<string, string> list =
                     JsonConvert.DeserializeObject<Dictionary<string, string>>(stringResponse);
                string accessToken = list["access_token"];
    
                System.IO.File.WriteAllText(@".\Log.txt", accessToken);
            }
            catch (Exception e)
            {
                string errorText = String.Format("{0} \n\n{1}", e.Message, e.InnerException != null ? e.InnerException.Message : "Acquire token failed");
                System.IO.File.WriteAllText(@".\Log.txt", errorText);
                throw;
            }
    

    It is deployed in an azure app service. When I hit this section I see this error: An attempt was made to access a socket in a way forbidden by its access permissions

    I tried connecting to http://169.254.169.254 to get the token using kudu console. But this endpoint does not seem to accessible there.

    I did try to use AzureServiceTokenProvider from Microsoft.Azure.Services.AppAuthentication for generating msi token but could not find any documentation about how to use it for multiple user assigned identities.

    Edit:

    Update 1:

    I tried to use endpoint from MSI_ENDPOINT environment variable instead of 169.254.169.254. But it looks like MSI_ENDPOINT value is not set when I run the app service. Here is the code I have tried:

       var endpoint = Environment.GetEnvironmentVariable("MSI_ENDPOINT");
        string apiVersion = "2018-02-01";
        string resource = "https://management.azure.com/";
        string objectId = "<objectid>";
        string clientId = "<clientId>";
    
            // Build request to acquire managed identities for Azure resources token
            //HttpWebRequest req = (HttpWebRequest)WebRequest.Create(
            //    "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/&object_id=4aef1720-b3b1-4935-8d68-e330508907fa&client_id=558ecc75-8697-4419-bab9-aa2c87043cfd");
    
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(
           String.Format(
                "{0}?resource={1}&api-version={2}&object_id={3}&client_id={4}",
                endpoint,
                resource,
                apiVersion,
                objectId,
                clientId));
    
            req.Headers["Metadata"] = "true";
            req.Method = "GET";
    
            try
            {
                // Call /token endpoint
                HttpWebResponse response = (HttpWebResponse)req.GetResponse();
    
                // Pipe response Stream to a StreamReader, and extract access token
                StreamReader streamResponse = new StreamReader(response.GetResponseStream());
                string stringResponse = streamResponse.ReadToEnd();
                Dictionary<string, string> list =
                     JsonConvert.DeserializeObject<Dictionary<string, string>>(stringResponse);
                string accessToken = list["access_token"];
    
                System.IO.File.WriteAllText(@".\Log.txt", accessToken);
            }
            catch (Exception e)
            {
                string errorText = String.Format("{0} \n\n{1}", e.Message, e.InnerException != null ? e.InnerException.Message : "Acquire token failed");
    
                string log = "MSI_ENDPOINT : " + endpoint + "\n";
                log += ("ErrorText : " + errorText + "\n");
                System.IO.File.WriteAllText(@".\Log.txt", errorText);
                throw;
            }
    

    解决方案

    Firstly, this link How to use managed identities for App Service and Azure Functions provides good documentation specific to MSI for App Services.

    Here is quick sample code.. to get token for a specific user assigned managed service identity as you've asked in your question.

    • resource - The AAD resource URI of the resource for which a token should be obtained.
    • apiversion - The version of the token API to be used. "2017-09-01" is currently the only version supported.
    • clientId - The ID of the user-assigned identity to be used. If omitted, the system-assigned identity is used.

      public static async Task<HttpResponseMessage> GetToken(string resource, string apiversion, string clientId)  
      {
          HttpClient client = new HttpClient();   
          client.DefaultRequestHeaders.Add("Secret", Environment.GetEnvironmentVariable("MSI_SECRET"));
          return await client.GetAsync(String.Format("{0}/?resource={1}&api-version={2}&clientid={3}", Environment.GetEnvironmentVariable("MSI_ENDPOINT"), resource, apiversion,clientId));
      }
      

      Overall I see a few changes that you should notice in the sample code above:

      1. Make use of MSI_ENDPOINT to construct URL at runtime
      2. parameter should be clientid and not client_id
      3. parameter object_id is not needed
      4. api version should be "2017-09-01" as documentation in above link says that's the only one supported.

    • About your issue with MSI_ENDPOINT value not being set when you run the app service, please take a look at this note from same link in Microsoft Docs

    • Screenshot from documentation that is relevant for all parameters used

    这篇关于如何获取针对特定用户分配的Azure App Service托管服务标识的令牌?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆