Plataforma de identidade da Microsoft e fluxo de concessão implícito OAuth 2.0
A plataforma de identidade da Microsoft suporta o fluxo de concessão implícita do OAuth 2.0, conforme descrito na especificação do OAuth 2.0. A característica definidora da concessão implícita é que os tokens (tokens de ID ou tokens de acesso) são retornados diretamente do ponto de extremidade /authorize em vez do ponto de extremidade /token. Isso é frequentemente usado como parte do fluxo de código de autorização, no que é chamado de "fluxo híbrido" - recuperando o token de ID na solicitação /authorize junto com um código de autorização.
Este artigo descreve como programar diretamente no protocolo em seu aplicativo para solicitar tokens do Microsoft Entra ID. Quando possível, recomendamos que utilize as Bibliotecas de Autenticação da Microsoft (MSAL) suportadas para adquirir tokens e chamar as APIs Web seguras. Para obter uma lista de exemplos de código que usam MSAL, consulte os exemplos de código de plataforma de identidade da Microsoft.
Aviso
A Microsoft recomenda que você não use o fluxo de concessão implícito. Na maioria dos cenários, alternativas mais seguras estão disponíveis e são recomendadas. Certas configurações desse fluxo exigem um grau muito alto de confiança no aplicativo e acarretam riscos que não estão presentes em outros fluxos. Você só deve usar esse fluxo quando outros fluxos mais seguros não forem viáveis. Para obter mais informações, consulte as preocupações de segurança com o fluxo de concessão implícito.
Diagrama de protocolo
O diagrama a seguir mostra a aparência de todo o fluxo de entrada implícito e as seções a seguir descrevem cada etapa em detalhes.
Cenários adequados para a subvenção implícita OAuth2
A concessão implícita só é confiável para a parte inicial e interativa do seu fluxo de login, onde a falta de cookies de terceiros não afeta seu aplicativo. Essa limitação significa que você deve usá-lo exclusivamente como parte do fluxo híbrido, onde seu aplicativo solicita um código e um token do ponto de extremidade de autorização. Em um fluxo híbrido, seu aplicativo recebe um código que pode ser trocado por um token de atualização, garantindo assim que a sessão de login do aplicativo permaneça válida ao longo do tempo.
Prefira o fluxo de código de autenticação
Com alguns navegadores removendo o suporte para cookies de terceiros, o fluxo de concessão implícito não é mais um método de autenticação adequado. Os recursos silenciosos de logon único (SSO) do fluxo implícito não funcionam sem cookies de terceiros, fazendo com que os aplicativos sejam interrompidos quando tentam obter um novo token. É altamente recomendável que todos os novos aplicativos usem o fluxo de código de autorização que agora oferece suporte a aplicativos de página única no lugar do fluxo implícito. Os aplicativos de página única existentes também devem migrar para o fluxo de código de autorização.
Preocupações de segurança com o fluxo de subvenção implícito
O fluxo de concessão implícito destina-se a aplicações web tradicionais onde o servidor tem controle sobre o processamento de dados POST de forma segura. Há duas maneiras principais de entregar tokens com o fluxo de concessão implícito: onde response_mode
é retornado como um fragmento de URL ou como um parâmetro de consulta (usando form POST
e GET
). No fluxo implícito onde response_mode=form_post
, o token é entregue com segurança através de um POST de formulário HTML para o URI de redirecionamento do cliente. Esse método garante que o token não seja exposto no fragmento de URL, o que, por sua vez, evita os riscos de vazamento de token através do histórico do navegador ou cabeçalhos de referência.
As preocupações de segurança com o fluxo implícito surgem quando os tokens são entregues usando response_mode=fragment
o . O fragmento de URL é a parte do URL que vem depois do #
símbolo e não é enviado para o servidor quando o navegador solicita uma nova página, mas está disponível para JavaScript em execução no navegador. Isso significa que o token é exposto a qualquer JavaScript em execução na página, o que pode ser um risco de segurança se a página incluir scripts de terceiros. Essas preocupações de segurança para tokens em SPAs também não se aplicam ao fluxo implícito com form POST
.
Quando você deve permitir que um token de acesso ou token de ID seja emitido quando solicitado usando concessão implícita ou fluxo híbrido?
A concessão implícita e o fluxo híbrido não são tão seguros quanto outros fluxos OAuth. A menos que seja absolutamente necessário, você não deve permitir que um token de acesso ou ID seja emitido quando solicitado usando concessão implícita ou fluxo híbrido no registro do aplicativo. Se você (ou seus desenvolvedores) estiverem usando o MSAL em seu aplicativo para implementar autenticação e autorização, nenhum campo precisará ser habilitado.
No entanto, se você (ou seus desenvolvedores) não estiver usando o MSAL em seu aplicativo, a tabela a seguir descreve quando os tokens de acesso ou token de ID devem ser habilitados.
Tipo de aplicativo que você está criando | Tokens que você deve ativar no Registro do aplicativo |
---|---|
Um SPA (aplicativo de página única) que não usa o fluxo de código de autorização com PKCE | Tokens de acesso & Tokens de ID |
Um aplicativo Web ou SPA que chama uma API da Web via JavaScript usando fluxo implícito | Tokens de acesso & Tokens de ID |
Um aplicativo Web ASP.NET Core e outros aplicativos Web que usam autenticação híbrida | Tokens de ID |
Enviar o pedido de início de sessão
Para iniciar sessão inicial do utilizador na sua aplicação, pode enviar um pedido de autenticação OpenID Connect e obter um id_token
da plataforma de identidade Microsoft.
Importante
Para solicitar com êxito um token de ID e/ou um token de acesso, o registro do aplicativo na página Centro de administração do Microsoft Entra - Registros de aplicativos deve ter o fluxo de concessão implícito correspondente habilitado, selecionando Tokens de ID e Tokens de acesso na seção Concessão implícita e fluxos híbridos. Se não estiver habilitado, um unsupported_response
erro será retornado:
The provided value for the input parameter 'response_type' is not allowed for this client. Expected value is 'code'
// Line breaks for legibility only
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&response_type=id_token
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&scope=openid
&response_mode=fragment
&state=12345
&nonce=678910
Parâmetro | Tipo | Descrição |
---|---|---|
tenant |
obrigatório | O {tenant} valor no caminho da solicitação pode ser usado para controlar quem pode entrar no aplicativo. Os valores permitidos são common , organizations , consumers e identificadores de locatário. Para obter mais detalhes, consulte noções básicas de protocolo. Essencialmente, para cenários de convidado em que você assina um usuário de um locatário para outro locatário, você deve fornecer o identificador de locatário para conectá-los corretamente ao locatário de recurso. |
client_id |
obrigatório | A ID do Aplicativo (cliente) que a página Centro de administração do Microsoft Entra - Registros de aplicativos atribuiu ao seu aplicativo. |
response_type |
obrigatório | Deve incluir id_token para login no OpenID Connect. Pode também incluir o response_type , token . Usar token aqui permite que seu aplicativo receba um token de acesso imediatamente do ponto de extremidade /authorize sem ter que fazer uma segunda solicitação ao ponto de extremidade /authorit. Se você usar o token response_type, o scope parâmetro deve conter um escopo indicando para qual recurso emitir o token (por exemplo, user.read no Microsoft Graph). Ele também pode conter code no lugar de fornecer um código de autorização, para uso no fluxo de código de token autorização. Essa id_token +code resposta às vezes é chamada de fluxo híbrido. |
redirect_uri |
recomendado | O URI de redirecionamento do seu aplicativo, onde as respostas de autenticação são enviadas e recebidas no seu aplicativo. Ele deve corresponder exatamente a um dos URIs de redirecionamento registrados no centro de administração do Microsoft Entra, exceto que deve ser codificado por URL. |
scope |
obrigatório | Uma lista de escopos separados por espaços. Para o OpenID Connect (id_tokens ), ele deve incluir o escopo openid , que se traduz na permissão "Entrar" na interface do usuário de consentimento. Opcionalmente, você também pode incluir os escopos email e profile para obter acesso a dados adicionais do usuário. Você também pode incluir outros escopos nesta solicitação para solicitar consentimento para vários recursos, se um token de acesso for solicitado. |
response_mode |
recomendado | Especifica o método que deve ser usado para enviar o token resultante de volta para seu aplicativo. O padrão é query apenas para um token de acesso, mas fragment se a solicitação incluir um id_token. Por motivos de segurança, é recomendável usar form_post para o fluxo implícito para garantir que o token não seja exposto no fragmento de URL. |
state |
recomendado | Um valor incluído na solicitação também é retornado na resposta do token. Pode ser uma sequência de qualquer conteúdo que desejar. Um valor exclusivo gerado aleatoriamente é normalmente usado para evitar ataques de falsificação de solicitação entre sites. O estado também é 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 a exibição em que eles estavam. |
nonce |
obrigatório | Um valor incluído na solicitação, gerado pelo aplicativo, que é incluído no token de ID resultante como uma declaração. O aplicativo pode verificar esse valor para mitigar ataques de repetição de token. O valor é normalmente uma cadeia de caracteres aleatória e exclusiva que pode ser usada para identificar a origem da solicitação. Necessário apenas quando uma id_token é solicitada. |
prompt |
opcional | Indica o tipo de interação do usuário necessária. Os únicos valores válidos neste momento são login , none , select_account , e consent . prompt=login força o usuário a inserir suas credenciais nessa solicitação, negando o logon único. prompt=none é o oposto - garante que o usuário não seja apresentado com qualquer prompt interativo. Se a solicitação não puder ser concluída silenciosamente via SSO, a plataforma de identidade da Microsoft retornará um erro. prompt=select_account envia o usuário para um seletor de contas onde todas as contas lembradas na sessão aparecem. prompt=consent acionará a caixa de diálogo de consentimento OAuth depois que o usuário entrar, solicitando que o usuário conceda permissões ao aplicativo. |
login_hint |
opcional | Você pode usar esse parâmetro para preencher previamente o campo de nome de usuário e endereço de e-mail da página de entrada do usuário, se souber o nome de usuário com antecedência. Muitas vezes, os aplicativos usam esse parâmetro durante a reautenticação, depois de já extrair a login_hint declaração opcional de uma entrada anterior. |
domain_hint |
opcional | Se incluído, ele ignora o processo de descoberta baseado em email pelo qual o usuário passa na página de login, levando a uma experiência de usuário um pouco mais simplificada. Esse parâmetro é comumente usado para aplicativos de Linha de Negócios que operam em um único locatário, onde eles fornecem um nome de domínio dentro de um determinado locatário, encaminhando o usuário para o provedor de federação desse locatário. Essa dica impede que os convidados façam login neste aplicativo e limita o uso de credenciais de nuvem, como FIDO. |
Neste ponto, o usuário é solicitado a inserir suas credenciais e concluir a autenticação. A plataforma de identidade da Microsoft garante que o usuário tenha consentido com as permissões indicadas no scope
parâmetro query. Se o usuário não consentiu com nenhuma dessas permissões, ele pede ao usuário para consentir com as permissões necessárias. Para saber mais, veja Permissões, consentimento e aplicativos multilocatário.
Depois que o usuário autentica e concede consentimento, a plataforma de identidade da Microsoft retorna uma resposta ao seu aplicativo no , indicado redirect_uri
, usando o método especificado no response_mode
parâmetro.
Resposta com êxito
Uma resposta bem-sucedida usando response_mode=fragment
e response_type=id_token+code
se parece com o seguinte (com quebras de linha para legibilidade):
GET https://localhost/myapp/#
code=0.AgAAktYV-sfpYESnQynylW_UKZmH-C9y_G1A
&id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...
&state=12345
Parâmetro | Description |
---|---|
code |
Incluído se response_type inclui code . É um código de autorização adequado para uso no fluxo de código de autorização. |
access_token |
Incluído se response_type inclui token . O token de acesso que o aplicativo solicitou. O token de acesso não deve ser decodificado ou inspecionado de outra forma, ele deve ser tratado como uma cadeia de caracteres opaca. |
token_type |
Incluído se response_type inclui token . Este é sempre um Bearer . |
expires_in |
Incluído se response_type inclui token . Indica o número de segundos em que o token é válido, para fins de cache. |
scope |
Incluído se response_type inclui token . Indica um ou mais escopos para os quais o access_token é válido. Pode não incluir todos os escopos solicitados se eles não forem aplicáveis ao usuário. Por exemplo, escopos somente do Microsoft Entra, solicitados ao fazer login usando uma conta pessoal. |
id_token |
Um JSON Web Token (JWT) assinado. O aplicativo pode decodificar os segmentos desse token para solicitar informações sobre o usuário que fez login. O aplicativo pode armazenar os valores em cache e exibi-los, mas não deve depender deles para quaisquer limites de autorização ou segurança. Para obter mais informações sobre tokens de ID, consulte o id_token reference . Nota: Apenas fornecido se openid o âmbito foi solicitado e response_type incluído id_tokens . |
state |
Se um parâmetro de estado for incluído na solicitação, o mesmo valor deverá aparecer na resposta. O aplicativo deve verificar se os valores de estado na solicitação e na resposta são idênticos. |
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. Os tokens para serviços da Microsoft podem usar um formato especial que não será validado como um JWT e também podem ser criptografados para usuários consumidores (conta da Microsoft). Embora a leitura de tokens seja uma ferramenta útil de depuração e aprendizagem, não dependa disso em seu código ou assuma especificidades sobre tokens que não são para uma API que você controla.
Resposta de erro
As respostas de erro também podem ser enviadas para o para que redirect_uri
o aplicativo possa lidar com elas adequadamente:
GET https://localhost/myapp/#
error=access_denied
&error_description=the+user+canceled+the+authentication
Parâmetro | Description |
---|---|
error |
Uma cadeia de caracteres de código de erro que pode ser usada para classificar tipos de erros que ocorrem e pode ser usada para reagir a erros. |
error_description |
Uma mensagem de erro específica que pode ajudar um desenvolvedor a identificar a causa raiz de um erro de autenticação. |
Adquira tokens de acesso silenciosamente
Agora que o usuário está conectado ao seu aplicativo de página única, você pode obter silenciosamente tokens de acesso para chamar APIs da Web protegidas pela plataforma de identidade da Microsoft, como o Microsoft Graph. Mesmo que você já tenha recebido um token usando o token
response_type, você pode usar esse método para adquirir tokens para recursos adicionais sem redirecionar o usuário para entrar novamente.
Importante
É improvável que essa parte do fluxo implícito funcione para seu aplicativo, pois é usada em diferentes navegadores devido à remoção de cookies de terceiros por padrão. Embora isso ainda funcione atualmente em navegadores baseados no Chromium que não estão em navegação anônima, os desenvolvedores devem reconsiderar o uso dessa parte do fluxo. Em navegadores que não suportam cookies de terceiros, você receberá um erro indicando que nenhum usuário está conectado, pois os cookies de sessão da página de login foram removidos pelo navegador.
No fluxo normal do OpenID Connect/OAuth, você faria isso fazendo uma solicitação ao ponto de extremidade da plataforma /token
de identidade da Microsoft. Você pode fazer a solicitação em um iframe oculto para obter novos tokens para outras APIs da Web:
// Line breaks for legibility only
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=00001111-aaaa-2222-bbbb-3333cccc4444&response_type=token
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&scope=https%3A%2F%2Fgraph.microsoft.com%2Fuser.read
&response_mode=fragment
&state=12345
&nonce=678910
&prompt=none
&login_hint=myuser@mycompany.com
Para obter detalhes sobre os parâmetros de consulta na URL, consulte Enviar a solicitação de login.
Gorjeta
Tente copiar e colar a seguinte solicitação em uma guia do navegador usando um real client_id
e username
a partir do registro do seu aplicativo. Isso permitirá que você veja a solicitação de token silencioso em ação.
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={your-client-id}&response_type=token&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F&scope=https%3A%2F%2Fgraph.microsoft.com%2Fuser.read&response_mode=fragment&state=12345&nonce=678910&prompt=none&login_hint={username}
Observe que isso funcionará mesmo em navegadores sem suporte a cookies de terceiros, já que você está inserindo isso diretamente em uma barra do navegador, em vez de abri-la dentro de um iframe.
Graças ao prompt=none
parâmetro, esta solicitação é bem-sucedida ou falha imediatamente e retorna ao seu aplicativo. A resposta é enviada para o seu aplicativo no endereço indicado redirect_uri
, usando o método especificado no response_mode
parâmetro.
Resposta com êxito
Uma resposta bem-sucedida usando se response_mode=fragment
parece com:
GET https://localhost/myapp/#
access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...
&state=12345
&token_type=Bearer
&expires_in=3599
&scope=https%3A%2F%2Fgraph.microsoft.com%2Fdirectory.read
Parâmetro | Description |
---|---|
access_token |
Incluído se response_type inclui token . O token de acesso que o aplicativo solicitou, neste caso para o Microsoft Graph. O token de acesso não deve ser decodificado ou inspecionado de outra forma, ele deve ser tratado como uma cadeia de caracteres opaca. |
token_type |
Este é sempre um Bearer . |
expires_in |
Indica o número de segundos em que o token é válido, para fins de cache. |
scope |
Indica um ou mais escopos para os quais o token de acesso é válido. Pode não incluir todos os escopos solicitados, se eles não forem aplicáveis ao usuário (se escopos somente do Microsoft Entras estiverem sendo solicitados quando uma conta pessoal for usada para entrar). |
id_token |
Um JSON Web Token (JWT) assinado. Incluído se response_type inclui id_token . O aplicativo pode decodificar os segmentos desse token para solicitar informações sobre o usuário que fez login. O aplicativo pode armazenar os valores em cache e exibi-los, mas não deve depender deles para quaisquer limites de autorização ou segurança. Para obter mais informações sobre id_tokens, consulte a id_token referência. Nota: Apenas fornecido se openid o âmbito foi solicitado. |
state |
Se um parâmetro de estado for incluído na solicitação, o mesmo valor deverá aparecer na resposta. O aplicativo deve verificar se os valores de estado na solicitação e na resposta são idênticos. |
Resposta de erro
As respostas de erro também podem ser enviadas para o para que redirect_uri
o aplicativo possa lidar com elas adequadamente. Se prompt=none
, um erro esperado é:
GET https://localhost/myapp/#
error=user_authentication_required
&error_description=the+request+could+not+be+completed+silently
Parâmetro | Description |
---|---|
error |
Uma cadeia de caracteres de código de erro que pode ser usada para classificar tipos de erros que ocorrem e pode ser usada para reagir a erros. |
error_description |
Uma mensagem de erro específica que pode ajudar um desenvolvedor a identificar a causa raiz de um erro de autenticação. |
Se você receber esse erro na solicitação iframe, o usuário deverá entrar interativamente novamente para recuperar um novo token. Pode optar por tratar este caso da forma que fizer sentido para a sua aplicação.
Atualizando tokens
A concessão implícita não fornece tokens de atualização. Tanto os tokens de ID quanto os tokens de acesso expirarão após um curto período de tempo, portanto, seu aplicativo deve estar preparado para atualizar esses tokens periodicamente. Para atualizar qualquer tipo de token, você pode executar a mesma solicitação iframe oculta delineada anteriormente, usando o prompt=none
parâmetro para controlar o comportamento da plataforma de identidade. Se você quiser receber um novo token de ID, certifique-se de usar id_token
o response_type
e scope=openid
, e um nonce
parâmetro.
Em navegadores que não suportam cookies de terceiros, isso resulta em um erro indicando que nenhum usuário está conectado.
Enviar uma solicitação de saída
O OpenID Connect end_session_endpoint
permite que seu aplicativo envie uma solicitação para a plataforma de identidade da Microsoft para encerrar a sessão de um usuário e limpar os cookies definidos pela plataforma de identidade da Microsoft. Para sair totalmente de um usuário de um aplicativo Web, seu aplicativo deve encerrar sua própria sessão com o usuário (geralmente limpando um cache de token ou descartando cookies) e, em seguida, redirecionar o navegador para:
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/logout?post_logout_redirect_uri=https://localhost/myapp/
Parâmetro | Tipo | Descrição |
---|---|---|
tenant |
obrigatório | O {tenant} valor no caminho da solicitação pode ser usado para controlar quem pode entrar no aplicativo. Os valores permitidos são common , organizations , consumers e identificadores de locatário. Para obter mais detalhes, consulte noções básicas de protocolo. |
post_logout_redirect_uri |
recomendado | A URL para a qual o usuário deve retornar após a conclusão do logout. Esse valor deve corresponder a um dos URIs de redirecionamento registrados para o aplicativo. Se não estiver incluído, o usuário receberá uma mensagem genérica da plataforma de identidade da Microsoft. |
Consulte também
- Examine as amostras MSAL JS para começar a codificar.
- Analise o fluxo do código de autorização como uma alternativa mais nova e melhor à concessão implícita.