После создания объекта клиентского приложения с его помощью можно получить токен, который затем будет использоваться для вызова веб-API.
Microsoft.Identity.Web добавляет методы расширения, которые предоставляют удобные службы для вызова Microsoft Graph или подчиненных веб-API. Эти методы подробно описаны в статье Веб-приложение, которое вызывает веб-API: вызов API. При использовании этих вспомогательных методов вам не нужно получать токен вручную.
Однако если вы хотите получить токен вручную, в следующем коде показан пример использования Microsoft.Identity.Web в контроллере Home для этой цели. Он вызывает Microsoft Graph с помощью REST API (вместо пакета SDK для Microsoft Graph). Как правило, вам не нужно получать маркер, необходимо создать заголовок авторизации, добавляемый в запрос. Чтобы получить заголовок авторизации, вы внедряете IAuthorizationHeaderProvider
службу путем внедрения зависимостей в конструктор контроллера (или конструктор страницы при использовании Blazor) и используете ее в действиях контроллера. Этот интерфейс содержит методы, которые создают строку, содержащую протокол (Bearer, Pop, ...) и токен. Чтобы получить заголовок авторизации для вызова API от имени пользователя, используйте (CreateAuthorizationHeaderForUserAsync
). Чтобы получить заголовок авторизации для вызова нижестоящего API от имени самого приложения, в сценарии управляющей программы используйте (CreateAuthorizationHeaderForAppAsync
).
Методы контроллера защищены атрибутом [Authorize]
, который гарантирует, что только прошедшие проверку подлинности вызовы могут использовать веб-API.
[Authorize]
public class MyApiController : Controller
{
/// <summary>
/// The web API will accept only tokens 1) for users, 2) that have the `access_as_user` scope for
/// this API.
/// </summary>
static readonly string[] scopeRequiredByApi = new string[] { "access_as_user" };
static readonly string[] scopesToAccessDownstreamApi = new string[] { "api://MyTodolistService/access_as_user" };
readonly IAuthorizationHeaderProvider authorizationHeaderProvider;
public MyApiController(IAuthorizationHeaderProvider authorizationHeaderProvider)
{
this.authorizationHeaderProvider = authorizationHeaderProvider;
}
[RequiredScopes(Scopes = scopesToAccessDownstreamApi)]
public IActionResult Index()
{
// Get an authorization header.
IAuthorizationHeaderProvider authorizationHeaderProvider = this.GetAuthorizationHeaderProvider();
string[] scopes = new string[]{"user.read"};
string authorizationHeader = await authorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(scopes);
return await callTodoListService(authorizationHeader);
}
}
Дополнительные сведения о методе callTodoListService
см. в статье Веб-API, который вызывает интерфейсы веб-API: вызов API.
Код для ASP.NET аналогичен коду, показанному для ASP.NET Core:
- Действие контроллера, защищенное атрибутом [Authorize], извлекает идентификатор клиента и пользователя элемента
ClaimsPrincipal
контроллера. (ASP.NET использует HttpContext.User
.) Microsoft.Identity.Web.OWIN добавляет методы расширения в контроллер, предоставляющий удобные службы для вызова Microsoft Graph или нижнего веб-API, или для получения заголовка авторизации или даже маркера. Методы, используемые для вызова API напрямую, подробно описаны в веб-приложении, которое вызывает веб-API: вызов API. При использовании этих вспомогательных методов вам не нужно получать токен вручную.
Однако если вы хотите вручную получить маркер или создать заголовок авторизации, в следующем коде показано, как использовать Microsoft.Identity.Web для этого в контроллере. Он вызывает API (Microsoft Graph) с помощью REST API вместо пакета SDK Microsoft Graph.
Чтобы получить заголовок авторизации, вы получите IAuthorizationHeaderProvider
службу от контроллера с помощью метода GetAuthorizationHeaderProvider
расширения. Чтобы получить заголовок авторизации для вызова API от имени пользователя, используйте (CreateAuthorizationHeaderForUserAsync
). Чтобы получить заголовок авторизации для вызова нижестоящего API от имени самого приложения, в сценарии управляющей программы используйте (CreateAuthorizationHeaderForAppAsync
).
Методы контроллера защищены атрибутом [Authorize]
, который разрешает использовать веб-приложение только авторизованным пользователям.
В следующем фрагменте кода показано действие заголовка HomeController
авторизации для вызова Microsoft Graph в качестве REST API:
[Authorize]
public class MyApiController : Controller
{
[AuthorizeForScopes(Scopes = new[] { "user.read" })]
public async Task<IActionResult> Profile()
{
// Get an authorization header.
IAuthorizationHeaderProvider authorizationHeaderProvider = this.GetAuthorizationHeaderProvider();
string[] scopes = new string[]{"user.read"};
string authorizationHeader = await authorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(scopes);
// Use the access token to call a protected web API.
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", authorizationHeader);
string json = await client.GetStringAsync(url);
}
}
В следующем фрагменте кода показано действие маркера MyApiController
доступа для вызова Microsoft Graph в качестве REST API:
[Authorize]
public class HomeController : Controller
{
[AuthorizeForScopes(Scopes = new[] { "user.read" })]
public async Task<IActionResult> Profile()
{
// Get an authorization header.
ITokenAcquirer tokenAcquirer = TokenAcquirerFactory.GetDefaultInstance().GetTokenAcquirer();
string[] scopes = new string[]{"user.read"};
string token = await await tokenAcquirer.GetTokenForUserAsync(scopes);
// Use the access token to call a protected web API.
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
string json = await client.GetStringAsync(url);
}
}
Ниже приведен пример кода, который вызывается в действиях контроллеров API. Он вызывает подчиненный API — Microsoft Graph.
@RestController
public class ApiController {
@Autowired
MsalAuthHelper msalAuthHelper;
@RequestMapping("/graphMeApi")
public String graphMeApi() throws MalformedURLException {
String oboAccessToken = msalAuthHelper.getOboToken("https://graph.microsoft.com/.default");
return callMicrosoftGraphMeEndpoint(oboAccessToken);
}
}
Веб-API на Python требует использования ПО промежуточного слоя для проверки токена носителя, полученного от клиента. Затем веб-API может получить маркер доступа для подчиненного API с помощью библиотеки MSAL Python, вызвав метод acquire_token_on_behalf_of
.
Ниже приведен пример кода, который получает маркер доступа с помощью метода acquire_token_on_behalf_of
и платформы Flask. Он вызывает подчиненный API — конечную точку подписок управления Azure.
def get(self):
_scopes = ["https://management.azure.com/user_impersonation"]
_azure_management_subscriptions_uri = "https://management.azure.com/subscriptions?api-version=2020-01-01"
current_access_token = request.headers.get("Authorization", None)
#This example only uses the default memory token cache and should not be used for production
msal_client = msal.ConfidentialClientApplication(
client_id=os.environ.get("CLIENT_ID"),
authority=os.environ.get("AUTHORITY"),
client_credential=os.environ.get("CLIENT_SECRET"))
#acquire token on behalf of the user that called this API
arm_resource_access_token = msal_client.acquire_token_on_behalf_of(
user_assertion=current_access_token.split(' ')[1],
scopes=_scopes
)
headers = {'Authorization': arm_resource_access_token['token_type'] + ' ' + arm_resource_access_token['access_token']}
subscriptions_list = req.get(_azure_management_subscriptions_uri), headers=headers).json()
return jsonify(subscriptions_list)
(Продвинутый уровень) Доступ к кэшу токенов выполнившего вход пользователя из фоновых приложений, интерфейсов API и служб
Вы можете использовать реализацию кэша токенов MSAL, чтобы разрешить фоновым приложениям, API и службам использовать кэш токенов доступа, чтобы продолжать действовать от имени пользователей в их отсутствие. Это особенно полезно, если фоновые приложения и службы должны продолжать работать от имени пользователя после того, как пользователь вышел из интерфейсного веб-приложения.
Сегодня большинство фоновых процессов используют разрешения приложений, когда им необходимо работать с данными пользователя без их присутствия для аутентификации или повторной аутентификации. Поскольку разрешения приложения часто требуют согласия администратора, что требует повышения привилегий, возникают ненужные трения, поскольку разработчик не намеревался получать разрешение сверх того, на которое пользователь изначально дал свое согласие для своего приложения.
Этот пример кода на GitHub показывает, как избежать этого ненужного трения, обращаясь к кэшу токенов MSAL из фоновых приложений:
Доступ к кэшу токенов вошедшего в систему пользователя из фоновых приложений, API и служб