Início de sessão de aplicação de página única com o fluxo implícito OAuth 2.0 no Azure Active Directory B2C

Muitas aplicações modernas têm um front-end de aplicação de página única (SPA) escrito principalmente em JavaScript. Muitas vezes, a aplicação é escrita através de uma arquitetura como React, Angular ou Vue.js. Os SPAs e outras aplicações JavaScript que são executadas principalmente num browser têm alguns desafios adicionais para a autenticação:

  • As características de segurança destas aplicações são diferentes das aplicações Web tradicionais baseadas no servidor.

  • Muitos servidores de autorização e fornecedores de identidade não suportam pedidos de partilha de recursos transversais à origem (CORS).

  • Os redirecionamentos de browser de página inteira para fora da aplicação podem ser invasivos para a experiência do utilizador.

A forma recomendada de suportar SPAs é o fluxo de código de autorização OAuth 2.0 (com PKCE).

Algumas arquiteturas, como MSAL.js 1.x, suportam apenas o fluxo de concessão implícita. Nestes casos, o Azure Active Directory B2C (Azure AD B2C) suporta o fluxo de concessão implícita de autorização do OAuth 2.0. O fluxo é descrito na secção 4.2 da especificação OAuth 2.0. No fluxo implícito, a aplicação recebe tokens diretamente do Azure AD ponto final de autorização B2C, sem qualquer troca servidor a servidor. Todas as lógicas de autenticação e processamento de sessões são realizadas inteiramente no cliente JavaScript com um redirecionamento de página ou uma caixa de pop-up.

Azure AD B2C expande o fluxo implícito OAuth 2.0 padrão para mais do que a autenticação e autorização simples. Azure AD B2C introduz o parâmetro de política. Com o parâmetro de política, pode utilizar o OAuth 2.0 para adicionar políticas à sua aplicação, tais como fluxos de utilizador de inscrição, início de sessão e gestão de perfis. No exemplo de pedidos HTTP neste artigo, utilizamos {tenant}.onmicrosoft.com para ilustração. Substitua {tenant}pelo nome do seu inquilino , se tiver um. Além disso, precisa de ter criado um fluxo de utilizador.

Utilizamos a figura seguinte para ilustrar o fluxo de início de sessão implícito. Cada passo é descrito em detalhe mais à frente no artigo.

Diagrama estilo pista de diagrama a mostrar o fluxo implícito openID Connect

Enviar pedidos de autenticação

Quando a sua aplicação Web precisar de autenticar o utilizador e executar um fluxo de utilizador, direciona o utilizador para o Azure AD ponto final do /authorize B2C. O utilizador efetua uma ação consoante o fluxo de utilizador.

Neste pedido, o cliente indica as permissões que tem de adquirir ao utilizador no scope parâmetro e o fluxo de utilizador a executar. Para saber como funciona o pedido, experimente colar o pedido num browser e executá-lo. Substituir:

  • {tenant}com o nome do seu Azure AD inquilino B2C.

  • 90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6 com o ID da aplicação que registou no seu inquilino.

  • {policy} com o nome de uma política que criou no seu inquilino, por exemplo b2c_1_sign_in.

GET https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/authorize?
client_id=90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6
&response_type=id_token+token
&redirect_uri=https%3A%2F%2Faadb2cplayground.azurewebsites.net%2F
&response_mode=fragment
&scope=openid%20offline_access
&state=arbitrary_data_you_can_receive_in_the_response
&nonce=12345

Os parâmetros no pedido HTTP GET são explicados na tabela abaixo.

Parâmetro Necessário Description
{tenant} Yes Nome do inquilino do Azure AD B2C
{policy} Yes O nome do fluxo de utilizador que pretende executar. Especifique o nome de um fluxo de utilizador que criou no seu inquilino Azure AD B2C. Por exemplo: b2c_1_sign_in, b2c_1_sign_upou b2c_1_edit_profile.
client_id Yes O ID da aplicação que o portal do Azure atribuído à sua aplicação.
response_type Yes Tem de incluir id_token para o início de sessão do OpenID Connect. Também pode incluir o tipo tokende resposta . Se utilizar tokeno , a sua aplicação pode receber imediatamente um token de acesso do ponto final de autorização, sem fazer um segundo pedido ao ponto final de autorização. Se utilizar o token tipo de resposta, o scope parâmetro tem de conter um âmbito que indique para que recurso emitir o token.
redirect_uri No O URI de redirecionamento da sua aplicação, para onde as respostas de autenticação podem ser enviadas e recebidas pela sua aplicação. Tem de corresponder exatamente a um dos URIs de redirecionamento que adicionou a uma aplicação registada no portal, exceto que tem de ser codificada por URL.
response_mode No Especifica o método a utilizar para enviar o token resultante de volta para a sua aplicação. Para fluxos implícitos, utilize fragment.
scope Yes Uma lista de âmbitos separada por espaços. Um valor de âmbito único indica Microsoft Entra ID de ambas as permissões que estão a ser pedidas. O openid âmbito indica uma permissão para iniciar sessão no utilizador e obter dados sobre o utilizador sob a forma de tokens de ID. O offline_access âmbito é opcional para aplicações Web. Indica que a sua aplicação precisa de um token de atualização para um acesso de longa duração aos recursos.
state No Um valor incluído no pedido que também é devolvido na resposta do token. Pode ser uma cadeia de qualquer conteúdo que pretenda utilizar. Normalmente, é utilizado um valor exclusivo gerado aleatoriamente para impedir ataques de falsificação de pedidos entre sites. O estado também é utilizado para codificar informações sobre o estado do utilizador na aplicação antes de o pedido de autenticação ocorrer, por exemplo, a página em que o utilizador estava ou o fluxo de utilizador que estava a ser executado.
nonce Yes Um valor incluído no pedido (gerado pela aplicação) que está incluído no token de ID resultante como uma afirmação. Em seguida, a aplicação pode verificar este valor para mitigar os ataques de repetição de tokens. Normalmente, o valor é uma cadeia aleatória e exclusiva que pode ser utilizada para identificar a origem do pedido.
pedido de aviso No O tipo de interação do utilizador que é necessário. Atualmente, o único valor válido é login. Este parâmetro força o utilizador a introduzir as respetivas credenciais nesse pedido. As Sign-On não têm efeito.

Esta é a parte interativa do fluxo. É pedido ao utilizador que conclua o fluxo de trabalho da política. O utilizador poderá ter de introduzir o respetivo nome de utilizador e palavra-passe, iniciar sessão com uma identidade social, inscrever-se numa conta local ou qualquer outro número de passos. As ações do utilizador dependem da forma como o fluxo de utilizador é definido.

Depois de o utilizador concluir o fluxo de utilizador, Azure AD B2C devolve uma resposta à sua aplicação através do redirect_uri. Utiliza o método especificado no response_mode parâmetro . A resposta é exatamente a mesma para cada um dos cenários de ação do utilizador, independentemente do fluxo de utilizador que foi executado.

Resposta com êxito

Uma resposta bem-sucedida que utiliza response_mode=fragment e response_type=id_token+token tem o seguinte aspeto, com quebras de linha para legibilidade:

GET https://aadb2cplayground.azurewebsites.net/#
access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...
&token_type=Bearer
&expires_in=3599
&scope="90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6 offline_access",
&id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...
&state=arbitrary_data_you_sent_earlier
Parâmetro Description
access_token O token de acesso que a aplicação pediu ao Azure AD B2C.
token_type O valor do tipo de token. O único tipo que Azure AD B2C suporta é o Portador.
expires_in O período de tempo durante o qual o token de acesso é válido (em segundos).
scope Os âmbitos para os quais o token é válido. Também pode utilizar âmbitos para colocar tokens em cache para utilização posterior.
id_token O token de ID que a aplicação pediu. Pode utilizar o token de ID para verificar a identidade do utilizador e iniciar uma sessão com o utilizador. Para obter mais informações sobre os tokens de ID e os respetivos conteúdos, veja o Azure AD referência do token B2C.
state Se um state parâmetro estiver incluído no pedido, o mesmo valor deverá aparecer na resposta. A aplicação deve verificar se os state valores no pedido e na resposta são idênticos.

Resposta a erros

As respostas de erro também podem ser enviadas para o URI de redirecionamento para que a aplicação possa processá-las adequadamente:

GET https://aadb2cplayground.azurewebsites.net/#
error=access_denied
&error_description=the+user+canceled+the+authentication
&state=arbitrary_data_you_can_receive_in_the_response
Parâmetro Descrição
erro Um código utilizado para classificar tipos de erros que ocorrem.
error_description Uma mensagem de erro específica que pode ajudá-lo a identificar a causa raiz de um erro de autenticação.
state Se um state parâmetro estiver incluído no pedido, o mesmo valor deverá aparecer na resposta. A aplicação deve verificar se os state valores no pedido e na resposta são idênticos.

Validar o token de ID

Receber um token de ID não é suficiente para autenticar o utilizador. Valide a assinatura do token de ID e verifique as afirmações no token de acordo com os requisitos da sua aplicação. Azure AD B2C utiliza Tokens Web JSON (JWTs) e criptografia de chaves públicas para assinar tokens e verificar se são válidos.

Estão disponíveis muitas bibliotecas open source para validar JWTs, consoante o idioma que preferir utilizar. Considere explorar bibliotecas open source disponíveis em vez de implementar a sua própria lógica de validação. Pode utilizar as informações neste artigo para o ajudar a aprender a utilizar corretamente essas bibliotecas.

Azure AD B2C tem um ponto final de metadados do OpenID Connect. Uma aplicação pode utilizar o ponto final para obter informações sobre Azure AD B2C no runtime. Estas informações incluem pontos finais, conteúdos de tokens e chaves de assinatura de tokens. Existe um documento de metadados JSON para cada fluxo de utilizador na sua Azure AD inquilino B2C. Por exemplo, o documento de metadados de um fluxo de utilizador com o nome b2c_1_sign_in num fabrikamb2c.onmicrosoft.com inquilino está localizado em:

https://fabrikamb2c.b2clogin.com/fabrikamb2c.onmicrosoft.com/b2c_1_sign_in/v2.0/.well-known/openid-configuration

Uma das propriedades deste documento de configuração é o jwks_uri. O valor para o mesmo fluxo de utilizador seria:

https://fabrikamb2c.b2clogin.com/fabrikamb2c.onmicrosoft.com/b2c_1_sign_in/discovery/v2.0/keys

Para determinar qual o fluxo de utilizador utilizado para assinar um token de ID (e de onde obter os metadados), pode utilizar qualquer uma das seguintes opções:

  • O nome do fluxo de utilizador está incluído na afirmação acr em id_token. Para obter informações sobre como analisar as afirmações de um token de ID, veja a referência do token B2C Azure AD.

  • Codificar o fluxo de utilizador no valor do state parâmetro quando emitir o pedido. Em seguida, descodifique o state parâmetro para determinar que fluxo de utilizador foi utilizado.

Depois de adquirir o documento de metadados do ponto final de metadados do OpenID Connect, pode utilizar as chaves públicas RSA-256 (localizadas neste ponto final) para validar a assinatura do token de ID. Pode haver várias chaves listadas neste ponto final a qualquer momento, cada uma identificada por um kid. O cabeçalho de id_token também contém uma kid afirmação. Indica qual destas chaves foi utilizada para assinar o token de ID. Para obter mais informações, incluindo saber mais sobre a validação de tokens, veja a referência de tokens Azure AD B2C.

Depois de validar a assinatura do token de ID, várias afirmações requerem verificação. Por exemplo:

  • Valide a nonce afirmação para impedir ataques de repetição de tokens. O respetivo valor deve ser o que especificou no pedido de início de sessão.

  • Valide a aud afirmação para garantir que o token de ID foi emitido para a sua aplicação. O respetivo valor deve ser o ID da aplicação da sua aplicação.

  • Valide as iat afirmações e exp para garantir que o token de ID não expirou.

Várias outras validações que deve efetuar são descritas em detalhe na Especificação do OpenID Connect Core. Também poderá querer validar afirmações adicionais, consoante o seu cenário. Algumas validações comuns incluem:

  • Garantir que o utilizador ou organização se inscreveu na aplicação.

  • Garantir que o utilizador tem autorização e privilégios adequados.

  • Garantir que ocorreu uma certa força de autenticação, como, por exemplo, ao utilizar Microsoft Entra autenticação multifator.

Para obter mais informações sobre as afirmações num token de ID, veja o Azure AD referência do token B2C.

Depois de validar o token de ID, pode iniciar uma sessão com o utilizador. Na sua aplicação, utilize as afirmações no token de ID para obter informações sobre o utilizador. Estas informações podem ser utilizadas para apresentação, registos, autorização, etc.

Obter tokens de acesso

Se a única coisa que as suas aplicações Web precisam de fazer é executar fluxos de utilizador, pode ignorar as secções seguintes. As informações nas secções seguintes aplicam-se apenas às aplicações Web que precisam de efetuar chamadas autenticadas para uma API Web protegida pelo próprio Azure AD B2C.

Agora que iniciou sessão com o utilizador no SPA, pode obter tokens de acesso para chamar APIs Web protegidas por Microsoft Entra ID. Mesmo que já tenha recebido um token com o token tipo de resposta, pode utilizar este método para adquirir tokens para recursos adicionais sem redirecionar o utilizador para iniciar sessão novamente.

Num fluxo de aplicação Web típico, faria um pedido ao /token ponto final. No entanto, o ponto final não suporta pedidos CORS, pelo que fazer chamadas AJAX para obter um token de atualização não é uma opção. Em vez disso, pode utilizar o fluxo implícito num elemento iframe HTML oculto para obter novos tokens para outras APIs Web. Eis um exemplo, com quebras de linha para legibilidade:

https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/authorize?
client_id=90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6
&response_type=token
&redirect_uri=https%3A%2F%2Faadb2cplayground.azurewebsites.net%2F
&scope=https%3A%2F%2Fapi.contoso.com%2Ftasks.read
&response_mode=fragment
&state=arbitrary_data_you_can_receive_in_the_response
&nonce=12345
&prompt=none
Parâmetro Necessário? Description
{tenant} Necessário Nome do seu inquilino Azure AD B2C
{policy} Necessário O fluxo de utilizador a ser executado. Especifique o nome de um fluxo de utilizador que criou no seu inquilino Azure AD B2C. Por exemplo: b2c_1_sign_in, b2c_1_sign_upou b2c_1_edit_profile.
client_id Necessário O ID da aplicação atribuído à sua aplicação no portal do Azure.
response_type Necessário Tem de incluir id_token para o início de sessão do OpenID Connect. Também pode incluir o tipo tokende resposta . Se utilizar token aqui, a sua aplicação pode receber imediatamente um token de acesso a partir do ponto final de autorização, sem fazer um segundo pedido para o ponto final de autorização. Se utilizar o token tipo de resposta, o scope parâmetro tem de conter um âmbito que indique para que recurso emitir o token.
redirect_uri Recomendado O URI de redirecionamento da sua aplicação, onde as respostas de autenticação podem ser enviadas e recebidas pela sua aplicação. Tem de corresponder exatamente a um dos URIs de redirecionamento que registou no portal, exceto que tem de estar codificado com URL.
scope Necessário Uma lista de âmbitos separados por espaço. Para obter tokens, inclua todos os âmbitos necessários para o recurso pretendido.
response_mode Recomendado Especifica o método utilizado para enviar o token resultante de volta para a sua aplicação. Para fluxo implícito, utilize fragment. Podem ser especificados query dois outros modos e form_post, mas não funcionam no fluxo implícito.
state Recomendado Um valor incluído no pedido que é devolvido na resposta do token. Pode ser uma cadeia de qualquer conteúdo que pretenda utilizar. Normalmente, é utilizado um valor exclusivo gerado aleatoriamente para evitar ataques de falsificação de pedidos entre sites. O estado também é utilizado para codificar informações sobre o estado do utilizador na aplicação antes do pedido de autenticação ter ocorrido. Por exemplo, a página ou vista em que o utilizador se encontrava.
nonce Necessário Um valor incluído no pedido, gerado pela aplicação incluída no token de ID resultante como uma afirmação. Em seguida, a aplicação pode verificar este valor para mitigar os ataques de repetição de tokens. Normalmente, o valor é uma cadeia aleatória e exclusiva que identifica a origem do pedido.
pedido Necessário Para atualizar e obter tokens num iframe oculto, utilize prompt=none para garantir que o iframe não fica bloqueado na página de início de sessão e devolve imediatamente.
login_hint Necessário Para atualizar e obter tokens num iframe oculto, inclua o nome de utilizador do utilizador nesta sugestão para distinguir entre múltiplas sessões que o utilizador pode ter num determinado momento. Pode extrair o nome de utilizador de um início de sessão anterior com a preferred_username afirmação (o profile âmbito é necessário para receber a preferred_username afirmação).
domain_hint Necessário Pode ser consumers ou organizations. Para atualizar e obter tokens num iframe oculto, inclua o domain_hint valor no pedido. Extraia a tid afirmação do token de ID de um início de sessão anterior para determinar qual o valor a utilizar (o profile âmbito é necessário para receber a tid afirmação). Se o valor da tid afirmação for 9188040d-6c67-4c5b-b112-36a304b66dad, utilize domain_hint=consumers. Caso contrário, utilize domain_hint=organizations.

Ao definir o prompt=none parâmetro, este pedido é bem-sucedido ou falha imediatamente e regressa à sua aplicação. Uma resposta bem-sucedida é enviada para a sua aplicação através do URI de redirecionamento, utilizando o método especificado no response_mode parâmetro.

Resposta bem-sucedida

Uma resposta bem-sucedida ao utilizar response_mode=fragment tem o seguinte aspeto:

GET https://aadb2cplayground.azurewebsites.net/#
access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...
&state=arbitrary_data_you_sent_earlier
&token_type=Bearer
&expires_in=3599
&scope=https%3A%2F%2Fapi.contoso.com%2Ftasks.read
Parâmetro Description
access_token O token que a aplicação pediu.
token_type O tipo de token será sempre Portador.
state Se um state parâmetro estiver incluído no pedido, o mesmo valor deverá aparecer na resposta. A aplicação deve verificar se os state valores no pedido e na resposta são idênticos.
expires_in Durante quanto tempo o token de acesso é válido (em segundos).
scope Os âmbitos para os quais o token de acesso é válido.

Resposta a erros

As respostas de erro também podem ser enviadas para o URI de redirecionamento para que a aplicação possa processá-las adequadamente. Para prompt=none, um erro esperado tem o seguinte aspeto:

GET https://aadb2cplayground.azurewebsites.net/#
error=user_authentication_required
&error_description=the+request+could+not+be+completed+silently
Parâmetro Descrição
erro Uma cadeia de código de erro que pode ser utilizada para classificar tipos de erros que ocorrem. Também pode utilizar a cadeia 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.

Se receber este erro no pedido iframe, o utilizador terá de iniciar sessão interativamente novamente para obter um novo token.

Atualizar tokens

Os tokens de ID e os tokens de acesso expiram após um curto período de tempo. A sua aplicação tem de estar preparada para atualizar estes tokens periodicamente. Os fluxos implícitos não lhe permitem obter um token de atualização por motivos de segurança. Para atualizar qualquer um dos tipos de token, utilize o fluxo implícito num elemento iframe HTML oculto. No pedido de autorização, inclua o prompt=none parâmetro . Para receber um novo valor de id_token, certifique-se de que utiliza response_type=id_token e scope=openid, e um nonce parâmetro.

Enviar um pedido de início de sessão

Quando quiser terminar sessão do utilizador na aplicação, redirecione o utilizador para Azure AD ponto final de fim de sessão do B2C. Em seguida, pode limpar a sessão do utilizador na aplicação. Se não redirecionar o utilizador, este poderá ser capaz de reautilizar novamente para a sua aplicação sem introduzir as respetivas credenciais novamente porque têm uma sessão de Sign-On Única válida com Azure AD B2C.

Pode simplesmente redirecionar o utilizador para o end_session_endpoint que está listado no mesmo documento de metadados do OpenID Connect descrito em Validar o token de ID. Por exemplo:

GET https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/logout?post_logout_redirect_uri=https%3A%2F%2Faadb2cplayground.azurewebsites.net%2F
Parâmetro Necessário Description
{tenant} Yes Nome do seu Azure AD inquilino B2C.
{policy} Yes O fluxo de utilizador que pretende utilizar para terminar a sessão do utilizador na sua aplicação. Este tem de ser o mesmo fluxo de utilizador que a aplicação utilizou para iniciar sessão do utilizador.
post_logout_redirect_uri No O URL para o qual o utilizador deve ser redirecionado após terminar sessão com êxito. Se não estiver incluído, Azure AD B2C mostra ao utilizador uma mensagem genérica.
state No Se um state parâmetro estiver incluído no pedido, o mesmo valor deverá aparecer na resposta. A aplicação deve verificar se os state valores no pedido e na resposta são idênticos.

Nota

Direcionar o utilizador para o end_session_endpoint limpa o estado de Sign-On Único do utilizador com Azure AD B2C. No entanto, não termina a sessão de fornecedor de identidade social do utilizador. Se o utilizador selecionar o mesmo fornecedor de identidade durante um início de sessão subsequente, o utilizador será autenticado novamente sem introduzir as respetivas credenciais. Se um utilizador quiser terminar sessão no seu Azure AD aplicação B2C, isso não significa necessariamente que queira terminar sessão completamente na sua conta do Facebook, por exemplo. No entanto, para contas locais, a sessão do utilizador será terminada corretamente.

Passos seguintes

Veja o exemplo de código: Iniciar sessão com Azure AD B2C num SPA JavaScript.