Dela via


Så här använder du hanterade identiteter för Azure-resurser på en virtuell Azure-dator för att hämta en åtkomsttoken

Hanterade identiteter för Azure-resurser ger Azure-tjänster en automatiskt hanterad identitet i Microsoft Entra ID. Du kan använda den här identiteten för att autentisera mot alla tjänster som har stöd för Microsoft Entra-autentisering, utan att behöva ha några autentiseringsuppgifter i koden.

Den här artikeln innehåller olika kod- och skriptexempel för tokenförvärv. Den innehåller också vägledning om hur du hanterar förfallodatum för token och HTTP-fel.

Förutsättningar

  • Om du inte känner till funktionen för hanterade identiteter för Azure-resurser kan du läsa igenom den här översikten. Om du inte har något Azure-konto registrerar du dig för ett kostnadsfritt konto innan du fortsätter.

Om du planerar att använda Azure PowerShell-exemplen i den här artikeln måste du installera den senaste versionen av Azure PowerShell.

Viktigt!

  • All exempelkod/skript i den här artikeln förutsätter att klienten körs på en virtuell dator med hanterade identiteter för Azure-resurser. Använd funktionen "Anslut" för den virtuella datorn i Azure Portal för att fjärransluta till den virtuella datorn. Mer information om hur du aktiverar hanterade identiteter för Azure-resurser på en virtuell dator finns i Konfigurera hanterade identiteter för Azure-resurser på en virtuell dator med hjälp av Azure-portalen eller någon av variantartiklarna (med Hjälp av PowerShell, CLI, en mall eller en Azure SDK).

Viktigt!

  • Säkerhetsgränsen för hanterade identiteter för Azure-resurser är den resurs där identiteten används. All kod/skript som körs på en virtuell dator kan begära och hämta token för alla hanterade identiteter som är tillgängliga på den.

Översikt

Ett klientprogram kan begära en appåtkomsttoken för hanterad identitet för att få åtkomst till en viss resurs. Token baseras på de hanterade identiteterna för Azure-resurstjänstens huvudnamn. Därför behöver klienten inte hämta en åtkomsttoken under sitt eget huvudnamn för tjänsten. Token är lämplig för användning som en bearer-token i tjänst-till-tjänst-anrop som kräver klientautentiseringsuppgifter.

Länk Beskrivning
Hämta en token med HTTP Protokollinformation för hanterade identiteter för slutpunkt för Azure-resurstoken
Hämta en token med hjälp av Azure.Identity Exempel på hur du använder hanterade identiteter för Azure-resursers REST-slutpunkt från en C#-klient med hjälp av Azure.Identity
Hämta en token med hjälp av C# Exempel på hur du använder hanterade identiteter för Azure-resursers REST-slutpunkt från en C#-klient med hjälp av HttpClient
Hämta en token med Java Exempel på användning av hanterade identiteter för REST-slutpunkt för Azure-resurser från en Java-klient
Hämta en token med Go Exempel på användning av hanterade identiteter för REST-slutpunkt för Azure-resurser från en Go-klient
Hämta en token med PowerShell Exempel på användning av hanterade identiteter för REST-slutpunkt för Azure-resurser från en PowerShell-klient
Hämta en token med CURL Exempel på användning av hanterade identiteter för REST-slutpunkt för Azure-resurser från en Bash/CURL-klient
Hantera cachelagring av token Vägledning för hantering av utgångna åtkomsttoken
Hantering av fel Vägledning för hantering av HTTP-fel som returneras från de hanterade identiteterna för tokenslutpunkten för Azure-resurser
Resurs-ID:t för Azure-tjänster Var du kan hämta resurs-ID:t för Azure-tjänster som stöds

Hämta en token med HTTP

Det grundläggande gränssnittet för att hämta en åtkomsttoken baseras på REST, vilket gör det tillgängligt för alla klientprogram som körs på den virtuella datorn och som kan göra HTTP REST-anrop. Den här metoden liknar programmeringsmodellen Microsoft Entra, förutom att klienten använder en slutpunkt på den virtuella datorn (jämfört med en Microsoft Entra-slutpunkt).

Exempelbegäran med IMDS-slutpunkten (Azure Instance Metadata Service) (rekommenderas):

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
Komponent Beskrivning
GET HTTP-verbet som anger att du vill hämta data från slutpunkten. I det här fallet en OAuth-åtkomsttoken.
http://169.254.169.254/metadata/identity/oauth2/token Slutpunkten för hanterade identiteter för Azure-resurser för tjänsten Instance Metadata.
api-version En frågesträngsparameter som anger API-versionen för IMDS-slutpunkten. Använd API-version 2018-02-01 eller senare.
resource En frågesträngsparameter som anger målresursens app-ID-URI. Den visas också i (målgrupps aud )anspråket för den utfärdade token. I det här exemplet begärs en token för att få åtkomst till Azure Resource Manager, som har en app-ID-URI på https://management.azure.com/.
Metadata Ett huvudfält för HTTP-begäran som krävs av hanterade identiteter. Den här informationen används som en åtgärd mot SSRF-attacker (Server Side Request Forgery). Det här värdet måste anges till "true" med gemener.
object_id (Valfritt) En frågesträngsparameter som anger object_id för den hanterade identitet som du vill ha token för. Krävs om den virtuella datorn har flera användartilldelade hanterade identiteter.
client_id (Valfritt) En frågesträngsparameter som anger client_id för den hanterade identitet som du vill ha token för. Krävs om den virtuella datorn har flera användartilldelade hanterade identiteter.
msi_res_id (Valfritt) En frågesträngsparameter som anger msi_res_id (Azure-resurs-ID) för den hanterade identitet som du vill ha token för. Krävs om den virtuella datorn har flera användartilldelade hanterade identiteter.

Exempelsvar:

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"
}
Komponent Beskrivning
access_token Den begärda åtkomsttoken. När du anropar ett skyddat REST API bäddas token in i Authorization fältet för begärandehuvud som en "bearer"-token, vilket gör att API:et kan autentisera anroparen.
refresh_token Används inte av hanterade identiteter för Azure-resurser.
expires_in Antalet sekunder som en åtkomsttoken är giltig innan den upphör att gälla, räknat från utfärdandet. Tidpunkten för utfärdandet finns i tokenets iat påstående.
expires_on Tidsintervallet när åtkomsttoken upphör att gälla. Datumet representeras som antalet sekunder från "1970-01-01T0:0:0Z UTC" (motsvarar tokens exp anspråk).
not_before Tidsspannet när åtkomsttoken börjar gälla och kan accepteras. Datumet representeras som antalet sekunder från "1970-01-01T0:0:0Z UTC" (motsvarar tokens nbf anspråk).
resource Resursen som åtkomsttoken begärdes för, som matchar frågesträngsparametern resource för begäran.
token_type Typen av token, som är en "Bearer"-åtkomsttoken, vilket innebär att resursen kan ge åtkomst till bäraren av denna token.

Hämta en token med hjälp av Azure Identity-klientbiblioteket

Att använda Azure Identity-klientbiblioteket är det rekommenderade sättet att använda hanterade identiteter. Alla Azure-SDK:er är integrerade med biblioteket Azure.Identity som ger stöd för DefaultAzureCredential. Den här klassen gör det enkelt att använda hanterade identiteter med Azure SDK:er.Läs mer

  1. Installera Azure.Identity-paketet och andra nödvändiga Azure SDK-bibliotekspaket, till exempel Azure.Security.KeyVault.Secrets.

  2. Använd exempelkoden nedan. Du behöver inte oroa dig för att få tokens. Du kan använda Azure SDK-klienterna direkt. Koden är till för att visa hur du får token, om du behöver.

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

Hämta en token med hjälp av C#

using System;
using System.Net.Http;
using Newtonsoft.Json.Linq;

// Construct HttpClient
var httpClient = new HttpClient
{
    DefaultRequestHeaders =
    {
        { "Metadata", Boolean.TrueString }
    }
};

// Construct URI to call
var resource = "https://management.azure.com/";
var uri = $"http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource={resource}";

// Make call
var response = await httpClient.GetAsync(uri);
try
{
    response.EnsureSuccessStatusCode();
}
catch (HttpRequestException)
{
    var error = await response.Content.ReadAsStringAsync();
    Console.WriteLine(error);
    throw;
}

// Parse response using Newtonsoft.Json
var content = await response.Content.ReadAsStringAsync();
var obj = JObject.Parse(content);
var accessToken = obj["access_token"];

Console.WriteLine(accessToken);

Hämta en token med Java

Använd det här JSON-biblioteket för att hämta en token med hjälp av Java.

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;
                }
            }
        }
    }
}

Hämta en token med 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)
}

Hämta en token med PowerShell

I följande exempel visas hur du använder hanterade identiteter för REST-slutpunkten för Azure-resurser från en PowerShell-klient för att:

  1. Hämta en åtkomsttoken.
  2. Använd åtkomsttoken för att anropa ett Azure Resource Manager REST API och få information om den virtuella datorn. Se till att ersätta ditt prenumerations-ID, resursgruppsnamn och namn på den virtuella datorn med <SUBSCRIPTION-ID>, <RESOURCE-GROUP><VM-NAME>och , respektive.
Invoke-RestMethod -Method GET -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"}

Exempel på hur du parsar åtkomsttoken från svaret:

# Get an access token for managed identities for Azure resources
$resource = 'https://management.azure.com'
$response = Invoke-RestMethod -Method GET `
                            -Uri "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=$resource" `
                            -Headers @{ Metadata="true" }
$accessToken = $response.access_token
Write-Host "Access token using a User-Assigned Managed Identity is $accessToken"

# Use the access token to get resource information for the VM
$secureToken = $accessToken | ConvertTo-SecureString -AsPlainText
$vmInfoRest = Invoke-RestMethod -Method GET `
                              -Uri 'https://management.azure.com/subscriptions/<SUBSCRIPTION-ID>/resourceGroups/<RESOURCE-GROUP>/providers/Microsoft.Compute/virtualMachines/<VM-NAME>?api-version=2017-12-01' `
                              -ContentType 'application/json' `
                              -Authentication Bearer `
                              -Token $secureToken
Write-Host "JSON returned from call to get VM info: $($vmInfoRest.content)"

Hämta en token med 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

Exempel på hur du parsar åtkomsttoken från svaret:

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 Access token using a User-Assigned Managed Identity is $access_token

Cachelagring av token

Undersystemet för hanterade identiteter cachelagrar token, men vi rekommenderar fortfarande att du implementerar cachelagring av token i koden. Du bör förbereda dig för scenarier där resursen anger att token har upphört att gälla.

Kabelanslutna anrop till Microsoft Entra ID resulterar endast när:

  • Cachemiss inträffar på grund av att det inte finns någon token i de hanterade identiteterna för cacheminnet för Azure-resursernas undersystem.
  • Den cachelagrade token har upphört att gälla.

Felhantering

Slutpunkten för hanterade identiteter signalerar fel via statuskodfältet i HTTP-svarsmeddelandehuvudet, som antingen 4xx- eller 5xx-fel:

Statuskod Felanledning Så här hanterar du
404 Hittades inte. IMDS-slutpunkten uppdateras. Försök igen med exponentiell backoff. Se vägledningen nedan.
410 IMDS håller på att uppdateras IMDS kommer att vara tillgängligt inom 70 sekunder
429 För många förfrågningar. IMDS: Gasspjällsgränsen har nåtts. Försök igen med exponentiell backoff. Se vägledningen nedan.
4xx Fel i begäran. En eller flera av begärandeparametrarna var felaktiga. Försök inte igen. Granska felen för mer information. 4xx-fel är designtidsfel.
5xx Tillfälligt fel från tjänst. De hanterade identiteterna för Azure-resurser, undersystem eller Microsoft Entra-ID returnerade ett tillfälligt fel. Det är säkert att försöka igen efter att ha väntat i minst 1 sekund. Om du försöker igen för snabbt eller för ofta kan IMDS och/eller Microsoft Entra ID returnera ett hastighetsbegränsningsfel (429).
uppnå tidsgräns IMDS-slutpunkten uppdateras. Försök igen med exponentiell backoff. Se vägledning senare.

Om ett fel inträffar innehåller motsvarande HTTP-svarstext JSON med felinformationen:

Komponent Beskrivning
fel Identifierare för fel.
felbeskrivning Utförlig beskrivning av felet. Felbeskrivningar kan ändras när som helst. Skriv inte kod som förgrenar sig baserat på värden i felbeskrivningen.

Referens för HTTP-svar

I det här avsnittet dokumenteras möjliga felsvar. Statusen "200 OK" är ett lyckat svar och åtkomsttoken finns i JSON-svarstexten i elementet access_token.

Statuskod Fel Felbeskrivning Lösning
400 Felaktig begäran ogiltig resurs AADSTS50001: Programmet med namnet <URI> hittades inte i klientorganisationen med namnet <TENANT-ID.> Det här meddelandet visar om klientadministratören inte har installerat programmet eller om ingen klientanvändare har samtyckt till det. Du kan ha skickat din autentiseringsbegäran till fel klientorganisation.\ (Endast Linux)
400 Felaktig begäran bad_request_102 Obligatorisk metadatarubrik har inte angetts Antingen saknas fältet för begärandehuvud Metadata i din begäran eller så är det felaktigt formaterat. Värdet måste anges som true, med gemener. Ett exempel finns i "Exempelbegäran" i föregående REST-avsnitt.
401 Inte auktoriserad unknown_source Okänd käll-URI<> Kontrollera att din HTTP GET-begärande-URI är korrekt formaterad. Andelen scheme:host/resource-path måste anges som http://localhost:50342/oauth2/token. Ett exempel finns i "Exempelbegäran" i föregående REST-avsnitt.
ogiltig_förfrågan Begäran saknar en obligatorisk parameter, innehåller ett ogiltigt parametervärde, innehåller en parameter mer än en gång eller är felaktig på annat sätt.
obehörig_klient Klienten har inte behörighet att begära en åtkomsttoken med den här metoden. Orsakas av en begäran på en virtuell dator som inte har hanterade identiteter för Azure-resurser som konfigurerats korrekt. Se Konfigurera hanterade identiteter för Azure-resurser på en virtuell dator med hjälp av Azure Portal om du behöver hjälp med VM-konfiguration.
åtkomst nekad Resursägaren eller auktoriseringsservern nekade begäran.
otillåten_svarstyp Auktoriseringsservern har inte stöd för att hämta en åtkomsttoken med den här metoden.
ogiltig_omfattning Det begärda omfånget är ogiltigt, okänt eller felaktigt formaterat.
500 Internt serverfel okänd Det gick inte att hämta token från Active Directory. Mer information finns i loggar i <filsökvägen> Kontrollera att den virtuella datorn har hanterade identiteter för Azure-resurser aktiverade. Se Konfigurera hanterade identiteter för Azure-resurser på en virtuell dator med hjälp av Azure Portal om du behöver hjälp med VM-konfiguration.

Kontrollera också att din HTTP GET-begärande-URI är korrekt formaterad, särskilt resurs-URI:n som anges i frågesträngen. Se "Exempelbegäran" i föregående REST-avsnitt för ett exempel, eller Azure-tjänster som stöder Microsoft Entra-autentisering för en lista över tjänster och deras respektive resurs-ID:t.

Viktigt!

Vägledning för återförsök

Försök igen om du får felkoden 404, 429 eller 5xx (se Felhantering). Om du får ett 410-fel indikerar det att IMDS går igenom uppdateringar och kommer att vara tillgängligt inom högst 70 sekunder.

Begränsningsgränser gäller för antalet anrop som görs till IMDS-slutpunkten. När tröskelvärdet för begränsning överskrids begränsar IMDS-slutpunkten eventuella ytterligare begäranden medan begränsningen gäller. Under den här perioden returnerar IMDS-slutpunkten HTTP-statuskoden 429 ("För många begäranden") och begärandena misslyckas.

För återförsök rekommenderar vi följande strategi:

Strategi för återförsök Inställningar Värden Hur det fungerar
Exponentiell återkoppling Antal nya försök
Minsta back-off
Maximal fördröjning
Delta-back-off
Första snabba återförsöket
5
0 sek
60 sek
2 sek
falskt
Försök 1 - fördröjning 0 sek
Försök 2 - fördröjning ~2 sek
Försök 3 - fördröjning ~6 sek
Försök 4 - fördröjning ~14 sek
Försök 5 - fördröjning ~30 sek

Resurs-ID:t för Azure-tjänster

Se Azure-tjänster med stöd för hanterade identiteter för en lista över resurser som stöder hanterade identiteter för Azure-resurser.

Nästa steg