Depois de criar um objeto de aplicativo cliente, use-o para adquirir um token que você pode usar para chamar uma API da Web.
Microsoft.Identity.Web adiciona métodos de extensão que fornecem serviços de conveniência para chamar o Microsoft Graph ou uma API da Web downstream. Esses métodos são explicados em detalhes em Um aplicativo Web que chama APIs da Web: Chamar uma API. Com esses métodos auxiliares, você não precisa adquirir manualmente um token.
Se, no entanto, você quiser adquirir manualmente um token, o código a seguir mostra um exemplo de uso de Microsoft.Identity.Web para fazer isso em um controlador doméstico. Ele chama o Microsoft Graph usando a API REST (em vez do SDK do Microsoft Graph). Normalmente, você não precisa obter um token, você precisa criar um cabeçalho de Autorização que você adiciona à sua solicitação. Para obter um cabeçalho de autorização, você injeta o IAuthorizationHeaderProvider
serviço por injeção de dependência no construtor do controlador (ou no construtor de página se usar Blazor) e o usa nas ações do controlador. Esta interface tem métodos que produzem uma string contendo o protocolo (Bearer, Pop, ...) e um token. Para obter um cabeçalho de autorização para chamar uma API em nome do usuário, use (CreateAuthorizationHeaderForUserAsync
). Para obter um cabeçalho de autorização para chamar uma API downstream em nome do próprio aplicativo, em um cenário de daemon, use (CreateAuthorizationHeaderForAppAsync
).
Os métodos do controlador são protegidos por um [Authorize]
atributo que garante que apenas chamadas autenticadas possam usar a API da Web.
[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);
}
}
Para obter detalhes sobre o callTodoListService
método, consulte Uma API da Web que chama APIs da Web: chame uma API.
O código para ASP.NET é semelhante ao código mostrado para ASP.NET Core:
- Uma ação do controlador, protegida por um atributo [Autorizar], extrai o ID do locatário e o ID do usuário do
ClaimsPrincipal
membro do controlador. (ASP.NET usa HttpContext.User
.) Microsoft.Identity.Web.OWIN adiciona métodos de extensão ao Controlador que fornecem serviços de conveniência para chamar o Microsoft Graph ou uma API da Web downstream, ou para obter um cabeçalho de autorização ou até mesmo um token. Os métodos usados para chamar uma API diretamente são explicados em detalhes em Um aplicativo Web que chama APIs da Web: Chamar uma API. Com esses métodos auxiliares, você não precisa adquirir manualmente um token.
Se, no entanto, você quiser adquirir manualmente um token ou criar um cabeçalho de autorização, o código a seguir mostra como usar Microsoft.Identity.Web para fazer isso em um controlador. Ele chama uma API (Microsoft Graph) usando a API REST em vez do SDK do Microsoft Graph.
Para obter um cabeçalho de autorização, você obtém um IAuthorizationHeaderProvider
serviço do controlador usando um método GetAuthorizationHeaderProvider
de extensão . Para obter um cabeçalho de autorização para chamar uma API em nome do usuário, use (CreateAuthorizationHeaderForUserAsync
). Para obter um cabeçalho de autorização para chamar uma API downstream em nome do próprio aplicativo, em um cenário de daemon, use (CreateAuthorizationHeaderForAppAsync
).
Os métodos do controlador são protegidos por um [Authorize]
atributo que garante que apenas usuários autenticados possam usar o aplicativo Web.
O trecho a seguir mostra a ação do , que obtém um cabeçalho de autorização para chamar o HomeController
Microsoft Graph como uma API REST:
[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);
}
}
O trecho a seguir mostra a ação do , que obtém um token de acesso para chamar o MyApiController
Microsoft Graph como uma API REST:
[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);
}
}
Aqui está um exemplo de código que é chamado nas ações dos controladores de API. Ele chama a API downstream - 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);
}
}
Uma API web Python requer o uso de middleware para validar o token de portador recebido do cliente. A API da Web pode então obter o token de acesso para uma API downstream usando a biblioteca Python do MSAL chamando o acquire_token_on_behalf_of
método.
Aqui está um exemplo de código que adquire um token de acesso usando o acquire_token_on_behalf_of
método e a estrutura Flask. Ele chama a API downstream - o ponto de extremidade das Assinaturas de Gerenciamento do 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)
(Avançado) Acessando o cache de token do usuário conectado a partir de aplicativos, APIs e serviços em segundo plano
Você pode usar a implementação do cache de token do MSAL para permitir que aplicativos, APIs e serviços em segundo plano usem o cache de token de acesso para continuar a agir em nome dos usuários na ausência deles. Isso é especialmente útil se os aplicativos e serviços em segundo plano precisarem continuar a funcionar em nome do usuário depois que ele sair do aplicativo Web front-end.
Hoje, a maioria dos processos em segundo plano usa permissões de aplicativo quando precisam trabalhar com os dados de um usuário sem que eles estejam presentes para autenticar ou reautenticar. Como as permissões de aplicativos geralmente exigem o consentimento do administrador, o que requer elevação de privilégio, atrito desnecessário é encontrado, pois o desenvolvedor não pretendia obter permissão além daquela que o usuário originalmente consentiu para seu aplicativo.
Este exemplo de código no GitHub mostra como evitar esse atrito desnecessário acessando o cache de token do MSAL a partir de aplicativos em segundo plano:
Acessando o cache de token do usuário conectado a partir de aplicativos, APIs e serviços em segundo plano