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 är en funktion i Microsoft Entra-ID. Alla Azure-tjänster som stöder hanterade identiteter för Azure-resurser har sin egen tidslinje. Var noga med att kontrollera tillgänglighetsstatus för hanterade identiteter för din resurs och kända problem innan du börjar.
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 tokens förfallotid 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 ett 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" i Azure-portalen 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. Alla 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 åtkomsttoken för endast hanterad identitetsapp för åtkomst till en viss resurs. Token baseras på hanterade identiteter för Tjänstens huvudnamn för Azure-resurser. 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 ägartoken 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 Azure-resurstokenslutpunkt |
Hämta en token med hjälp av Azure.Identity | Hämta en token med hjälp av Azure.Identity-biblioteket |
Hämta en token med hjälp av biblioteket Microsoft.Azure.Services.AppAuthentication för .NET | Exempel på hur du använder biblioteket Microsoft.Azure.Services.AppAuthentication från en .NET-klient |
Hämta en token med C# | Exempel på hur du använder hanterade identiteter för Azure-resursers REST-slutpunkt från en C#-klient |
Hämta en token med Java | Exempel på hur du använder hanterade identiteter för Azure-resursers REST-slutpunkt från en Java-klient |
Hämta en token med Go | Exempel på hur du använder hanterade identiteter för Azure-resursers REST-slutpunkt från en Go-klient |
Hämta en token med PowerShell | Exempel på hur du använder hanterade identiteter för Azure-resursers REST-slutpunkt från en PowerShell-klient |
Hämta en token med CURL | Exempel på hur du använder hanterade identiteter för Azure-resursers REST-slutpunkt från en Bash/CURL-klient |
Hantera cachelagring av token | Vägledning för hantering av utgångna åtkomsttoken |
Felhantering | Vägledning för hantering av HTTP-fel som returneras från de hanterade identiteterna för Azure-resursers tokenslutpunkt |
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 som kan göra HTTP REST-anrop. Den här metoden liknar Microsoft Entra-programmeringsmodellen, förutom att klienten använder en slutpunkt på den virtuella datorn (jämfört med en Microsoft Entra-slutpunkt).
Exempelbegäran med hjälp av 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
Element | Description |
---|---|
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 |
De hanterade identiteterna för Azure-resursers slutpunkt för instansmetadatatjänsten. |
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. Det visas också i anspråket (målgruppen aud ) för den utfärdade token. I det här exemplet begärs en token för åtkomst till Azure Resource Manager, som har en app-ID-URI för https://management.azure.com/ . |
Metadata |
Ett http-begärandehuvudfält 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", i alla 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"
}
Element | Description |
---|---|
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 "ägartoken", 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 åtkomsttoken fortsätter att vara giltig, innan den upphör att gälla, från tidpunkten för utfärdandet. Tidpunkten för utfärdandet finns i tokens iat anspråk. |
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 |
Tidsintervallet 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 ägarnamnet för denna token. |
Hämta en token med azure-identitetsklientbiblioteket
Att använda Azure identity-klientbiblioteket är det rekommenderade sättet att använda hanterade identiteter. Alla Azure SDK:er är integrerade med Azure.Identity
biblioteket 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ära sig mer
Installera Azure.Identity-paketet och andra nödvändiga Azure SDK-bibliotekspaket, till exempel Azure.Security.KeyVault.Secrets.
Använd exempelkoden nedan. Du behöver inte oroa dig för att få token. Du kan använda Azure SDK-klienterna direkt. Koden är till för att visa hur du hämtar token, om du behöver det.
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);
Hämta en token med hjälp av biblioteket Microsoft.Azure.Services.AppAuthentication för .NET
För .NET-program och -funktioner är det enklaste sättet att arbeta med hanterade identiteter för Azure-resurser via paketet Microsoft.Azure.Services.AppAuthentication. Med det här biblioteket kan du också testa koden lokalt på utvecklingsdatorn. Du kan testa koden med ditt användarkonto från Visual Studio, Azure CLI eller Active Directory Integrated Authentication. Mer information om lokala utvecklingsalternativ med det här biblioteket finns i referensen Microsoft.Azure.Services.AppAuthentication. Det här avsnittet visar hur du kommer igång med biblioteket i koden.
Lägg till referenser till NuGet-paketen Microsoft.Azure.Services.AppAuthentication och Microsoft.Azure.KeyVault i ditt program.
Lägg till följande kod i programmet:
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));
Mer information om Microsoft.Azure.Services.AppAuthentication och de åtgärder som exponeras finns i microsoft.Azure.Services.AppAuthentication-referensen och App Service och KeyVault med hanterade identiteter för Azure-resurser .NET-exempel.
Hämta en token med 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");
}
Hämta en token med Java
Använd det här JSON-biblioteket för att hämta en token med 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 de hanterade identiteterna för REST-slutpunkten för Azure-resurser från en PowerShell-klient till:
- Hämta en åtkomsttoken.
- Använd åtkomsttoken för att anropa ett Rest-API för Azure Resource Manager 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>
respektive<VM-NAME>
.
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"}
Exempel på hur du parsar åtkomsttoken från svaret:
# 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
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 The managed identities for Azure resources access token is $access_token
Cachelagring av token
Undersystemet för hanterade identiteter cachelagrar token, men vi rekommenderar ändå 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.
On-the-wire-anrop till Microsoft Entra ID-resultat endast när:
- Cachemissen inträffar på grund av att det inte finns någon token i de hanterade identiteterna för Undersystemcache för Azure-resurser.
- Den cachelagrade token har upphört att gälla.
Felhantering
Slutpunkten för hanterade identiteter signalerar fel via statuskodfältet i HTTP-svarsmeddelanderubriken, som antingen 4xx- eller 5xx-fel:
Statuskod | Felorsak | Hantera |
---|---|---|
404 Hittades inte. | IMDS-slutpunkten uppdateras. | Försök igen med exponentiell backoff. Se vägledningen nedan. |
410 | IMDS genomgår uppdateringar | IMDS kommer att vara tillgängligt inom 70 sekunder |
429 För många förfrågningar. | GRÄNSEN för IMDS-begränsning 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. Mer information finns i felinformationen. 4xx-fel är designtidsfel. |
5xx Tillfälligt fel från tjänsten. | De hanterade identiteterna för Azure-resursers 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). |
timeout | IMDS-slutpunkten uppdateras. | Försök igen med exponentiell backoff. Se vägledningen nedan. |
Om ett fel inträffar innehåller motsvarande HTTP-svarstext JSON med felinformationen:
Element | Description |
---|---|
fel | Felidentifierare. |
error_description | Utförlig beskrivning av felet. Felbeskrivningar kan ändras när som helst. Skriv inte kod som förgrenar baserat på värden i felbeskrivningen. |
HTTP-svarsreferens
I det här avsnittet beskrivs möjliga felsvar. Statusen "200 OK" är ett lyckat svar och åtkomsttoken finns i svarstexten JSON i access_token-elementet.
Statuskod | Fel | Felbeskrivning | Lösning |
---|---|---|---|
400 – Felaktig begäran | invalid_resource | 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 klient.\ | (Endast Linux) |
400 – Felaktig begäran | bad_request_102 | Obligatoriskt metadatahuvud har inte angetts | Metadata Antingen saknas fältet för begäranderubriken i din begäran eller så formateras det felaktigt. Värdet måste anges som true , i alla gemener. Se "Exempelbegäran" i föregående REST-avsnitt för ett exempel. |
401 – Ej behörig | unknown_source | Okänd käll-URI <> | Kontrollera att din HTTP GET-begärande-URI är korrekt formaterad. Delen scheme:host/resource-path måste anges som http://localhost:50342/oauth2/token . Se "Exempelbegäran" i föregående REST-avsnitt för ett exempel. |
invalid_request | Begäran saknar en obligatorisk parameter, innehåller ett ogiltigt parametervärde, innehåller en parameter mer än en gång eller på annat sätt är felaktigt. | ||
unauthorized_client | 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 korrekt konfigurerade. Se Konfigurera hanterade identiteter för Azure-resurser på en virtuell dator med hjälp av Azure-portalen om du behöver hjälp med VM-konfiguration. | |
access_denied | Resursägaren eller auktoriseringsservern nekade begäran. | ||
unsupported_response_type | Auktoriseringsservern stöder inte hämtning av en åtkomsttoken med den här metoden. | ||
invalid_scope | Det begärda omfånget är ogiltigt, okänt eller felaktigt. | ||
500 Internt serverfel | okänt | 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-portalen 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: n. |
Viktigt!
Vägledning för återförsök
Vi rekommenderar att du försöker igen om du får felkoden 404, 429 eller 5xx (se Felhantering ovan). Om du får ett 410-fel anger det att IMDS genomgår uppdateringar och kommer att vara tillgängligt om 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 är i kraft. Under den här perioden returnerar IMDS-slutpunkten HTTP-statuskoden 429 ("För många begäranden") och begäranden misslyckas.
För att försöka igen rekommenderar vi följande strategi:
Återförsöksstrategi | Inställningar | Värden | Hur det fungerar |
---|---|---|---|
ExponentialBackoff | Antal nya försök Min. backoff Max. backoff Deltabackoff Första snabba återförsöket |
5 0 sek. 60 sek. 2 sek. falskt |
Försök 1 – 0 sek. fördröjning Försök 2 – ~2 sek. fördröjning Försök 3 – ~6 sek. fördröjning Försök 4 – ~14 sek. fördröjning Försök 5 – ~30 sek. fördröjning |
Resurs-ID:t för Azure-tjänster
Se Azure Services 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
- Information om hur du aktiverar hanterade identiteter för Azure-resurser på en virtuell Azure-dator finns i Konfigurera hanterade identiteter för Azure-resurser på en virtuell dator med hjälp av Azure-portalen.