Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Управляемые удостоверения для ресурсов Azure предоставляют службам Azure автоматически управляемую идентичность в Microsoft Entra ID. Это удостоверение можно использовать для проверки подлинности в любой службе, которая поддерживает аутентификацию Microsoft Entra, без использования учетных данных в коде.
В этой статье приведены различные примеры кода и скриптов для получения токенов. Он также содержит рекомендации по обработке истечения срока действия маркера и ошибок HTTP.
Предпосылки
- Если вы не знакомы с функцией управляемых удостоверений для ресурсов Azure, см. этот обзор. Если у вас нет учетной записи Azure, зарегистрируйтесь для получения бесплатной учетной записи, прежде чем продолжить.
Если вы планируете использовать примеры Azure PowerShell в этой статье, обязательно установите последнюю версию Azure PowerShell.
Это важно
- Весь пример кода или скрипта в этой статье предполагает, что клиент работает на виртуальной машине с управляемыми удостоверениями для ресурсов Azure. Используйте функцию "Подключиться" виртуальной машины на портале Azure для удаленного подключения к виртуальной машине. Дополнительные сведения о включении управляемых удостоверений для ресурсов Azure на виртуальной машине см. в статье "Настройка управляемых удостоверений для ресурсов Azure на виртуальной машине" с помощью портала Azure или одной из статей вариантов (с помощью PowerShell, CLI, шаблона или пакета SDK Azure).
Это важно
- Граница безопасности управляемых идентификаторов для ресурсов Azure — это тот ресурс, где используется данный идентификатор. Весь код и скрипты, работающие на виртуальной машине, могут запрашивать и извлекать токены для любых доступных на ней управляемых удостоверений.
Обзор
Клиентское приложение может запросить токен доступа только для приложений, чтобы получить доступ к указанному ресурсу. Маркер основан на управляемых удостоверениях для субъекта-службы ресурсов Azure. Таким образом, клиенту не требуется получать токен доступа в рамках собственного служебного принципала. Данный токен подходит для использования в качестве токена-носителя в вызовах между службами, требующих учетных данных клиента.
| Ссылка | Описание |
|---|---|
| Получение маркера с помощью HTTP | Сведения о протоколе для управляемых удостоверений для конечной точки токена ресурсов Azure |
| Получение токена с помощью Azure.Identity | Пример использования управляемых удостоверений для REST API конечной точки ресурсов Azure в приложении на C# с библиотекой Azure.Identity |
| Получение маркера с помощью C# | Пример использования управляемых идентификаторов для REST конечной точки ресурсов Azure из клиента на C# с использованием HttpClient |
| Получение токена с помощью Java | Пример использования управляемых идентификаторов для REST-конечной точки Azure с помощью Java-клиента |
| Получение маркера с помощью Go | Пример использования управляемых удостоверений для REST API конечной точки ресурсов Azure из клиента на языке Go |
| Получение токена с помощью PowerShell | Пример того, как использовать управляемые удостоверения для REST-конечной точки ресурсов Azure из клиента PowerShell |
| Получите токен с помощью CURL | Пример использования управляемых удостоверений для конечной точки REST ресурсов Azure с клиента Bash/CURL |
| Обработка кэширования токенов | Руководство по обработке маркеров доступа с истекшим сроком действия |
| обработка ошибок | Руководство по обработке ошибок HTTP, возвращаемых из управляемых удостоверений для конечной точки маркера ресурсов Azure |
| Идентификаторы ресурсов для служб Azure | Где получить идентификаторы ресурсов для поддерживаемых служб Azure |
Получение маркера с помощью HTTP
Базовый интерфейс для получения маркера доступа основан на REST, что делает его доступным для любого клиентского приложения, работающего на виртуальной машине, которая может выполнять http-вызовы REST. Такой подход аналогичен модели программирования Microsoft Entra, за исключением того, что клиент использует конечную точку на виртуальной машине вместо конечной точки Microsoft Entra.
Пример запроса с помощью конечной точки службы метаданных экземпляра Azure (IMDS) (рекомендуется):
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
| Элемент | Описание |
|---|---|
GET |
HTTP-команда, указывающая, что необходимо извлечь данные из конечной точки. В этом случае используется маркер доступа OAuth. |
http://169.254.169.254/metadata/identity/oauth2/token |
Управляемые удостоверения для службы метаданных экземпляров являются точкой доступа к ресурсам Azure. |
api-version |
Параметр строки запроса, указывающий версию API для конечной точки IMDS. Используйте версию API 2018-02-01 или более позднюю версию. |
resource |
Параметр строки запроса, указывающий URI идентификатора приложения целевого ресурса. Он также отображается в aud утверждении (аудитории) выданного маркера. В этом примере запрашивается токен для доступа к Azure Resource Manager, у которого URI идентификатора приложения https://management.azure.com/. |
Metadata |
Поле заголовка HTTP-запроса, необходимое для управляемых удостоверений. Эта информация используется для защиты от атак подделки запросов на стороне сервера (SSRF). Это значение должно иметь значение true, в любом нижнем регистре. |
object_id |
(Необязательно) Параметр строки запроса, указывающий object_id управляемой идентичности, для которой вы хотите получить токен. Обязательно, если у виртуальной машины есть несколько управляемых удостоверений, назначаемых пользователем. |
client_id |
(Необязательно) Параметр строки запроса, указывающий client_id управляемого удостоверения, для которого вы хотите получить токен. Обязательно, если у виртуальной машины есть несколько управляемых удостоверений, назначаемых пользователем. |
msi_res_id |
(Необязательно) Параметр строки запроса, указывающий msi_res_id (идентификатор ресурса Azure) управляемой учетной записи, для которой требуется токен. Обязательно, если у виртуальной машины есть несколько управляемых удостоверений, назначаемых пользователем. |
Пример ответа:
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"
}
| Элемент | Описание |
|---|---|
access_token |
Запрашиваемый маркер доступа. При вызове защищенного REST API токен внедряется в Authorization поле заголовка запроса в качестве токена типа Bearer, позволяя API аутентифицировать вызывающего пользователя. |
refresh_token |
Не используется управляемыми удостоверениями для ресурсов Azure. |
expires_in |
Количество секунд, в течение которых токен доступа остается действительным, начиная с момента его выдачи и до истечения срока действия. Время выдачи можно найти в заявке iat токена. |
expires_on |
Интервал времени, когда срок действия маркера доступа истекает. Дата представлена в виде количества секунд от "1970-01-01T0:0Z UTC" (соответствует утверждению токена exp). |
not_before |
Интервал времени, когда маркер доступа вступает в силу, и его можно принять. Дата представлена в виде количества секунд от "1970-01-01T0:0Z UTC" (соответствует утверждению токена nbf). |
resource |
Ресурс, для которого запрашивается маркер доступа, соответствующий resource параметру строки запроса. |
token_type |
Тип токена, который является токеном доступа типа "Bearer", что означает, что ресурс может предоставить доступ обладателю этого токена. |
Получение токена с помощью клиентской библиотеки удостоверений Azure
Рекомендуется использовать клиентскую библиотеку удостоверений Azure для управления удостоверениями. Все пакеты SDK Azure интегрированы с библиотекой Azure.Identity , которая обеспечивает поддержку DefaultAzureCredential. Этот класс упрощает использование управляемых удостоверений в SDK Azure.Подробнее
Установите пакет Azure.Identity и другие необходимые пакеты библиотеки Пакета SDK Azure, например Azure.Security.KeyVault.Secret.
Используйте приведенный ниже пример кода. Вам не нужно беспокоиться о получении токенов. Вы можете напрямую использовать клиенты azure SDK. Код предназначен для демонстрации того, как получить маркер, если вам нужно.
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);
Получите токен с помощью 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);
Получение токена с помощью Java
Используйте эту библиотеку JSON для получения токена с помощью 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;
}
}
}
}
}
Получение токена с использованием 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)
}
Получение токена с помощью PowerShell
В следующем примере показано, как использовать управляемые удостоверения для REST-эндпоинта ресурсов Azure с клиента PowerShell:
- Получение токена доступа.
- Используйте маркер доступа для вызова REST API Azure Resource Manager и получения сведений о виртуальной машине. Обязательно замените идентификатор подписки, имя группы ресурсов и имя виртуальной машины на
<SUBSCRIPTION-ID>,<RESOURCE-GROUP>и<VM-NAME>соответственно.
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"}
Пример разбора маркера доступа из ответа:
# 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)"
Получите токен с помощью 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
Пример разбора маркера доступа из ответа:
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
Кэширование маркеров
Подсистема управляемых удостоверений кэширует токены, но мы по-прежнему рекомендуем реализовать кэширование токенов в коде. Необходимо подготовиться к сценариям, когда ресурс указывает, что срок действия маркера истек.
Сетевые вызовы к Microsoft Entra ID выполняются только в следующих случаях:
- Промах кэша происходит из-за отсутствия токена в кэше подсистемы управляемых идентичностей для ресурсов Azure.
- Срок действия кэшированного токена истек.
Обработка ошибок
Конечная точка управляемых удостоверений сигнализирует об ошибках через поле кода состояния заголовка сообщения HTTP в виде ошибок 4xx или 5xx:
| Код состояния | Причина ошибки | Как справляться |
|---|---|---|
| 404. Не найдено. | Точка подключения IMDS находится в процессе обновления. | Повторите попытку с экспоненциальной задержкой. См. инструкции ниже. |
| 410 | IMDS проходит через обновления | IMDS будет доступен в течение 70 секунд |
| 429 — слишком много запросов | Достигнуто ограничение пропускной способности IMDS. | Повторите попытку с экспоненциальной задержкой. См. инструкции ниже. |
| Ошибка 4xx в запросе. | Один или несколько параметров запроса неверные. | Не пытайтесь снова. Для получения дополнительной информации просмотрите сведения об ошибке. Ошибки 4xx — это ошибки времени разработки. |
| 5xx Временная ошибка сервиса. | Управляемые удостоверения подсистемы ресурсов Azure или Microsoft Entra ID вернули временную ошибку. | Это безопасно повторить после ожидания по крайней мере 1 секунды. Если вы слишком быстро или слишком часто повторите попытку, IMDS и /или идентификатор Microsoft Entra может вернуть ошибку ограничения скорости (429). |
| время ожидания истекло | Точка подключения IMDS находится в процессе обновления. | Повторите попытку с экспоненциальной задержкой. См. инструкции позже. |
Если возникает ошибка, соответствующий текст ответа HTTP содержит JSON с подробными сведениями об ошибке:
| Элемент | Описание |
|---|---|
| ошибка | Идентификатор ошибки. |
| описание ошибки | Подробное описание ошибки. Описания ошибок могут в любое время измениться. Не записывайте код, который ветвляется на основе значений в описании ошибки. |
Справочник по HTTP-ответам
В этом разделе описаны возможные ответы на ошибки. Состояние "200 ОК" — это успешный ответ, и маркер доступа содержится в тексте ответа JSON в элементе access_token.
| Код состояния | Ошибка | Описание ошибки | Решение |
|---|---|---|---|
| 400 Недопустимый запрос | неверный_ресурс | AADSTS50001: приложение с именем <URI> не найдено в клиенте с именем <TENANT-ID>. Это сообщение отображается, если администратор арендатора не установил приложение или ни один пользователь арендатора не дал на него согласие. Возможно, запрос проверки подлинности отправлен неправильному клиенту.\ | (только Для Linux) |
| 400 Недопустимый запрос | bad_request_102 | Обязательный заголовок метаданных не указан |
Metadata Поле заголовка запроса отсутствует в запросе или отформатировано неправильно. Значение должно быть указано как trueв нижнем регистре. Пример запроса см. в предыдущем разделе REST. |
| 401 — не авторизовано | unknown_source | Неизвестный URI< источника> | Убедитесь, что URI ЗАПРОСА HTTP GET правильно отформатирован. Данный scheme:host/resource-path сегмент необходимо указать как http://localhost:50342/oauth2/token. Пример запроса см. в предыдущем разделе REST. |
| недействительный_запрос | Запрос отсутствует обязательный параметр, включает недопустимое значение параметра, включает параметр более одного раза или неправильно сформирован. | ||
| неавторизованный клиент | Клиент не имеет права запрашивать маркер доступа с помощью этого метода. | Вызвано запросом на виртуальной машине, которая неправильно настроена и не имеет управляемых удостоверений для ресурсов Azure. См. Конфигурация управляемых удостоверений для ресурсов Azure на виртуальной машине с использованием портала Azure если вам нужна помощь в настройке виртуальной машины. | |
| Доступ запрещен | Владельцы ресурсов или сервер авторизации отклонили запрос. | ||
| неподдерживаемый_тип_ответа | Сервер авторизации не поддерживает получение маркера доступа с помощью этого метода. | ||
| недопустимый_объем | Запрашиваемая область является недействительной, неизвестной или искаженной. | ||
| Ошибка внутреннего сервера 500 | неизвестно | Не удалось получить маркер из Active Directory. Дополнительные сведения см. в журналах в< пути файла> | Убедитесь, что виртуальная машина имеет управляемые удостоверения для ресурсов Azure. См. Конфигурация управляемых удостоверений для ресурсов Azure на виртуальной машине с использованием портала Azure если вам нужна помощь в настройке виртуальной машины. Кроме того, убедитесь, что URI ЗАПРОСА HTTP GET правильно отформатирован, особенно URI ресурса, указанного в строке запроса. Пример запроса см. в предыдущем разделе REST, например, или службы Azure, поддерживающие проверку подлинности Microsoft Entra , для списка служб и соответствующих идентификаторов ресурсов. |
Это важно
- IMDS не предназначен для использования через прокси-сервер и это не поддерживается. Примеры обхода прокси-серверов см. в примерах метаданных экземпляра Azure.
Руководство по повторной попытке
Повторите попытку при получении кода ошибки 404, 429 или 5xx (см. обработку ошибок). Если вы получаете ошибку 410, это означает, что IMDS проходит через обновления и будет доступен не более 70 секунд.
Ограничения регулирования применяются к количеству вызовов, выполненных в конечную точку IMDS. При превышении порогового значения регулирования конечная точка IMDS ограничивает любые дальнейшие запросы, пока ограничение действует. В течение этого периода конечная точка IMDS возвращает код состояния HTTP 429 ("Слишком много запросов"), а запросы завершаются сбоем.
Для повторных попыток рекомендуется использовать следующую стратегию:
| Стратегия повторных попыток | Настройки | Значения | Принцип работы |
|---|---|---|---|
| Экспоненциальная задержка | Счетчик повторов Минимальная задержка Максимальная задержка ожидания Отсрочка по Дельте Первая быстрая повторная попытка |
5 0 с 60 с 2 с неправда |
Попытка 1 — задержка 0 с Попытка 2 — задержка ~2 с Попытка 3 — задержка ~6 с Попытка 4 — задержка ~14 с Попытка 5 — задержка ~30 с |
Идентификаторы ресурсов для служб Azure
Ознакомьтесь со службами Azure с поддержкой управляемых удостоверений, чтобы узнать список ресурсов, поддерживающих управляемые удостоверения для ресурсов Azure.
Дальнейшие шаги
- Сведения о включении управляемых удостоверений для ресурсов Azure на виртуальной машине Azure см. в статье "Настройка управляемых удостоверений для ресурсов Azure" на виртуальной машине с помощью портала Azure.