Plataforma de identidade da Microsoft e o fluxo de credenciais do cliente OAuth 2.0
O fluxo de concessão de credenciais do cliente OAuth 2.0 permite que um serviço Web (cliente confidencial) use suas próprias credenciais, em vez de representar um usuário, para autenticar ao chamar outro serviço Web. A concessão especificada na RFC 6749, às vezes chamada de OAuth de duas etapas, pode ser usada para acessar recursos hospedados na Web usando a identidade de um aplicativo. Esse tipo geralmente é usado para interações servidor a servidor que devem ser executadas em segundo plano, sem interação imediata com um usuário, e geralmente é chamado de daemons ou contas de serviço .
No fluxo de credenciais do cliente, as permissões são concedidas diretamente ao próprio aplicativo por um administrador. Quando o aplicativo apresenta um token para um recurso, o recurso impõe que o próprio aplicativo tenha autorização para executar uma ação, pois não há nenhum usuário envolvido na autenticação. Este artigo aborda as duas etapas necessárias para:
Este artigo descreve como programar diretamente contra o protocolo em seu aplicativo. Quando possível, recomendamos usar as MSAL (bibliotecas de autenticação da Microsoft) com suporte para adquirir tokens e chamar APIs Web seguras. Você também pode consultar os aplicativos de exemplo que utilizam MSAL. Como uma observação, os tokens de atualização nunca serão concedidos com esse fluxo, pois client_id
e client_secret
(que seriam necessários para obter um token de atualização) podem ser usados para obter um token de acesso.
Para um nível mais alto de garantia, a plataforma de identidade da Microsoft também permite que o serviço de chamada se autentique usando um certificado ou credencial federada em vez de um segredo compartilhado. Como as próprias credenciais do aplicativo estão sendo usadas, essas credenciais devem ser mantidas seguras. Nunca publique essa credencial no código-fonte, embuta em páginas da Web ou utilize em um aplicativo nativo amplamente distribuído.
Diagrama de protocolo
Todo o fluxo de credenciais do cliente é semelhante ao diagrama a seguir. Descrevemos cada uma das etapas mais adiante neste artigo.
Diagrama
Obter autorização direta
Normalmente, um aplicativo recebe autorização direta para acessar um recurso de duas maneiras:
- Por meio de uma ACL (lista de controle de acesso) no recurso
- Por meio da atribuição de permissão de aplicativo no Microsoft Entra ID
Esses dois métodos são os mais comuns na ID do Microsoft Entra e os recomendamos para clientes e recursos que executam o fluxo de credenciais do cliente. Um recurso também pode optar por autorizar seus clientes de outras maneiras. Cada servidor de recursos pode escolher o método que faz mais sentido para seu aplicativo.
Listas de controle de acesso
Um provedor de recursos pode impor uma verificação de autorização com base em uma lista de IDs de aplicativo (cliente) às quais ele conhece e concede um nível específico de acesso. Quando o recurso recebe um token da plataforma de identidade da Microsoft, ele pode decodificar o token e extrair a ID do aplicativo do cliente das declarações appid
e iss
. Em seguida, ele compara o aplicativo com uma ACL (lista de controle de acesso) que ele mantém. A granularidade e o método da ACL podem variar substancialmente entre os recursos.
Um caso de uso comum é usar uma ACL para executar testes para um aplicativo Web ou para uma API Web. A API Web pode conceder apenas um subconjunto de permissões completas a um cliente específico. Para executar testes de ponta a ponta na API, você pode criar um cliente de teste que adquira tokens da plataforma de identidade da Microsoft e os envia para a API. Em seguida, a API verifica a ACL da ID do aplicativo do cliente de teste para obter acesso total a toda a funcionalidade da API. Se você usar esse tipo de ACL, certifique-se de validar não apenas o valor appid
do chamador, mas também validar que o valor iss
do token é confiável.
Esse tipo de autorização é comum para daemons e contas de serviço que precisam acessar dados de usuários consumidores que têm contas pessoais da Microsoft. Para dados pertencentes a organizações, recomendamos que você obtenha a autorização necessária por meio de permissões de aplicativo.
Controlando tokens sem a declaração roles
Para habilitar esse padrão de autorização baseado em ACL, a ID do Microsoft Entra não exige que os aplicativos sejam autorizados a obter tokens para outro aplicativo. Portanto, tokens somente de aplicativo podem ser emitidos sem uma declaração roles
. Os aplicativos que expõem APIs devem implementar verificações de permissão para aceitar tokens.
Caso deseje impedir que os aplicativos obtenham tokens de acesso somente de aplicativo sem função para o seu aplicativo, verifique se os requisitos de atribuição estão habilitados para o seu aplicativo. Isso impedirá que usuários e aplicativos sem funções atribuídas possam obter um token para este aplicativo.
Permissões de aplicativo
Em vez de usar ACLs, você pode usar APIs para expor um conjunto de permissões de aplicativo . Elas são concedidas a um aplicativo pelo administrador de uma organização e só podem ser usadas para acessar dados pertencentes a essa organização e seus funcionários. Por exemplo, o Microsoft Graph expõe várias permissões de aplicativo para fazer o seguinte:
- Ler emails em todas as caixas de correio
- Ler e gravar emails em todas as caixas de correio
- Enviar email como qualquer usuário
- Ler dados do diretório
Para usar funções de aplicativo (permissões de aplicativo) com sua API (em vez do Microsoft Graph), primeiro, exponha as funções de aplicativo no registro do aplicativo da API no centro de administração do Microsoft Entra. Em seguida, configure as funções de aplicativo necessárias selecionando essas permissões no registro do aplicativo cliente. Se você não tiver exposto nenhuma funções de aplicativo no registro de aplicativo da API, não poderá especificar permissões de aplicativo para essa API no registro de aplicativo do aplicativo cliente no Centro de administração do Microsoft Entra.
Ao se autenticar como um aplicativo (em vez de um usuário), você não poderá usar as permissões delegadas, pois não há usuários em nome dos quais o aplicativo possa atuar. Você deve usar permissões de aplicativo, também conhecidas como funções de aplicativo, que são concedidas por um administrador ou pelo proprietário da API.
Para obter mais informações sobre permissões de aplicativo, consulte Permissões e consentimento.
Recomendado: inscrever o administrador em seu aplicativo para ter funções de aplicativo atribuídas
Normalmente, quando você cria um aplicativo que usa permissões de aplicativo, o aplicativo requer uma página ou exibição na qual o administrador aprova as permissões do aplicativo. Essa página pode ser parte do fluxo de entrada do aplicativo, parte das configurações do aplicativo ou um fluxo dedicado de conexão. Geralmente, faz sentido que o aplicativo somente mostre o modo de exibição de conexão depois que o usuário entra com uma conta corporativa ou de estudante da Microsoft.
Se você conectar o usuário ao seu aplicativo, poderá identificar a organização à qual o usuário pertence antes de pedir ao usuário para aprovar as permissões do aplicativo. Embora não seja estritamente necessário, ele pode ajudá-lo a criar uma experiência mais intuitiva para seus usuários. Para conectar o usuário, siga os tutoriais de protocolo da plataforma de identidade da Microsoft.
Solicitar as permissões de um administrador de diretório
Quando estiver pronto para solicitar permissões do administrador da organização, você poderá redirecionar o usuário para o endpoint de consentimento de administrador da plataforma de identidade da Microsoft .
// Line breaks are for legibility only.
GET https://login.microsoftonline.com/{tenant}/adminconsent?
client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&state=12345
&redirect_uri=http://localhost/myapp/permissions
Dica pro: tente colar a solicitação a seguir em um navegador.
https://login.microsoftonline.com/common/adminconsent?client_id=00001111-aaaa-2222-bbbb-3333cccc4444&state=12345&redirect_uri=http://localhost/myapp/permissions
Parâmetro | Condição | Descrição |
---|---|---|
tenant |
Necessário | O locatário do diretório para o qual você deseja solicitar permissão. Pode estar no formato de nome amigável ou de GUID. Se você não souber a qual locatário o usuário pertence e se quiser deixá-lo entrar com qualquer locatário, use common . |
client_id |
Necessário | A ID do aplicativo (cliente) que a experiência centro de administração do Microsoft Entra – Registros de aplicativo atribui ao seu aplicativo. |
redirect_uri |
Necessário | O URI de redirecionamento para onde você deseja que a resposta seja enviada para ser processada pelo seu aplicativo. Ele deve corresponder exatamente a uma das URIs de redirecionamento que você registrou no portal, exceto que ela deve ser codificada em URL e pode ter segmentos de caminho adicionais. |
state |
Recomendado | Um valor incluído na solicitação que também é retornado na resposta do token. Pode ser uma cadeia de caracteres de qualquer conteúdo desejado. O estado é usado para codificar informações sobre o estado do usuário no aplicativo antes da solicitação de autenticação ocorrer, como a página ou exibição em que ele estava. |
Neste ponto, a ID do Microsoft Entra impõe que apenas um administrador de locatário possa entrar para concluir a solicitação. O administrador será solicitado a aprovar todas as permissões de aplicativo direto que você solicitou para seu aplicativo no portal de registro do aplicativo.
Resposta bem-sucedida
Se o administrador aprovar as permissões para seu aplicativo, a resposta bem-sucedida terá esta aparência:
GET http://localhost/myapp/permissions?tenant=aaaabbbb-0000-cccc-1111-dddd2222eeee&state=state=12345&admin_consent=True
Parâmetro | Descrição |
---|---|
tenant |
O locatário do diretório que concedeu ao seu aplicativo as permissões solicitadas, no formato GUID. |
state |
Um valor incluído na solicitação que também é retornado na resposta do token. Pode ser uma cadeia de caracteres de qualquer conteúdo desejado. O estado é usado para codificar informações sobre o estado do usuário no aplicativo antes da solicitação de autenticação ocorrer, como a página ou exibição em que ele estava. |
admin_consent |
Definido como True. |
Resposta de erro
Se o administrador não aprovar as permissões para seu aplicativo, a resposta com falha será semelhante a esta:
GET http://localhost/myapp/permissions?error=permission_denied&error_description=The+admin+canceled+the+request
Parâmetro | Descrição |
---|---|
error |
Uma cadeia de caracteres de código de erro que você pode usar para classificar tipos de erros e que você pode usar para reagir a erros. |
error_description |
Uma mensagem de erro específica que pode ajudá-lo a identificar a causa raiz de um erro. |
Depois de receber uma resposta bem-sucedida do ponto de extremidade de provisionamento do aplicativo, o aplicativo terá as permissões diretas solicitadas. Agora você pode solicitar um token para o recurso desejado.
Obter um token
Depois de adquirir a autorização necessária para seu aplicativo, prossiga com a aquisição de tokens de acesso para APIs. Para obter um token usando a concessão de credenciais do cliente, envie uma solicitação POST para a plataforma de identidade da Microsoft /token
. Há alguns casos diferentes:
- Solicitação de token de acesso com um segredo compartilhado
- Solicitação de token de acesso com um certificado
- Solicitação de token de acesso com uma credencial federada
Primeiro caso: 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:443
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=qWgdYAmab0YSkuL1qKv5bPX
&grant_type=client_credentials
# Replace {tenant} with your tenant!
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'client_id=00001111-aaaa-2222-bbbb-3333cccc4444&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret=A1bC2dE3f...&grant_type=client_credentials' 'https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token'
Parâmetro | Condição | Descrição |
---|---|---|
tenant |
Necessário | O aplicativo de locatário do diretório planos operar, no formato de nome de domínio ou GUID. |
client_id |
Necessário | A ID do aplicativo atribuída ao seu aplicativo. Você pode encontrar essas informações no portal em que registrou seu aplicativo. |
scope |
Necessário | O valor passado para o parâmetro scope nesta solicitação deve ser o identificador de recurso (URI da ID do aplicativo) do recurso desejado, sufixo com .default . Todos os escopos incluídos devem ser para um único recurso. A inclusão de escopos para vários recursos resultará em um erro. Para o exemplo do Microsoft Graph, o valor é https://graph.microsoft.com/.default . Esse valor informa à plataforma de identidade da Microsoft que, de todas as permissões de aplicativos diretas configuradas para seu aplicativo, o endpoint deve emitir um token para as permissões associadas ao recurso que você deseja usar. Para saber mais sobre o escopo do /.default , consulte a documentação de consentimento . |
client_secret |
Necessário | O segredo do cliente que você gerou para seu aplicativo no portal de registro do aplicativo. O segredo do cliente deve ser codificado em URL antes de ser enviado. O padrão de autenticação básico de fornecer credenciais no cabeçalho de autorização, conforme a RFC 6749, também tem suporte. |
grant_type |
Necessário | Deve ser definido como client_credentials . |
Segundo caso: solicitação de token de acesso com um certificado
POST /{tenant}/oauth2/v2.0/token HTTP/1.1 // Line breaks for clarity
Host: login.microsoftonline.com:443
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=eyJhbGciOiJSUzI1NiIsIng1dCI6Imd4OHRHeXN5amNScUtqRlBuZDdSRnd2d1pJMCJ9.eyJ{a lot of characters here}M8U3bSUKKJDEg
&grant_type=client_credentials
Parâmetro | Condição | Descrição |
---|---|---|
tenant |
Necessário | O aplicativo de locatário do diretório planos operar, no formato de nome de domínio ou GUID. |
client_id |
Necessário | A ID do aplicativo (cliente) atribuída ao seu aplicativo. |
scope |
Necessário | O valor passado para o parâmetro scope nesta solicitação deve ser o identificador de recurso (URI da ID do aplicativo) do recurso desejado, sufixo com .default . Todos os escopos incluídos devem ser para um único recurso. A inclusão de escopos para vários recursos resultará em um erro. Para o exemplo do Microsoft Graph, o valor é https://graph.microsoft.com/.default . Esse valor informa à plataforma de identidade da Microsoft que, de todas as permissões diretas de aplicativo configuradas para seu aplicativo, o endpoint deve emitir um token para aquelas associadas ao recurso que você deseja usar. Para saber mais sobre o escopo do /.default , consulte a documentação de consentimento . |
client_assertion_type |
Necessário | O valor deve ser definido como urn:ietf:params:oauth:client-assertion-type:jwt-bearer . |
client_assertion |
Necessário | Uma asserção (um token Web JSON) que você precisa criar e assinar usando o certificado que você registrou como credenciais para seu aplicativo. Leia mais sobre credenciais de certificado para saber como registrar seu certificado e saber sobre o formato da asserção. |
grant_type |
Necessário | Deve ser definido como client_credentials . |
Os parâmetros para a solicitação baseada em certificado diferem apenas de uma maneira da solicitação baseada em segredo compartilhada: o parâmetro client_secret
é substituído pelos parâmetros client_assertion_type
e client_assertion
.
Terceiro caso: solicitação de token de acesso com uma credencial federada
POST /{tenant}/oauth2/v2.0/token HTTP/1.1 // Line breaks for clarity
Host: login.microsoftonline.com:443
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=eyJhbGciOiJSUzI1NiIsIng1dCI6Imd4OHRHeXN5amNScUtqRlBuZDdSRnd2d1pJMCJ9.eyJ{a lot of characters here}M8U3bSUKKJDEg
&grant_type=client_credentials
Parâmetro | Condição | Descrição |
---|---|---|
client_assertion |
Necessário | Uma declaração (um token Web JWT ou JSON) que seu aplicativo obtém de outro provedor de identidade fora da plataforma de identidade da Microsoft, como o Kubernetes. As especificidades deste JWT devem ser registradas em seu aplicativo como uma credencial de identidade federada . Leia sobre federação de identidade de carga de trabalho para saber como configurar e usar instruções geradas por outros provedores de identidade. |
Tudo na solicitação é igual ao fluxo baseado em certificado, com a exceção crucial da origem do client_assertion
. Nesse fluxo, seu aplicativo não cria a declaração JWT em si. Em vez disso, seu aplicativo usa um JWT criado por outro provedor de identidade. Isso é chamado de federação de identidade de carga de trabalho , em que a identidade de seus aplicativos em outra plataforma de identidade é usada para adquirir tokens dentro da plataforma de identidade da Microsoft. Isso é mais adequado para cenários entre nuvens, como hospedar sua computação fora do Azure, mas acessar APIs protegidas pela plataforma de identidade da Microsoft. Para obter informações sobre o formato necessário de JWTs criado por outros provedores de identidade, leia sobre o formato de declaração.
Resposta bem-sucedida
Uma resposta bem-sucedida de qualquer método tem esta aparência:
{
"token_type": "Bearer",
"expires_in": 3599,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1uQ19WWmNBVGZNNXBP..."
}
Parâmetro | Descrição |
---|---|
access_token |
O token de acesso solicitado. O aplicativo pode usar esse token para se autenticar no recurso protegido, como em uma API Web. |
token_type |
Indica o valor do tipo de token. O único tipo compatível com a plataforma de identidade da Microsoft é bearer . |
expires_in |
A quantidade de tempo que um token de acesso é válido (em segundos). |
Aviso
Não tente validar ou ler tokens para qualquer API que você não possua, incluindo os tokens neste exemplo, em seu código. Tokens para serviços da Microsoft podem usar um formato especial que não será validado como um JWT e também pode ser criptografado para usuários consumidores (conta da Microsoft). Embora a leitura de tokens seja uma ferramenta útil de depuração e aprendizado, não use dependências sobre isso em seu código ou assuma detalhes sobre tokens que não são para uma API que você controla.
Resposta de erro
Uma resposta de erro (400 Solicitação Inválida) tem esta aparência:
{
"error": "invalid_scope",
"error_description": "AADSTS70011: The provided value for the input parameter 'scope' is not valid. The scope https://foo.microsoft.com/.default is not valid.\r\nTrace ID: 0000aaaa-11bb-cccc-dd22-eeeeee333333\r\nCorrelation ID: aaaa0000-bb11-2222-33cc-444444dddddd\r\nTimestamp: 2016-01-09 02:02:12Z",
"error_codes": [
70011
],
"timestamp": "YYYY-MM-DD HH:MM:SSZ",
"trace_id": "0000aaaa-11bb-cccc-dd22-eeeeee333333",
"correlation_id": "aaaa0000-bb11-2222-33cc-444444dddddd"
}
Parâmetro | Descrição |
---|---|
error |
Uma cadeia de caracteres de código de erro que você pode usar para classificar tipos de erros que ocorrem e para reagir a erros. |
error_description |
Uma mensagem de erro específica que pode ajudá-lo a identificar a causa raiz de um erro de autenticação. |
error_codes |
Uma lista de códigos de erro específicos do STS que podem ajudar no diagnóstico. |
timestamp |
A hora em que o erro ocorreu. |
trace_id |
Um identificador exclusivo para a solicitação para ajudar no diagnóstico. |
correlation_id |
Um identificador exclusivo para a solicitação para ajudar com o diagnóstico entre componentes. |
Usar um token
Agora que você adquiriu um token, use o token para fazer solicitações ao recurso. Quando o token expirar, repita a solicitação ao endpoint /token
para obter um novo token de acesso.
GET /v1.0/users HTTP/1.1
Host: graph.microsoft.com:443
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbG...
Experimente o comando a seguir em seu terminal, garantindo substituir o token por seu próprio.
curl -X GET -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbG..." 'https://graph.microsoft.com/v1.0/users'
Exemplos de código e outra documentação
Leia a documentação de visão geral das credenciais do cliente da Biblioteca de Autenticação da Microsoft
Amostra | Plataforma | Descrição |
---|---|---|
active-directory-dotnetcore-daemon-v2 | .NET 6.0+ | Um aplicativo ASP.NET Core que exibe os usuários de um locatário consultando o Microsoft Graph usando a identidade do aplicativo, em vez de em nome de um usuário. O exemplo também ilustra a variação usando certificados para autenticação. |
active-directory-dotnet-daemon-v2 | ASP.NET MVC | Um aplicativo Web que sincroniza dados do Microsoft Graph usando a identidade do aplicativo, em vez de em nome de um usuário. |
ms-identity-javascript-nodejs-console | Console Node.js | Um aplicativo Node.js que exibe os usuários de um tenant consultando o Microsoft Graph usando a identidade do aplicativo |