Použití spravovaných identit pro prostředky Azure na virtuálním počítači Azure k získání přístupového tokenu

Spravované identity pro prostředky Azure jsou funkcí ID Microsoft Entra. Každá ze služeb Azure, které podporují spravované identity pro prostředky Azure, se řídí vlastní časovou osou. Než začnete, nezapomeňte zkontrolovat stav dostupnosti spravovaných identit pro váš prostředek a známé problémy.

Spravované identity pro prostředky Azure poskytují službám Azure automaticky spravovanou identitu v Microsoft Entra ID. Tuto identitu můžete použít k ověření ve všech službách, které podporují ověřování Microsoft Entra, aniž byste v kódu měli přihlašovací údaje.

Tento článek obsahuje různé příklady kódu a skriptů pro získání tokenu. Obsahuje také pokyny týkající se zpracování vypršení platnosti tokenu a chyb HTTP.

Předpoklady

Pokud plánujete používat příklady Azure PowerShellu v tomto článku, nezapomeňte nainstalovat nejnovější verzi Azure PowerShellu.

Důležité

  • Veškerý ukázkový kód nebo skript v tomto článku předpokládá, že klient běží na virtuálním počítači se spravovanými identitami pro prostředky Azure. Pomocí funkce "Připojení" virtuálního počítače na webu Azure Portal se vzdáleně připojte k virtuálnímu počítači. Podrobnosti o povolení spravovaných identit pro prostředky Azure na virtuálním počítači najdete v tématu Konfigurace spravovaných identit pro prostředky Azure na virtuálním počítači pomocí webu Azure Portal nebo některého z článků o variantách (pomocí PowerShellu, rozhraní příkazového řádku, šablony nebo sady Azure SDK).

Důležité

  • Hranice zabezpečení spravovaných identit pro prostředky Azure je prostředek, ve kterém se identita používá. Všechny kódy a skripty spuštěné na virtuálním počítači můžou požadovat a načítat tokeny pro všechny spravované identity, které jsou v něm k dispozici.

Přehled

Klientská aplikace může požádat o přístup k danému prostředku přístupový token jen pro spravovanou identitu. Token je založený na spravovaných identitách instančního objektu prostředků Azure. Proto není nutné, aby klient získal přístupový token pod vlastním instančním objektem. Token je vhodný pro použití jako nosný token ve voláních mezi službami vyžadujících přihlašovací údaje klienta.

Odkaz Popis
Získání tokenu pomocí protokolu HTTP Podrobnosti protokolu pro spravované identity pro koncový bod tokenu prostředků Azure
Získání tokenu pomocí Azure.Identity Získání tokenu pomocí knihovny Azure.Identity
Získání tokenu pomocí knihovny Microsoft.Azure.Services.AppAuthentication pro .NET Příklad použití knihovny Microsoft.Azure.Services.AppAuthentication z klienta .NET
Získání tokenu pomocí jazyka C# Příklad použití spravovaných identit pro koncový bod REST prostředků Azure z klienta jazyka C#
Získání tokenu pomocí Javy Příklad použití spravovaných identit pro koncový bod REST prostředků Azure z klienta Java
Získání tokenu pomocí Jazyka Go Příklad použití spravovaných identit pro koncový bod REST prostředků Azure z klienta Go
Získání tokenu pomocí PowerShellu Příklad použití spravovaných identit pro koncový bod REST prostředků Azure z klienta PowerShellu
Získání tokenu pomocí CURL Příklad použití spravovaných identit pro koncový bod REST prostředků Azure z klienta Bash/CURL
Zpracování ukládání tokenů do mezipaměti Pokyny pro zpracování přístupových tokenů s vypršenou platností
Zpracování chyb Pokyny pro zpracování chyb HTTP vrácených ze spravovaných identit pro koncový bod tokenu tokenu prostředků Azure
ID prostředků pro služby Azure Kde získat ID prostředků pro podporované služby Azure

Získání tokenu pomocí protokolu HTTP

Základní rozhraní pro získání přístupového tokenu je založené na rest, takže je přístupné pro všechny klientské aplikace spuštěné na virtuálním počítači, které můžou volat HTTP REST. Tento přístup se podobá programovacímu modelu Microsoft Entra, s výjimkou toho, že klient používá koncový bod na virtuálním počítači (vs. koncový bod Microsoft Entra).

Ukázkový požadavek s využitím koncového bodu Azure Instance Metadata Service (IMDS) (doporučeno)::

GET 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/' HTTP/1.1 Metadata: true
Element (Prvek) Popis
GET Příkaz HTTP označující, že chcete načíst data z koncového bodu. V tomto případě přístupový token OAuth.
http://169.254.169.254/metadata/identity/oauth2/token Spravované identity pro koncový bod prostředků Azure pro službu Instance Metadata Service.
api-version Parametr řetězce dotazu označující verzi rozhraní API pro koncový bod IMDS. Použijte verzi 2018-02-01 rozhraní API nebo vyšší.
resource Parametr řetězce dotazu označující identifikátor URI ID aplikace cílového prostředku. Zobrazí se také v aud deklaraci identity vydaného tokenu (cílová skupina). Tento příklad požaduje token pro přístup k Azure Resource Manageru, který má identifikátor URI https://management.azure.com/ID aplikace .
Metadata Pole hlavičky požadavku HTTP vyžadované spravovanými identitami. Tyto informace se používají jako zmírnění rizik proti útokům SSRF (SSRF) na straně serveru. Tato hodnota musí být nastavena na hodnotu true , ve všech malých písmenech.
object_id (Volitelné) Parametr řetězce dotazu označující object_id spravované identity, pro kterou chcete token. Vyžaduje se, pokud má váš virtuální počítač více spravovaných identit přiřazených uživatelem.
client_id (Volitelné) Parametr řetězce dotazu označující client_id spravované identity, pro kterou chcete token získat. Vyžaduje se, pokud má váš virtuální počítač více spravovaných identit přiřazených uživatelem.
msi_res_id (Volitelné) Parametr řetězce dotazu označující msi_res_id (ID prostředku Azure) spravované identity, pro kterou chcete token získat. Vyžaduje se, pokud má váš virtuální počítač více spravovaných identit přiřazených uživatelem.

Ukázková odpověď:

HTTP/1.1 200 OK
Content-Type: application/json
{
  "access_token": "eyJ0eXAi...",
  "refresh_token": "",
  "expires_in": "3599",
  "expires_on": "1506484173",
  "not_before": "1506480273",
  "resource": "https://management.azure.com/",
  "token_type": "Bearer"
}
Element (Prvek) Popis
access_token Požadovaný přístupový token. Při volání zabezpečeného rozhraní REST API se token vloží do Authorization pole hlavičky požadavku jako "nosný" token, který rozhraní API umožní ověřit volajícího.
refresh_token Spravované identity pro prostředky Azure se nepoužívají.
expires_in Početsekundch Čas vystavení najdete v deklaraci identity tokenu iat .
expires_on Časový rozsah, kdy vyprší platnost přístupového tokenu. Datum je reprezentováno jako počet sekund od "1970-01-01T0:0:0Z UTC" (odpovídá deklaraci tokenu exp ).
not_before Časový rozsah, kdy se přístupový token projeví, a lze ho přijmout. Datum je reprezentováno jako počet sekund od "1970-01-01T0:0:0Z UTC" (odpovídá deklaraci tokenu nbf ).
resource Prostředek, pro který byl požadován přístupový token, který odpovídá parametru resource řetězce dotazu požadavku.
token_type Typ tokenu, což je přístupový token "Nosný", což znamená, že prostředek může udělit přístup k nosné tomuto tokenu.

Získání tokenu pomocí klientské knihovny identit Azure

Použití klientské knihovny identit Azure je doporučeným způsobem použití spravovaných identit. Všechny sady Sdk Azure jsou integrované s knihovnou Azure.Identity , která poskytuje podporu pro DefaultAzureCredential. Tato třída usnadňuje používání spravovaných identit se sadami Azure SDK.Víc se uč

  1. Nainstalujte balíček Azure.Identity a další požadované balíčky knihovny Azure SDK, například Azure.Security.KeyVault.Secrets.

  2. Použijte níže uvedený ukázkový kód. Nemusíte se starat o získání tokenů. Klienty Sady Azure SDK můžete používat přímo. Kód ukazuje, jak token získat, pokud potřebujete.

    using Azure.Core;
    using Azure.Identity;
    
    string userAssignedClientId = "<your managed identity client Id>";
    var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions { ManagedIdentityClientId = userAssignedClientId });
    var accessToken = credential.GetToken(new TokenRequestContext(new[] { "https://vault.azure.net" }));
    // To print the token, you can convert it to string 
    String accessTokenString = accessToken.Token.ToString();
    
    //You can use the credential object directly with Key Vault client.     
    var client = new SecretClient(new Uri("https://myvault.vault.azure.net/"), credential);
    

Získání tokenu pomocí knihovny Microsoft.Azure.Services.AppAuthentication pro .NET

Pro aplikace a funkce .NET je nejjednodušší způsob práce se spravovanými identitami pro prostředky Azure prostřednictvím balíčku Microsoft.Azure.Services.AppAuthentication. Tato knihovna vám také umožní otestovat kód místně na vývojovém počítači. Kód můžete otestovat pomocí uživatelského účtu ze sady Visual Studio, Azure CLI nebo integrovaného ověřování Active Directory. Další informace o místních možnostech vývoje v této knihovně najdete v referenčních informacích k Microsoft.Azure.Services.AppAuthentication. V této části se dozvíte, jak začít s knihovnou v kódu.

  1. Přidejte do aplikace odkazy na balíčky NuGet Microsoft.Azure.Services.AppAuthentication a Microsoft.Azure.KeyVault .

  2. Do aplikace přidejte následující kód:

    using Microsoft.Azure.Services.AppAuthentication;
    using Microsoft.Azure.KeyVault;
    // ...
    var azureServiceTokenProvider = new AzureServiceTokenProvider();
    string accessToken = await azureServiceTokenProvider.GetAccessTokenAsync("https://management.azure.com/");
    // OR
    var kv = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
    

Další informace o Microsoft.Azure.Services.AppAuthentication a operacích, které zveřejňuje, najdete v referenčních informacích k Microsoft.Azure.Services.AppAuthentication a app Service a KeyVault se spravovanými identitami pro prostředky Azure v ukázce .NET.

Získání tokenu pomocí jazyka C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Web.Script.Serialization; 

// Build request to acquire managed identities for Azure resources token
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/");
request.Headers["Metadata"] = "true";
request.Method = "GET";

try
{
    // Call /token endpoint
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();

    // Pipe response Stream to a StreamReader, and extract access token
    StreamReader streamResponse = new StreamReader(response.GetResponseStream()); 
    string stringResponse = streamResponse.ReadToEnd();
    JavaScriptSerializer j = new JavaScriptSerializer();
    Dictionary<string, string> list = (Dictionary<string, string>) j.Deserialize(stringResponse, typeof(Dictionary<string, string>));
    string accessToken = list["access_token"];
}
catch (Exception e)
{
    string errorText = String.Format("{0} \n\n{1}", e.Message, e.InnerException != null ? e.InnerException.Message : "Acquire token failed");
}

Získání tokenu pomocí Javy

Pomocí této knihovny JSON načtěte token pomocí Javy.

import java.io.*;
import java.net.*;
import com.fasterxml.jackson.core.*;
 
class GetMSIToken {
    public static void main(String[] args) throws Exception {
 
        URL msiEndpoint = new URL("http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/");
        HttpURLConnection con = (HttpURLConnection) msiEndpoint.openConnection();
        con.setRequestMethod("GET");
        con.setRequestProperty("Metadata", "true");
 
        if (con.getResponseCode()!=200) {
            throw new Exception("Error calling managed identity token endpoint.");
        }
 
        InputStream responseStream = con.getInputStream();
 
        JsonFactory factory = new JsonFactory();
        JsonParser parser = factory.createParser(responseStream);
 
        while(!parser.isClosed()){
            JsonToken jsonToken = parser.nextToken();
 
            if(JsonToken.FIELD_NAME.equals(jsonToken)){
                String fieldName = parser.getCurrentName();
                jsonToken = parser.nextToken();
 
                if("access_token".equals(fieldName)){
                    String accesstoken = parser.getValueAsString();
                    System.out.println("Access Token: " + accesstoken.substring(0,5)+ "..." + accesstoken.substring(accesstoken.length()-5));
                    return;
                }
            }
        }
    }
}

Získání tokenu pomocí Jazyka Go

package main

import (
  "fmt"
  "io/ioutil"
  "net/http"
  "net/url"
  "encoding/json"
)

type responseJson struct {
  AccessToken string `json:"access_token"`
  RefreshToken string `json:"refresh_token"`
  ExpiresIn string `json:"expires_in"`
  ExpiresOn string `json:"expires_on"`
  NotBefore string `json:"not_before"`
  Resource string `json:"resource"`
  TokenType string `json:"token_type"`
}

func main() {
    
    // Create HTTP request for a managed services for Azure resources token to access Azure Resource Manager
    var msi_endpoint *url.URL
    msi_endpoint, err := url.Parse("http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01")
    if err != nil {
      fmt.Println("Error creating URL: ", err)
      return 
    }
    msi_parameters := msi_endpoint.Query()
    msi_parameters.Add("resource", "https://management.azure.com/")
    msi_endpoint.RawQuery = msi_parameters.Encode()
    req, err := http.NewRequest("GET", msi_endpoint.String(), nil)
    if err != nil {
      fmt.Println("Error creating HTTP request: ", err)
      return 
    }
    req.Header.Add("Metadata", "true")

    // Call managed services for Azure resources token endpoint
    client := &http.Client{}
    resp, err := client.Do(req) 
    if err != nil{
      fmt.Println("Error calling token endpoint: ", err)
      return
    }

    // Pull out response body
    responseBytes,err := ioutil.ReadAll(resp.Body)
    defer resp.Body.Close()
    if err != nil {
      fmt.Println("Error reading response body : ", err)
      return
    }

    // Unmarshall response body into struct
    var r responseJson
    err = json.Unmarshal(responseBytes, &r)
    if err != nil {
      fmt.Println("Error unmarshalling the response:", err)
      return
    }

    // Print HTTP response and marshalled response body elements to console
    fmt.Println("Response status:", resp.Status)
    fmt.Println("access_token: ", r.AccessToken)
    fmt.Println("refresh_token: ", r.RefreshToken)
    fmt.Println("expires_in: ", r.ExpiresIn)
    fmt.Println("expires_on: ", r.ExpiresOn)
    fmt.Println("not_before: ", r.NotBefore)
    fmt.Println("resource: ", r.Resource)
    fmt.Println("token_type: ", r.TokenType)
}

Získání tokenu pomocí PowerShellu

Následující příklad ukazuje použití spravovaných identit pro koncový bod REST prostředků Azure z klienta PowerShellu do:

  1. Získání přístupového tokenu
  2. Přístupový token použijte k volání rozhraní REST API Azure Resource Manageru a získání informací o virtuálním počítači. Nezapomeňte nahradit ID předplatného, název skupiny prostředků a název virtuálního počítače , <SUBSCRIPTION-ID><RESOURCE-GROUP>a <VM-NAME>v uvedeném pořadí.
Invoke-WebRequest -Uri 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fmanagement.azure.com%2F' -Headers @{Metadata="true"}

Příklad analýzy přístupového tokenu z odpovědi:

# Get an access token for managed identities for Azure resources
$response = Invoke-WebRequest -Uri 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fmanagement.azure.com%2F' `
                              -Headers @{Metadata="true"}
$content =$response.Content | ConvertFrom-Json
$access_token = $content.access_token
echo "The managed identities for Azure resources access token is $access_token"

# Use the access token to get resource information for the VM
$vmInfoRest = (Invoke-WebRequest -Uri 'https://management.azure.com/subscriptions/<SUBSCRIPTION-ID>/resourceGroups/<RESOURCE-GROUP>/providers/Microsoft.Compute/virtualMachines/<VM-NAME>?api-version=2017-12-01' -Method GET -ContentType "application/json" -Headers @{ Authorization ="Bearer $access_token"}).content
echo "JSON returned from call to get VM info:"
echo $vmInfoRest

Získání tokenu pomocí CURL

curl 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fmanagement.azure.com%2F' -H Metadata:true -s

Příklad analýzy přístupového tokenu z odpovědi:

response=$(curl 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fmanagement.azure.com%2F' -H Metadata:true -s)
access_token=$(echo $response | python -c 'import sys, json; print (json.load(sys.stdin)["access_token"])')
echo The managed identities for Azure resources access token is $access_token

Ukládání tokenů do mezipaměti

Spravované identity subsystému ukládají tokeny do mezipaměti, ale přesto doporučujeme implementovat ukládání tokenů do mezipaměti ve vašem kódu. Měli byste se připravit na scénáře, ve kterých prostředek indikuje, že platnost tokenu vypršela.

On-the-wire volání do Výsledku ID Microsoft Entra pouze v případech, kdy:

  • K chybě mezipaměti dochází kvůli chybějícímu tokenu ve spravovaných identitách pro mezipaměť subsystému prostředků Azure.
  • Platnost tokenu v mezipaměti vypršela.

Zpracování chyb

Koncové body spravovaných identit signalizují chyby prostřednictvím pole stavového kódu hlavičky zprávy http jako chyby 4xx nebo 5xx:

Kód stavu Důvod chyby Zpracování
404 Nenalezena. Koncový bod IMDS se aktualizuje. Zkuste to znovu s exponenciálním zpochybněním. Prohlédnou si následující doprovodné materiály.
410 IMDS prochází aktualizacemi IMDS bude k dispozici do 70 sekund.
429 Příliš mnoho požadavků. Dosáhlo se limitu omezení IMDS. Zkuste to znovu s exponenciálním zpochybněním. Prohlédnou si následující doprovodné materiály.
Chyba 4xx v požadavku. Jeden nebo více parametrů požadavku bylo nesprávné. Zkuste to znovu. Další informace najdete v podrobnostech o chybě. Chyby 4xx jsou chyby v době návrhu.
5xx Přechodná chyba ze služby. Spravované identity pro subsystém prostředků Azure nebo ID Microsoft Entra vrátily přechodnou chybu. Po čekání alespoň na 1 sekundu je bezpečné to zkusit znovu. Pokud to zkusíte příliš rychle nebo příliš často, IMDS nebo Microsoft Entra ID může vrátit chybu limitu rychlosti (429).
timeout Koncový bod IMDS se aktualizuje. Zkuste to znovu s exponenciálním zpochybněním. Prohlédnou si následující doprovodné materiály.

Pokud dojde k chybě, odpovídající text odpovědi HTTP obsahuje JSON s podrobnostmi o chybě:

Element (Prvek) Popis
chyba Identifikátor chyby.
error_description Podrobný popis chyby Popisy chyb se můžou kdykoli změnit. Nezapisujte kód, který se větví na základě hodnot v popisu chyby.

Referenční informace k odpovědi HTTP

Tato část dokumentuje možné odpovědi na chyby. Stav "200 OK" je úspěšná odpověď a přístupový token je součástí kódu JSON odpovědi v elementu access_token.

Stavový kód Chyba Popis chyby Řešení
400 – Chybný požadavek invalid_resource AADSTS50001: Aplikace s názvem <URI> nebyla v tenantovi s názvem <TENANT-ID> nalezena. Tato zpráva ukazuje, jestli správce tenanta nenainstaloval aplikaci nebo k ní žádný uživatel tenanta neschoval souhlas. Možná jste odeslali žádost o ověření nesprávnému tenantovi.\ (jenom Linux)
400 – Chybný požadavek bad_request_102 Požadovaná hlavička metadat není zadaná. Metadata V požadavku chybí pole hlavičky požadavku nebo je nesprávně naformátované. Hodnota musí být zadána jako true, ve všech malých písmenech. Příklad najdete v části Ukázka požadavku v předchozí části REST.
401 – Neautorizováno unknown_source Neznámý identifikátor URI zdroje <> Ověřte, že je identifikátor URI požadavku HTTP GET správně naformátovaný. Část scheme:host/resource-path musí být zadána jako http://localhost:50342/oauth2/token. Příklad najdete v části Ukázka požadavku v předchozí části REST.
invalid_request Požadavek chybí povinný parametr, obsahuje neplatnou hodnotu parametru, obsahuje parametr více než jednou nebo je jinak poškozený.
unauthorized_client Klient nemá autorizaci k vyžádání přístupového tokenu pomocí této metody. Příčinou požadavku na virtuálním počítači, který nemá spravované identity pro prostředky Azure správně nakonfigurované Pokud potřebujete pomoc s konfigurací virtuálního počítače, přečtěte si téma Konfigurace spravovaných identit pro prostředky Azure na virtuálním počítači pomocí webu Azure Portal .
access_denied Vlastník prostředku nebo autorizační server žádost zamítl.
unsupported_response_type Autorizační server nepodporuje získání přístupového tokenu pomocí této metody.
invalid_scope Požadovaný obor je neplatný, neznámý nebo poškozený.
Chyba „500 Internal server error“ neznámé Nepodařilo se načíst token ze služby Active Directory. Podrobnosti najdete v protokolech v <cestě k souboru.> Ověřte, že virtuální počítač má povolené spravované identity pro prostředky Azure. Pokud potřebujete pomoc s konfigurací virtuálního počítače, přečtěte si téma Konfigurace spravovaných identit pro prostředky Azure na virtuálním počítači pomocí webu Azure Portal .

Ověřte také, že je identifikátor URI požadavku HTTP GET správně naformátovaný, zejména identifikátor URI prostředku zadaný v řetězci dotazu. Podívejte se na ukázkovou žádost v předchozí části REST, například služby Azure, které podporují ověřování Microsoft Entra pro seznam služeb a jejich id příslušných prostředků.

Důležité

  • IMDS není určeno k použití za proxy serverem a není to podporováno. Příklady obejití proxy serverů najdete v ukázkách metadat služby Azure Instance.

Pokyny k opakování

Pokud se zobrazí kód chyby 404, 429 nebo 5xx , doporučujeme to zopakovat (viz zpracování chyb výše). Pokud se zobrazí chyba 410, znamená to, že IMDS prochází aktualizacemi a bude k dispozici maximálně za 70 sekund.

Omezení omezení se vztahují na počet volání provedených v koncovém bodu IMDS. Při překročení prahové hodnoty omezování limituje koncový bod IMDS všechny další požadavky, zatímco omezení platí. Během tohoto období koncový bod IMDS vrátí stavový kód HTTP 429 (Příliš mnoho požadavků) a požadavky selžou.

Pro opakování doporučujeme následující strategii:

Strategie opakování Settings Hodnoty Jak to funguje
ExponentialBackoff Počet opakování
Min back-off
Max back-off
Delta back-off
První rychlé opakování
5
0 s
60 s
2 s
false (nepravda)
Pokus 1 – zpoždění 0 s
Pokus 2 – zpoždění ~2 s
Pokus 3 – zpoždění ~6 s
Pokus 4 – zpoždění ~14 s
Pokus 5 – zpoždění ~30 s

ID prostředků pro služby Azure

Seznam prostředků, které podporují spravované identity, najdete v tématu Služby Azure s podporou spravovaných identit.

Další kroky