Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Importante
A partir de 1º de maio de 2025, o Azure AD B2C não estará mais disponível para compra para novos clientes. Saiba mais nas nossas Perguntas Frequentes.
Este artigo mostra como adicionar a autenticação do Azure Ative Directory B2C (Azure AD B2C) ao seu próprio aplicativo de página única (SPA). Saiba como criar um aplicativo SPA usando a Biblioteca de Autenticação da Microsoft para JavaScript (MSAL.js).
Use este artigo com Configurar autenticação em um aplicativo SPA de exemplo, substituindo o aplicativo SPA de exemplo por seu próprio aplicativo SPA.
Visão geral
Este artigo usa o Node.js e o Express para criar um aplicativo Web Node.js básico. O Express é uma estrutura de aplicativo Web Node.js mínima e flexível que fornece um conjunto de recursos para aplicativos Web e móveis.
A biblioteca de autenticaçãoMSAL.js é uma biblioteca fornecida pela Microsoft que simplifica a adição de suporte de autenticação e autorização a aplicativos SPA.
Sugestão
Todo o código MSAL.js é executado no lado do cliente. Você pode substituir o código do lado do servidor Node.js e Express por outras soluções, como linguagens de script .NET Core, Java e Hypertext Preprocessor (PHP).
Pré-requisitos
Para revisar os pré-requisitos e as instruções de integração, consulte Configurar a autenticação em um aplicativo SPA de exemplo.
Etapa 1: Criar um projeto de aplicativo SPA
Você pode usar um projeto de aplicativo SPA existente ou criar um novo. Para criar um novo projeto, faça o seguinte:
Abra um shell de comando e crie um novo diretório (por exemplo, myApp). Esse diretório conterá o código do aplicativo, a interface do usuário e os arquivos de configuração.
Insira o diretório que você criou.
Use o
npm initcomando para criar umpackage.jsonarquivo para seu aplicativo. Este comando solicita informações sobre seu aplicativo (por exemplo, o nome e a versão do aplicativo e o nome do ponto de entrada inicial, o arquivo index.js ). Execute o seguinte comando e aceite os valores padrão:
npm init
Etapa 2: Instalar as dependências
Para instalar o pacote Express, no shell de comando, execute o seguinte comando:
npm install express
Para localizar os arquivos estáticos do aplicativo, o código do lado do servidor usa o pacote Path .
Para instalar o pacote Path, no shell de comando, execute o seguinte comando:
npm install path
Etapa 3: Configurar o servidor Web
Na pasta myApp , crie um arquivo chamado index.js, que contém o seguinte código:
// Initialize express
const express = require('express');
const app = express();
// The port to listen to incoming HTTP requests
const port = 6420;
// Initialize path
const path = require('path');
// Set the front-end folder to serve public assets.
app.use(express.static('App'));
// Set up a route for the index.html
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname + '/index.html'));
});
// Start the server, and listen for HTTP requests
app.listen(port, () => {
console.log(`Listening on http://localhost:${port}`);
});
Etapa 4: Criar a interface do usuário do SPA
Adicione o ficheiro do aplicativo SPA index.html. Esse arquivo implementa uma interface de usuário criada com uma estrutura de Bootstrap e importa arquivos de script para configuração, autenticação e chamadas de API da Web.
Os recursos referenciados pelo arquivo index.html são detalhados na tabela a seguir:
| Referência | Definição |
|---|---|
| MSAL.js biblioteca | Caminho CDN da biblioteca JavaScript de autenticação MSAL.js. |
| Folha de estilo do Bootstrap | Uma estrutura de front-end gratuita para um desenvolvimento web mais rápido e fácil. A estrutura inclui modelos de design baseados em HTML e CSS. |
Para renderizar o arquivo de índice SPA, na pasta myApp , crie um arquivo chamado index.html, que contém o seguinte trecho HTML:
<!DOCTYPE html>
<html>
<head>
<title>My Azure AD B2C test app</title>
</head>
<body>
<h2>My Azure AD B2C test app</h2>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous" />
<button type="button" id="signIn" class="btn btn-secondary" onclick="signIn()">Sign-in</button>
<button type="button" id="signOut" class="btn btn-success d-none" onclick="signOut()">Sign-out</button>
<h5 id="welcome-div" class="card-header text-center d-none"></h5>
<br />
<!-- Content -->
<div class="card">
<div class="card-body text-center">
<pre id="response" class="card-text"></pre>
<button type="button" id="callApiButton" class="btn btn-primary d-none" onclick="passTokenToApi()">Call API</button>
</div>
</div>
<script src="https://alcdn.msauth.net/browser/2.14.2/js/msal-browser.min.js" integrity="sha384-ggh+EF1aSqm+Y4yvv2n17KpurNcZTeYtUZUvhPziElsstmIEubyEB6AIVpKLuZgr" crossorigin="anonymous"></script>
<!-- Importing app scripts (load order is important) -->
<script type="text/javascript" src="./apiConfig.js"></script>
<script type="text/javascript" src="./policies.js"></script>
<script type="text/javascript" src="./authConfig.js"></script>
<script type="text/javascript" src="./ui.js"></script>
<!-- <script type="text/javascript" src="./authRedirect.js"></script> -->
<!-- uncomment the above line and comment the line below if you would like to use the redirect flow -->
<script type="text/javascript" src="./authRedirect.js"></script>
<script type="text/javascript" src="./api.js"></script>
</body>
</html>
Etapa 5: Configurar a biblioteca de autenticação
Configure como a biblioteca de MSAL.js se integra ao Azure AD B2C. A biblioteca MSAL.js utiliza um objeto de configuração comum para se conectar aos pontos de extremidade de autenticação do tenant no Azure AD B2C.
Para configurar a biblioteca de autenticação, faça o seguinte:
Na pasta myApp , crie uma nova pasta chamada App.
Dentro da pasta Aplicativo , crie um novo arquivo chamado authConfig.js.
Adicione o seguinte código JavaScript ao arquivo authConfig.js :
const msalConfig = { auth: { clientId: "<Application-ID>", authority: b2cPolicies.authorities.signUpSignIn.authority, knownAuthorities: [b2cPolicies.authorityDomain], redirectUri: "http://localhost:6420", }, cache: { cacheLocation: "localStorage", . storeAuthStateInCookie: false, } }; const loginRequest = { scopes: ["openid", ...apiConfig.b2cScopes], }; const tokenRequest = { scopes: [...apiConfig.b2cScopes], forceRefresh: false };Substitua
<Application-ID>pelo ID de registo da aplicação. Para obter mais informações, consulte Configurar a autenticação em um aplicativo SPA de exemplo.
Sugestão
Para obter mais opções de configuração de objeto MSAL, consulte o artigo Opções de autenticação .
Etapa 6: Especificar seus fluxos de usuário do Azure AD B2C
Crie o arquivo policies.js , que fornece informações sobre seu ambiente do Azure AD B2C. A biblioteca de MSAL.js usa essas informações para criar solicitações de autenticação para o Azure AD B2C.
Para especificar seus fluxos de usuário do Azure AD B2C, faça o seguinte:
Dentro da pasta Aplicativo , crie um novo arquivo chamado policies.js.
Adicione o seguinte código ao arquivo policies.js :
const b2cPolicies = { names: { signUpSignIn: "B2C_1_SUSI", editProfile: "B2C_1_EditProfile" }, authorities: { signUpSignIn: { authority: "https://contoso.b2clogin.com/contoso.onmicrosoft.com/Your-B2C-SignInOrSignUp-Policy-Id", }, editProfile: { authority: "https://contoso.b2clogin.com/contoso.onmicrosoft.com/Your-B2C-EditProfile-Policy-Id" } }, authorityDomain: "contoso.b2clogin.com" }Substitua
B2C_1_SUSIpelo nome da política de entrada do Azure AD B2C.Substitua
B2C_1_EditProfilepelo nome da política do Azure AD B2C do seu perfil de edição.Substitua todas as instâncias de
contosopelo seu nome do tenant do Azure AD B2C.
Etapa 7: Usar o MSAL para entrar no usuário
Nesta etapa, implemente os métodos para inicializar o fluxo de entrada, a aquisição de token de acesso à API e os métodos de saída.
Para obter mais informações, consulte o artigo Usar a Biblioteca de Autenticação da Microsoft (MSAL) para entrar no usuário .
Para entrar no usuário, faça o seguinte:
Dentro da pasta Aplicativo , crie um novo arquivo chamado authRedirect.js.
No seu authRedirect.js, copie e cole o seguinte código:
// Create the main myMSALObj instance // configuration parameters are located at authConfig.js const myMSALObj = new msal.PublicClientApplication(msalConfig); let accountId = ""; let idTokenObject = ""; let accessToken = null; myMSALObj.handleRedirectPromise() .then(response => { if (response) { /** * For the purpose of setting an active account for UI update, we want to consider only the auth response resulting * from SUSI flow. "tfp" claim in the id token tells us the policy (NOTE: legacy policies may use "acr" instead of "tfp"). * To learn more about B2C tokens, visit https://v4.hkg1.meaqua.org/azure/active-directory-b2c/tokens-overview */ if (response.idTokenClaims['tfp'].toUpperCase() === b2cPolicies.names.signUpSignIn.toUpperCase()) { handleResponse(response); } } }) .catch(error => { console.log(error); }); function setAccount(account) { accountId = account.homeAccountId; idTokenObject = account.idTokenClaims; myClaims= JSON.stringify(idTokenObject); welcomeUser(myClaims); } function selectAccount() { /** * See here for more information on account retrieval: * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/Accounts.md */ const currentAccounts = myMSALObj.getAllAccounts(); if (currentAccounts.length < 1) { return; } else if (currentAccounts.length > 1) { /** * Due to the way MSAL caches account objects, the auth response from initiating a user-flow * is cached as a new account, which results in more than one account in the cache. Here we make * sure we are selecting the account with homeAccountId that contains the sign-up/sign-in user-flow, * as this is the default flow the user initially signed-in with. */ const accounts = currentAccounts.filter(account => account.homeAccountId.toUpperCase().includes(b2cPolicies.names.signUpSignIn.toUpperCase()) && account.idTokenClaims.iss.toUpperCase().includes(b2cPolicies.authorityDomain.toUpperCase()) && account.idTokenClaims.aud === msalConfig.auth.clientId ); if (accounts.length > 1) { // localAccountId identifies the entity for which the token asserts information. if (accounts.every(account => account.localAccountId === accounts[0].localAccountId)) { // All accounts belong to the same user setAccount(accounts[0]); } else { // Multiple users detected. Logout all to be safe. signOut(); }; } else if (accounts.length === 1) { setAccount(accounts[0]); } } else if (currentAccounts.length === 1) { setAccount(currentAccounts[0]); } } // in case of page refresh selectAccount(); async function handleResponse(response) { if (response !== null) { setAccount(response.account); } else { selectAccount(); } } function signIn() { myMSALObj.loginRedirect(loginRequest); } function signOut() { const logoutRequest = { postLogoutRedirectUri: msalConfig.auth.redirectUri, }; myMSALObj.logoutRedirect(logoutRequest); } function getTokenRedirect(request) { request.account = myMSALObj.getAccountByHomeId(accountId); return myMSALObj.acquireTokenSilent(request) .then((response) => { // In case the response from B2C server has an empty accessToken field // throw an error to initiate token acquisition if (!response.accessToken || response.accessToken === "") { throw new msal.InteractionRequiredAuthError; } else { console.log("access_token acquired at: " + new Date().toString()); accessToken = response.accessToken; passTokenToApi(); } }).catch(error => { console.log("Silent token acquisition fails. Acquiring token using popup. \n", error); if (error instanceof msal.InteractionRequiredAuthError) { // fallback to interaction when silent call fails return myMSALObj.acquireTokenRedirect(request); } else { console.log(error); } }); } // Acquires and access token and then passes it to the API call function passTokenToApi() { if (!accessToken) { getTokenRedirect(tokenRequest); } else { try { callApi(apiConfig.webApi, accessToken); } catch(error) { console.log(error); } } } function editProfile() { const editProfileRequest = b2cPolicies.authorities.editProfile; editProfileRequest.loginHint = myMSALObj.getAccountByHomeId(accountId).username; myMSALObj.loginRedirect(editProfileRequest); }
Etapa 8: Configurar o local e o escopo da API Web
Para permitir que seu aplicativo SPA chame uma API da Web, forneça o local do ponto de extremidade da API da Web e os escopos a serem usados para autorizar o acesso à API da Web.
Para configurar o local e os escopos da API Web, faça o seguinte:
Dentro da pasta Aplicativo , crie um novo arquivo chamado apiConfig.js.
No seu apiConfig.js, copie e cole o seguinte código:
// The current application coordinates were pre-registered in a B2C tenant. const apiConfig = { b2cScopes: ["https://contoso.onmicrosoft.com/tasks/tasks.read"], webApi: "https://mydomain.azurewebsites.net/tasks" };Substitua
contosopelo nome do locatário. O nome do escopo necessário pode ser encontrado conforme descrito no artigo Configurar escopos .Substitua o valor por
webApipelo local do endpoint da sua API da Web.
Etapa 9: Chame sua API da Web
Defina a solicitação HTTP para seu ponto de extremidade da API. A solicitação HTTP é configurada para inserir o token de acesso adquirido com MSAL.js no cabeçalho HTTP da solicitação.
O código seguinte define o pedido HTTP GET para o ponto de acesso da API, passando o token de acesso no Authorization cabeçalho HTTP. O local da webApi API é definido pela chave em apiConfig.js.
Para chamar sua API da Web usando o token adquirido, faça o seguinte:
Dentro da pasta Aplicativo , crie um novo arquivo chamado api.js.
Adicione o seguinte código ao arquivo api.js :
function callApi(endpoint, token) { const headers = new Headers(); const bearer = `Bearer ${token}`; headers.append("Authorization", bearer); const options = { method: "GET", headers: headers }; logMessage('Calling web API...'); fetch(endpoint, options) .then(response => response.json()) .then(response => { if (response) { logMessage('Web API responded: ' + response.name); } return response; }).catch(error => { console.error(error); }); }
Etapa 10: Adicionar a referência de elementos da interface do usuário
O aplicativo SPA usa JavaScript para controlar os elementos da interface do usuário. Por exemplo, exibe os botões de iniciar e terminar sessão e exibe as afirmações do token de ID dos utilizadores no ecrã.
Para adicionar a referência de elementos da interface do usuário, faça o seguinte:
Dentro da pasta Aplicativo , crie um arquivo chamado ui.js.
Adicione o seguinte código ao arquivo ui.js :
// Select DOM elements to work with const signInButton = document.getElementById('signIn'); const signOutButton = document.getElementById('signOut') const titleDiv = document.getElementById('title-div'); const welcomeDiv = document.getElementById('welcome-div'); const tableDiv = document.getElementById('table-div'); const tableBody = document.getElementById('table-body-div'); const editProfileButton = document.getElementById('editProfileButton'); const callApiButton = document.getElementById('callApiButton'); const response = document.getElementById("response"); const label = document.getElementById('label'); function welcomeUser(claims) { welcomeDiv.innerHTML = `Token claims: </br></br> ${claims}!` signInButton.classList.add('d-none'); signOutButton.classList.remove('d-none'); welcomeDiv.classList.remove('d-none'); callApiButton.classList.remove('d-none'); } function logMessage(s) { response.appendChild(document.createTextNode('\n' + s + '\n')); }
Etapa 11: Executar seu aplicativo SPA
No shell de comando, execute os seguintes comandos:
npm install
npm ./index.js
- Ir para https://localhost:6420.
- Selecione Iniciar sessão.
- Conclua o processo de inscrição ou login.
Depois de autenticar-se com êxito, o token de ID analisado é exibido no ecrã. Selecione Call API para invocar o ponto de extremidade da API.
Próximos passos
- Saiba mais sobre o exemplo de código.
- Configure as opções de Autenticação em seu próprio aplicativo SPA usando o Azure AD B2C.
- Habilite a autenticação em sua própria API da Web.