Adquirir tokens para chamar uma API Web usando um aplicativo daemon

Depois de construir um aplicativo cliente confidencial, você pode adquirir um token para o aplicativo recorrendo a AcquireTokenForClient, passando o escopo e, opcionalmente, forçando uma atualização do token.

Escopos a serem solicitados

O escopo a ser solicitado para um fluxo de credenciais do cliente é o nome do recurso seguido por /.default. Essa notação instrui a ID do Microsoft Entra a usar as permissões de nível do aplicativo declaradas estaticamente durante o registro de aplicativo. Além disso, essas permissões de API precisam ser concedidas por um administrador de locatários.

Veja um exemplo de definição dos escopos para a API Web como parte da configuração em um arquivo appsettings.json. Este exemplo é obtido do código daemon do console .NET no GitHub.

{
    "AzureAd": {
        // Same AzureAd section as before.
    },

    "MyWebApi": {
        "BaseUrl": "https://localhost:44372/",
        "RelativePath": "api/TodoList",
        "RequestAppToken": true,
        "Scopes": [ "[Enter here the scopes for your web API]" ]
    }
}

Recursos do Azure AD (v1.0)

O escopo usado para credenciais de cliente sempre deve ser a ID de recurso seguida por /.default.

Importante

Quando o MSAL solicita um token de acesso para um recurso que aceita um token de acesso da versão 1,0, a ID do Microsoft Entra analisa o público-alvo desejado do escopo solicitado, incluindo tudo antes da última barra e usando-o como o identificador de recurso. Portanto, assim como no banco de dados SQL do Azure (https://database.windows.net), the resource expects an audience that ends with a slash (for Azure SQL Database, https://database.windows.net/), você precisará solicitar um escopo do https://database.windows.net//.default. (Observe a barra dupla.) Veja também o problema MSAL.NET #747: Resource url's trailing slash is omitted, which caused sql auth failure.

AcquireTokenForClient API

Para adquirir um token para o aplicativo, use AcquireTokenForClient ou seu equivalente, dependendo da plataforma.

Com o Microsoft.Identity.Web, você não precisa adquirir um token. Você pode usar APIs de nível superior, como você vê em Chamar uma API Web de um aplicativo daemon. No entanto, se você estiver usando um SDK que requer token, o snippet de código a seguir mostrará como obter esse token.

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Identity.Abstractions;
using Microsoft.Identity.Web;

// In the Program.cs, acquire a token for your downstream API

var tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();
ITokenAcquirer acquirer = tokenAcquirerFactory.GetTokenAcquirer();
AcquireTokenResult tokenResult = await acquirer.GetTokenForUserAsync(new[] { "https://graph.microsoft.com/.default" });
string accessToken = tokenResult.AccessToken;

Protocolo

Se você ainda não tiver uma biblioteca para a linguagem escolhida, talvez queira usar o protocolo diretamente:

Na primeira ocorrência: solicitação de token de acesso com um segredo compartilhado

POST /{tenant}/oauth2/v2.0/token HTTP/1.1           //Line breaks for clarity.
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_secret=A1b-C2d_E3f.H4i,J5k?L6m!N7o-P8q_R9s.T0u
&grant_type=client_credentials

Segundo caso: acessar a solicitação de token usando um certificado

POST /{tenant}/oauth2/v2.0/token HTTP/1.1               // Line breaks for clarity.
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_id=11112222-bbbb-3333-cccc-4444dddd5555
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=aaaaaaaa-0b0b-...
&grant_type=client_credentials

Para saber mais, confira a plataforma de identidade da Microsoft e o fluxo de credenciais do cliente OAuth 2.0.

Solução de problemas

Você usou o escopo de recurso/. padrão?

Se você receber uma mensagem de erro informando que usou um escopo inválido, provavelmente não usou o resource/.default escopo.

Se você receber privilégios insuficientes para concluir o erro de operação ao chamar a API, o administrador do locatário precisará conceder permissões ao aplicativo.

Se você não conceder consentimento do administrador ao seu aplicativo, você encontrará o seguinte erro:

Failed to call the web API: Forbidden
Content: {
  "error": {
    "code": "Authorization_RequestDenied",
    "message": "Insufficient privileges to complete the operation.",
    "innerError": {
      "request-id": "<guid>",
      "date": "<date>"
    }
  }
}

Selecione uma das opções a seguir, dependendo da função.

Administrator de locatário global

Para um administrador de locatário global, acesse Aplicativos empresariais no centro de administração do Microsoft Entra. Selecione o registro do aplicativo e selecione Permissões na seção Segurança do painel esquerdo. Em seguida, selecione o botão grande rotulado Conceder consentimento de administrador para {Tenant Name} (em que {Tenant Name} é o nome do diretório).

Usuário padrão

Para usuários padrão do seu locatário, solicite ao Administrador Global que forneça consentimento do administrador para o aplicativo. Para fazer isso, forneça a seguinte URL ao administrador:

https://login.microsoftonline.com/Enter_the_Tenant_Id_Here/adminconsent?client_id=Enter_the_Application_Id_Here

Na URL:

  • Substitua Enter_the_Tenant_Id_Here pela ID ou pelo nome do locatário (por exemplo, contoso.microsoft.com).
  • Enter_the_Application_Id_Here é a ID do aplicativo (cliente) que você registrou.

O erro AADSTS50011: No reply address is registered for the application pode ser exibido depois que você conceder consentimento ao aplicativo usando a URL anterior. Esse erro ocorre porque o aplicativo e a URL não têm um URI de redirecionamento. Ela pode ser ignorada.

Você está recorrendo a sua própria API?

Se o aplicativo daemon chamar sua API Web e você não tiver conseguido adicionar uma permissão de aplicativo ao registro de aplicativo do daemon, será necessário Adicionar funções de aplicativo ao registro de aplicativo da API Web.

Próximas etapas

Vá para o próximo artigo nesse cenário, Recorrendo a uma API Web.