Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Ważne
Od 1 maja 2025 r. usługa Azure AD B2C nie będzie już dostępna do zakupu dla nowych klientów. Dowiedz się więcej w naszych często zadawanych pytaniach.
W tym artykule pokazano, jak dodać uwierzytelnianie usługi Azure Active Directory B2C (Azure AD B2C) do własnej aplikacji jednostronicowej (SPA). Dowiedz się, jak utworzyć aplikację SPA przy użyciu biblioteki uwierzytelniania firmy Microsoft dla języka JavaScript (MSAL.js).
Użyj tego artykułu wraz z Konfiguracja uwierzytelniania w przykładowej aplikacji SPA, zastępując przykładową aplikację SPA własną.
Przegląd
W tym artykule użyto Node.js i platformy Express do utworzenia podstawowej aplikacji internetowej Node.js. Platforma Express to minimalna i elastyczna platforma aplikacji internetowej Node.js, która udostępnia zestaw funkcji dla aplikacji internetowych i mobilnych.
Biblioteka uwierzytelniania MSAL.js to biblioteka dostarczona przez firmę Microsoft, która upraszcza dodawanie obsługi uwierzytelniania i autoryzacji do aplikacji SPA.
Wskazówka
Cały kod MSAL.js jest uruchamiany po stronie klienta. Kod po stronie serwera Node.js i Express można zastąpić innymi rozwiązaniami, takimi jak języki skryptowe .NET Core, Java i preprocesora hipertekstu (PHP).
Wymagania wstępne
Aby zapoznać się z wymaganiami wstępnymi i instrukcjami dotyczącymi integracji, zobacz Konfigurowanie uwierzytelniania w przykładowej aplikacji SPA.
Krok 1. Tworzenie projektu aplikacji SPA
Możesz użyć istniejącego projektu aplikacji SPA lub utworzyć nowy. Aby utworzyć nowy projekt, wykonaj następujące czynności:
Otwórz powłokę poleceń i utwórz nowy katalog (na przykład myApp). Ten katalog będzie zawierać kod aplikacji, interfejs użytkownika i pliki konfiguracji.
Wprowadź utworzony katalog.
Użyj polecenia ,
npm initaby utworzyćpackage.jsonplik dla aplikacji. To polecenie monituje o podanie informacji o aplikacji (na przykład nazwy i wersji aplikacji oraz nazwy początkowego punktu wejścia, pliku index.js ). Uruchom następujące polecenie i zaakceptuj wartości domyślne:
npm init
Krok 2. Instalowanie zależności
Aby zainstalować pakiet Express, w konsoli uruchom następujące polecenie:
npm install express
Aby zlokalizować pliki statyczne aplikacji, kod po stronie serwera używa pakietu Path .
Aby zainstalować pakiet Path, w powłoce poleceń uruchom następujące polecenie:
npm install path
Krok 3. Konfigurowanie serwera internetowego
W folderze myApp utwórz plik o nazwie index.js, który zawiera następujący kod:
// 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}`);
});
Krok 4. Tworzenie interfejsu użytkownika SPA
Dodaj plik aplikacji index.html SPA. Ten plik implementuje interfejs użytkownika utworzony za pomocą platformy Bootstrap i importuje pliki skryptów na potrzeby konfiguracji, uwierzytelniania i wywołań internetowego interfejsu API.
Zasoby, do których odwołuje się plik index.html , są szczegółowo opisane w poniższej tabeli:
| Źródło | Definicja |
|---|---|
| MSAL.js biblioteka | MSAL.js biblioteka JavaScript uwierzytelniania ścieżka CDN. |
| Arkusz stylów bootstrap | Bezpłatna struktura frontonu umożliwiająca szybsze i łatwiejsze tworzenie aplikacji internetowych. Struktura zawiera szablony projektowe oparte na kodzie HTML i CSS. |
Aby wyrenderować plik indeksu SPA, w folderze myApp utwórz plik o nazwie index.html, który zawiera następujący fragment kodu 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>
Krok 5. Konfigurowanie biblioteki uwierzytelniania
Skonfiguruj sposób integracji biblioteki MSAL.js z usługą Azure AD B2C. Biblioteka MSAL.js używa ogólnego obiektu konfiguracji do łączenia się z punktami końcowymi uwierzytelniania w dzierżawie usługi Azure AD B2C.
Aby skonfigurować bibliotekę uwierzytelniania, wykonaj następujące czynności:
W folderze myApp utwórz nowy folder o nazwie Aplikacja.
W folderze Aplikacja utwórz nowy plik o nazwie authConfig.js.
Dodaj następujący kod JavaScript do pliku 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 };Zastąp
<Application-ID>identyfikatorem aplikacji rejestracji. Aby uzyskać więcej informacji, zobacz Konfigurowanie uwierzytelniania w przykładowej aplikacji SPA.
Wskazówka
Więcej opcji konfiguracji obiektów MSAL znajdziesz w artykule Opcje uwierzytelniania.
Krok 6. Określanie przepływów użytkownika usługi Azure AD B2C
Utwórz plik policies.js , który zawiera informacje o środowisku Azure AD B2C. Biblioteka MSAL.js używa tych informacji do tworzenia żądań uwierzytelniania do usługi Azure AD B2C.
Aby określić przepływy użytkowników usługi Azure AD B2C, wykonaj następujące czynności:
W folderze Aplikacja utwórz nowy plik o nazwie policies.js.
Dodaj następujący kod do pliku 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" }Zastąp
B2C_1_SUSInazwą swojej polityki logowania w usłudze Azure AD B2C.Zastąp
B2C_1_EditProfilenazwą zasad profilów edycji usługi Azure AD B2C.Zastąp wszystkie wystąpienia
contosonazwą dzierżawy usługi Azure AD B2C twojej organizacji.
Krok 7. Logowanie użytkownika przy użyciu biblioteki MSAL
W tym kroku zaimplementuj metody inicjalizacji przepływu logowania, uzyskiwania tokenu dostępu do interfejsu API i metod wylogowywania.
Aby uzyskać więcej informacji, zobacz artykuł Używanie biblioteki Microsoft Authentication Library (MSAL) do logowania użytkownika .
Aby zalogować się do użytkownika, wykonaj następujące czynności:
W folderze Aplikacja utwórz nowy plik o nazwie authRedirect.js.
W authRedirect.jsskopiuj i wklej następujący kod:
// 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://learn.microsoft.com/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); }
Krok 8. Konfigurowanie lokalizacji i zakresu internetowego interfejsu API
Aby umożliwić aplikacji SPA wywołanie internetowego interfejsu API, podaj lokalizację internetowego punktu końcowego interfejsu API i zakresy używane do autoryzowania dostępu do internetowego interfejsu API.
Aby skonfigurować lokalizację i zakresy internetowego interfejsu API, wykonaj następujące czynności:
W folderze Aplikacja utwórz nowy plik o nazwie apiConfig.js.
W apiConfig.jsskopiuj i wklej następujący kod:
// 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" };Zastąp
contosonazwą dzierżawy. Wymagana nazwa zakresu można znaleźć zgodnie z opisem w artykule Konfigurowanie zakresów .Zastąp wartość parametru
webApilokalizacją punktu końcowego internetowego interfejsu API.
Krok 9. Wywoływanie internetowego interfejsu API
Zdefiniuj żądanie HTTP do punktu końcowego interfejsu API. Żądanie HTTP jest skonfigurowane tak, aby przekazywało token dostępu, który został uzyskany za pomocą MSAL.js , do nagłówka Authorization HTTP w żądaniu.
Poniższy kod definiuje żądanie HTTP GET do punktu końcowego interfejsu API, przekazując token dostępu w nagłówku Authorization HTTP. Lokalizacja interfejsu API jest zdefiniowana przez webApi klucz w apiConfig.js.
Aby wywołać internetowy interfejs API przy użyciu uzyskanego tokenu, wykonaj następujące czynności:
W folderze Aplikacja utwórz nowy plik o nazwie api.js.
Dodaj następujący kod do pliku 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); }); }
Krok 10. Dodawanie odwołania do elementów interfejsu użytkownika
Aplikacja SPA używa języka JavaScript do kontrolowania elementów interfejsu użytkownika. Na przykład wyświetla przyciski logowania i wylogowywania oraz renderuje dane tokenu identyfikacyjnego użytkownika na ekranie.
Aby dodać odwołanie do elementów interfejsu użytkownika, wykonaj następujące czynności:
W folderze Aplikacja utwórz plik o nazwie ui.js.
Dodaj następujący kod do pliku 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')); }
Krok 11. Uruchamianie aplikacji SPA
W wierszu poleceń uruchom następujące komendy:
npm install
npm ./index.js
- Przejdź do https://localhost:6420.
- Wybierz pozycję Zaloguj się.
- Ukończ proces rejestracji lub logowania.
Po pomyślnym uwierzytelnieniu na ekranie zostanie wyświetlony przeanalizowany token identyfikatora. Wybierz Call API , aby wywołać punkt końcowy interfejsu API.