fluxo de concessão implícita da plataforma de identidade da Microsoft e OAuth 2.0
A plataforma de identidade da Microsoft dá suporte ao fluxo de concessão implícita do OAuth 2.0, conforme descrito na Especificação do OAuth 2.0. A definição da característica 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 geralmente é usado como parte do fluxo do código de autorização, em 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 do seu aplicativo para solicitar tokens do Microsoft Entra ID. Quando possível, recomendamos que você use as MSAL (bibliotecas de autenticação da Microsoft) com suporte para adquirir tokens e chamar APIs Web seguras. Para obter uma lista de exemplos de código que usam MSAL, consulte os exemplos de código da plataforma de identidade da Microsoft.
Aviso
A Microsoft recomenda que você não use o fluxo de concessão implícita. Na maioria dos cenários, alternativas mais seguras estão disponíveis e são recomendadas. Algumas configurações desse fluxo exigem um grau muito alto de confiança no aplicativo e traz riscos que não estão presentes em outros fluxos. Use-o somente 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ícita e as seções a seguir descrevem cada etapa em detalhes.
Cenários adequados para a concessão implícita OAuth2
A concessão implícita é apenas confiável para a parte inicial e interativa do seu fluxo de entrada, em que a falta de cookies de terceiros não pode afetar o seu aplicativo. Essa limitação significa que você deve usá-la exclusivamente como parte do fluxo híbrido, em que seu aplicativo solicita um código e um token do ponto de extremidade de autorização. Em um fluxo híbrido, o seu aplicativo recebe um código que pode ser resgatado para um token de atualização, garantindo assim que a sessão de logon do aplicativo permaneça válida ao longo do tempo.
Prefira o fluxo do código de autenticação
Como alguns navegadores removeram o suporte a cookies de terceiros, o fluxo de concessão implícita não é mais um método de autenticação adequado. As funcionalidades de SSO (logon único) silenciosas 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 dá 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 fluxo de concessão implícito
O fluxo de concessão implícita destina-se a aplicativos Web tradicionais em que o servidor tem controle sobre o processamento de dados POST com segurança. Há duas maneiras principais de entregar tokens com o fluxo de concessão implícita: com response_mode
retornado como um fragmento de URL ou como um parâmetro de consulta (usando form POST
e GET
). No fluxo implícito em que response_mode=form_post
, o token é entregue com segurança por meio de um formulário HTML POST 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 por meio do histórico do navegador ou dos cabeçalhos do referenciador.
As preocupações de segurança com o fluxo implícito surgem quando os tokens são entregues usando response_mode=fragment
. O fragmento de URL é a parte do URL que vem após o símbolo #
e não é enviado ao 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 um token de ID seja emitido quando solicitado usando a concessão implícita ou o 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 de ID seja emitido quando solicitado usando a concessão implícita ou o fluxo híbrido no registro do aplicativo. Se você (ou os desenvolvedores) estiver usando a MSAL no seu aplicativo para implementar a autenticação e a autorização, nenhum campo precisará ser habilitado.
No entanto, se você ou seus desenvolvedores não estiverem usando o MSAL em seu aplicativo, a tabela a seguir define quando os tokens de acesso ou o token de ID devem ser habilitados.
Tipo de aplicativo que você está criando | Tokens que você deve habilitar no registro de 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 e tokens de ID |
Um aplicativo Web ou SPA que chama uma API Web via JavaScript usando fluxo implícito | Tokens de acesso e tokens de ID |
Um aplicativo Web ASP.NET Core e outros aplicativos Web que usam a autenticação híbrida | Tokens de ID |
Enviar a solicitação de conexão
Para autenticar inicialmente o usuário em seu aplicativo, você pode enviar uma solicitação de autenticação OpenID Connect e obter um id_token
da plataforma de identidade da Microsoft.
Importante
Para solicitar um token de ID e/ou um token de acesso com sucesso, o registro de aplicativo na página do centro de administração do Microsoft Entra – Registros de aplicativo precisa ter o fluxo de concessão implícita 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, será retornado um erro unsupported_response
:
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 valor {tenant} 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. Criticamente, para cenários de convidado em que você conecta um usuário de um locatário a outro locatário, você deve fornecer o identificador de locatário para que ele se conecte corretamente no locatário do recurso. |
client_id |
obrigatório | A ID do aplicativo (cliente) que a página do centro de administração do Microsoft Entra – Registros de aplicativo atribui ao seu aplicativo. |
response_type |
obrigatório | Deve incluir id_token para conexão do OpenID Connect. Também pode incluir o response_type , token . O uso de token aqui permite que seu aplicativo receba imediatamente um token de acesso do ponto de extremidade de /authorize sem precisar fazer uma segunda solicitação ao ponto de extremidade /authorize. Se você usar o response_type token , o parâmetro scope 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 token para fornecer um código de autorização para uso no fluxo do código de autorização. Essa resposta id_token +code às vezes é chamada de fluxo híbrido. |
redirect_uri |
recomendável | O URI de redirecionamento do seu aplicativo, no qual as respostas de autenticação são enviadas e recebidas em seu aplicativo. Ele deve corresponder exatamente a uma das URIs de redirecionamento que você registrou no Centro de administração do Microsoft Entra, exceto que ela deve ser codificada em URL. |
scope |
obrigatório | Uma lista de escopos separados por espaços. Para o OpenID Connect (id_tokens ), é necessário incluir o escopo openid , que é traduzido para a permissão "Fazer seu logon" na interface do usuário de consentimento. Como opção, convém incluir os escopos email e profile para obter acesso a dados adicionais do usuário. Você também poderá incluir outros escopos nessa solicitação a fim de solicitar o consentimento a vários recursos, se um token de acesso for solicitado. |
response_mode |
recomendável | Especifica o método que deve ser usado para enviar o token resultante de volta ao aplicativo. O padrão é query para apenas um token de acesso, mas é fragment caso a solicitação inclua 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 |
recomendável | 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. Um valor exclusivo gerado aleatoriamente normalmente é usado para impedir ataques de solicitação intersite forjada. O estado também é usado para codificar informações sobre o estado do usuário no aplicativo antes que a solicitação de autenticação ocorra, como a página ou a exibição em que ele estava. |
nonce |
obrigatório | Um valor incluído na solicitação, gerado pelo aplicativo, que está incluído no token de ID resultante como uma reivindicação. O aplicativo pode, então, verificar esse valor para atenuar os ataques de reproduçã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. Obrigatório somente quando um id_token é solicitado. |
prompt |
opcionais | Indica o tipo de interação do usuário que é necessário. Os únicos valores válidos no momento são login , none , select_account e consent . prompt=login força o usuário a inserir as credenciais na solicitação, negando o logon único. prompt=none é o oposto – ele garante que não seja apresentado nenhum prompt interativo ao usuário. 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 conta em que todas as contas lembradas na sessão serão exibidas. prompt=consent irá disparar a caixa de diálogo de consentimento do OAuth depois que o usuário iniciar a sessão, solicitando que ele conceda permissões ao aplicativo. |
login_hint |
opcionais | Você pode usar esse parâmetro para pré-armazenar o nome de usuário e o campo de endereço de email 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á terem extraído a login_hint declaração opcional de uma entrada anterior. |
domain_hint |
opcionais | Se for incluído, ele ignorará o processo de descoberta baseada em email que o usuário passa na página de entrada, resultando em uma experiência de usuário um pouco mais simples. Esse parâmetro é usado normalmente para aplicativos de linha de negócios que operam em um único locatário, no qual eles fornecerão um nome de domínio dentro de um determinado locatário, encaminhando o usuário para o provedor de federação para esse locatário. Essa dica impede que os convidados entrem neste aplicativo e limita o uso de credenciais de nuvem como FIDO. |
Nesse ponto, é solicitado que o usuário insira suas credenciais e conclua a autenticação. A plataforma de identidade da Microsoft garante que o usuário tenha dado as permissões indicadas no parâmetro de consulta scope
. Se o usuário não consentir a nenhuma dessas permissões, ele será solicitado a consentir às permissões necessárias. Para obter mais informações, confira Permissões, consentimento e aplicativos multilocatário.
Depois que o usuário autenticar e der consentimento, a plataforma de identidade da Microsoft retornará uma resposta ao aplicativo no redirect_uri
indicado, usando o método especificado no parâmetro response_mode
.
Resposta bem-sucedida
Uma resposta bem-sucedida usando response_mode=fragment
e response_type=id_token+code
é semelhante ao 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 | Descrição |
---|---|
code |
Incluído se response_type incluir 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 incluir 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 incluir token . Isso é sempre um Bearer . |
expires_in |
Incluído se response_type incluir token . Indica o número de segundos pelos quais o token é válido para fins de cache. |
scope |
Incluído se response_type incluir token . Indica um ou mais escopos para os quais o access_token é válido. Talvez não inclua todos os escopos solicitados se eles não forem aplicáveis ao usuário. Por exemplo, escopos somente Microsoft Entra solicitados ao fazer logon usando uma conta pessoal. |
id_token |
Um JWT (JSON Web Token) assinado. O aplicativo pode decodificar os segmentos desse token para solicitar informações sobre o usuário que se conectou. O aplicativo pode armazenar em cache os valores e exibi-los, mas não deve confiar neles para nenhuma autorização ou limite de segurança. Para obter mais informações sobre tokens de ID, confira id_token reference . Observação: somente fornecido se o escopo openid for solicitado e se response_type tiver 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 nem ler tokens de APIs que não sejam suas em seu código, incluindo os tokens deste exemplo. Os tokens de 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 do consumidor (conta Microsoft). Embora a leitura de tokens seja uma ferramenta útil de depuração e aprendizagem, não assuma dependências disso em seu código ou assuma informações específicas sobre tokens que não são de uma API que você controla.
Resposta de erro
As respostas de erro também podem ser enviadas ao redirect_uri
para que o aplicativo possa tratá-las adequadamente:
GET https://localhost/myapp/#
error=access_denied
&error_description=the+user+canceled+the+authentication
Parâmetro | Descrição |
---|---|
error |
Uma cadeia de caracteres de códigos de erro que pode ser usada para classificar tipos de erro que ocorrem e pode ser usada para responder aos 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. |
Adquirir tokens de acesso silenciosamente
Agora que seu usuário fez login em seu aplicativo de página única, pode silenciosamente obter tokens de acesso para chamar APIs Web protegidas pela plataforma de identidade da Microsoft, como o Microsoft Graph. Mesmo se já tiver recebido um token usando o response_type token
, você poderá usar esse método para adquirir tokens para recursos adicionais sem redirecionar o usuário para entrar novamente.
Importante
Essa parte do fluxo implícito provavelmente não funcionará 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 em Chromium que não estão em Incognito, os desenvolvedores devem reconsiderar o uso dessa parte do fluxo. Em navegadores que não dão suporte a cookies de terceiros, você receberá um erro indicando que nenhum usuário está conectado, pois os cookies de sessão da página de logon foram removidos pelo navegador.
No fluxo normal de OpenID Connect/OAuth, você faria isso por meio de uma solicitação para o ponto de extremidade /token
da plataforma 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 entrada.
Dica
Tente copiar e colar a seguinte solicitação em uma guia do navegador usando um real client_id
e username
do registro do seu aplicativo. Isso permitirá que você veja a solicitação de token silenciosa 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 de navegador, em vez de abri-lo em um iframe.
Graças ao parâmetro prompt=none
, essa solicitação tem êxito ou falha imediatamente e retorna ao seu aplicativo. A resposta bem-sucedida é enviada ao seu aplicativo no redirect_uri
indicado, usando o método especificado no parâmetro response_mode
.
Resposta bem-sucedida
Uma resposta bem-sucedida usando response_mode=fragment
tem a seguinte aparência:
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 | Descrição |
---|---|
access_token |
Incluído se response_type incluir token . O token de acesso solicitado pelo aplicativo, nesse 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 |
Isso é sempre um Bearer . |
expires_in |
Indica o número de segundos pelos quais 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 eram aplicáveis ao usuário (se escopos somente do Microsoft Entra sendo solicitados quando uma conta pessoal é usada para fazer login). |
id_token |
Um JWT (JSON Web Token) assinado. Incluído se response_type incluir id_token . O aplicativo pode decodificar os segmentos desse token para solicitar informações sobre o usuário que se conectou. O aplicativo pode armazenar em cache os valores e exibi-los, mas não deve confiar neles para nenhuma autorização ou limite de segurança. Para obter mais informações sobre id_tokens, veja a referência id_token . Observação: Somente fornecido se o escopo openid for 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 ao redirect_uri
para que o aplicativo possa tratá-las 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 | Descrição |
---|---|
error |
Uma cadeia de caracteres de códigos de erro que pode ser usada para classificar tipos de erro que ocorrem e pode ser usada para responder aos 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 do iframe, o usuário deverá entrar novamente de forma interativa para recuperar um novo token. Você pode escolher lidar com isso da maneira que fizer mais sentido para seu aplicativo.
Atualizando tokens
A concessão implícita não fornece tokens de atualização. Os tokens de ID e 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 de iframe oculto definida anteriormente usando o parâmetro prompt=none
para controlar o comportamento da plataforma de identidade. Se você deseja receber um novo token de ID, certifique-se de usar id_token
em response_type
e scope=openid
, bem como um parâmetro nonce
.
Em navegadores que não dão suporte a 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 o 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 desconectar por completo um usuário de um aplicativo Web, seu aplicativo deve encerrar sua própria sessão com o usuário (normalmente, limpando o cache de token ou removendo cookies) e, depois, 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 valor {tenant} 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 |
recomendável | A URL para a qual o usuário deve retornar após a conclusão da saída. Esse valor deve corresponder a um dos URIs de redirecionamento registrados no aplicativo. Se ele não estiver incluído, o usuário vê uma mensagem genérica pela plataforma de identidade da Microsoft. |
Confira também
- Percorra os exemplos de MSAL JS para começar a codificação.
- Examine o fluxo do código de autorização como uma alternativa mais nova e melhor para a concessão implícita.