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.
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 exemplob2c_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_up ou 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 token de resposta . Se utilizar token o , 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
emid_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 ostate
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 eexp
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_up ou 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 token de 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.