Hitelesítés engedélyezése saját egyoldalas alkalmazásban Azure AD B2C használatával
Ez a cikk bemutatja, hogyan adhat hozzá Azure Active Directory B2C-hitelesítést (Azure AD B2C) saját egyoldalas alkalmazásához (SPA). Megtudhatja, hogyan hozhat létre SPA-alkalmazást a Microsoft Authentication Library for JavaScript (MSAL.js) használatával.
Ezt a cikket a Hitelesítés konfigurálása egy spa-mintaalkalmazásban című témakörben találja, és a minta SPA-alkalmazást a saját SPA-alkalmazásával helyettesítheti.
Áttekintés
Ez a cikk Node.js és Express használatával hoz létre alapszintű Node.js webalkalmazást. Az Express egy minimális és rugalmas Node.js webalkalmazás-keretrendszer, amely számos funkciót biztosít a web- és mobilalkalmazásokhoz.
A MSAL.js hitelesítési kódtár egy Microsoft által biztosított kódtár, amely leegyszerűsíti a hitelesítés és az engedélyezés támogatását az SPA-alkalmazásokhoz.
Tipp
A teljes MSAL.js kód az ügyféloldalon fut. A Node.js és az Express kiszolgálóoldali kódját más megoldásokkal is helyettesítheti, például a .NET Core, a Java és a Hypertext Preprocessor (PHP) szkriptnyelvekkel.
Előfeltételek
Az előfeltételek és az integrációs utasítások áttekintéséhez lásd: Hitelesítés konfigurálása spa-mintaalkalmazásban.
1. lépés: SPA-alkalmazásprojekt létrehozása
Használhat egy meglévő SPA-alkalmazásprojektet, vagy létrehozhat egy újat. Új projekt létrehozásához tegye a következőket:
Nyisson meg egy parancshéjat, és hozzon létre egy új könyvtárat (például myApp). Ez a könyvtár tartalmazza az alkalmazáskódot, a felhasználói felületet és a konfigurációs fájlokat.
Adja meg a létrehozott könyvtárat.
npm init
Az paranccsal hozzon létre egypackage.json
fájlt az alkalmazáshoz. Ez a parancssor az alkalmazással kapcsolatos információk megadását kéri (például az alkalmazás nevét és verzióját, valamint a kezdeti belépési pont nevét, a index.js fájlt). Futtassa a következő parancsot, és fogadja el az alapértelmezett értékeket:
npm init
2. lépés: A függőségek telepítése
Az Express-csomag telepítéséhez futtassa a következő parancsot a parancshéjban:
npm install express
Az alkalmazás statikus fájljainak megkereséséhez a kiszolgálóoldali kód a Path csomagot használja.
Az Elérési út csomag telepítéséhez futtassa a következő parancsot a parancshéjban:
npm install path
3. lépés: A webkiszolgáló konfigurálása
A myApp mappában hozzon létre egy index.jsnevű fájlt, amely a következő kódot tartalmazza:
// 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}`);
});
4. lépés: Az SPA felhasználói felületének létrehozása
Adja hozzá az SPA-alkalmazásfájlt index.html
. Ez a fájl egy Bootstrap-keretrendszerrel létrehozott felhasználói felületet implementál, és szkriptfájlokat importál konfigurációs, hitelesítési és webes API-hívásokhoz.
A index.html fájl által hivatkozott erőforrásokat az alábbi táblázatban találja:
Referencia | Definíció |
---|---|
MSAL.js könyvtár | MSAL.js hitelesítés JavaScript-kódtár CDN-elérési útja. |
Bootstrap stíluslap | Ingyenes előtér-keretrendszer a gyorsabb és egyszerűbb webes fejlesztéshez. A keretrendszer HTML- és CSS-alapú tervezési sablonokat tartalmaz. |
policies.js |
A Azure AD B2C egyéni szabályzatait és felhasználói folyamatait tartalmazza. |
authConfig.js |
Hitelesítési konfigurációs paramétereket tartalmaz. |
authRedirect.js |
A hitelesítési logikát tartalmazza. |
apiConfig.js |
Webes API-hatóköröket és az API-végpont helyét tartalmazza. |
api.js |
Meghatározza az API meghívásához és a válasz kezeléséhez használni kívánt módszert. |
ui.js |
Szabályozza a felhasználói felület elemeit. |
Az SPA-indexfájl megjelenítéséhez a myApp mappában hozzon létre egy index.htmlnevű fájlt, amely a következő HTML-kódrészletet tartalmazza:
<!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>
5. lépés: A hitelesítési kódtár konfigurálása
Konfigurálja, hogy a MSAL.js kódtár hogyan integrálható Azure AD B2C-vel. A MSAL.js kódtár egy gyakori konfigurációs objektumot használ a Azure AD B2C-bérlő hitelesítési végpontjaihoz való csatlakozáshoz.
A hitelesítési kódtár konfigurálásához tegye a következőket:
A myApp mappában hozzon létre egy app nevű új mappát.
Az Alkalmazás mappában hozzon létre egy új fájlt authConfig.jsnéven.
Adja hozzá a következő JavaScript-kódot a authConfig.js fájlhoz:
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 };
Cserélje le a elemet
<Application-ID>
az alkalmazásregisztrációs alkalmazásazonosítóra. További információ: Hitelesítés konfigurálása minta SPA-alkalmazásban.
Tipp
További MSAL-objektumkonfigurációs lehetőségekért tekintse meg a Hitelesítési beállítások című cikket.
6. lépés: A Azure AD B2C felhasználói folyamatainak megadása
Hozza létre a policies.js fájlt, amely információkat nyújt a Azure AD B2C-környezetről. A MSAL.js kódtár ezeket az információkat használja a B2C Azure AD hitelesítési kérések létrehozásához.
A Azure AD B2C felhasználói folyamatainak megadásához tegye a következőket:
Az Alkalmazás mappában hozzon létre egy új fájlt policies.jsnéven.
Adja hozzá a következő kódot a policies.js fájlhoz:
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" }
Cserélje le a elemet
B2C_1_SUSI
a bejelentkezési Azure AD B2C-szabályzat nevére.Cserélje le a elemet
B2C_1_EditProfile
a szerkesztési profilra Azure AD B2C-szabályzat nevére.Cserélje le az összes példányt
contoso
a Azure AD B2C-bérlő nevére.
7. lépés: A felhasználó bejelentkezése az MSAL használatával
Ebben a lépésben implementálja a bejelentkezési folyamat inicializálására szolgáló metódusokat, az API hozzáférési jogkivonat-beszerzését és a kijelentkezési módszereket.
További információ: A Microsoft Authentication Library (MSAL) használata a felhasználói bejelentkezéshez című cikk.
A felhasználó bejelentkezéséhez tegye a következőket:
Az Alkalmazás mappában hozzon létre egy új fájlt authRedirect.jsnéven.
Másolja és illessze be a következő kódot a authRedirect.js:
// 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); }
8. lépés: A webes API helyének és hatókörének konfigurálása
Ha engedélyezni szeretné, hogy a SPA-alkalmazás meghívjon egy webes API-t, adja meg a webes API-végpont helyét és a webes API-hoz való hozzáférés engedélyezéséhez használni kívánt hatóköröket .
A webes API helyének és hatóköreinek konfigurálásához tegye a következőket:
Az Alkalmazás mappában hozzon létre egy új fájlt apiConfig.jsnéven.
Másolja és illessze be a következő kódot a apiConfig.js:
// 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" };
Cserélje le
contoso
a elemet a bérlő nevére. A szükséges hatókör neve a Hatókörök konfigurálása című cikkben leírtak szerint található.Cserélje le a értékét
webApi
a webes API-végpont helyére.
9. lépés: A webes API meghívása
Adja meg az API-végpontra irányuló HTTP-kérést. A HTTP-kérés úgy van konfigurálva, hogy átadja a MSAL.js által beszerzett hozzáférési jogkivonatot a Authorization
kérelem HTTP-fejlécébe.
Az alábbi kód határozza meg a HTTP-kérést GET
az API-végpontnak, és átadja a hozzáférési jogkivonatot a Authorization
HTTP-fejlécen belül. Az API helyét a webApi
apiConfig.jskulcs határozza meg.
Ha a megszerzett jogkivonat használatával szeretné meghívni a webes API-t, tegye a következőket:
Az Alkalmazás mappában hozzon létre egy új fájlt api.jsnéven.
Adja hozzá a következő kódot a api.js fájlhoz:
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); }); }
10. lépés: A felhasználói felület elemeire vonatkozó referencia hozzáadása
Az SPA alkalmazás JavaScript használatával szabályozza a felhasználói felület elemeit. Megjeleníti például a bejelentkezési és kijelentkezés gombokat, és megjeleníti a felhasználók azonosító jogkivonat-jogcímeit a képernyőn.
A felhasználói felület elemeire vonatkozó hivatkozás hozzáadásához tegye a következőket:
Az Alkalmazás mappában hozzon létre egy ui.jsnevű fájlt.
Adja hozzá a következő kódot a ui.js fájlhoz:
// 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')); }
11. lépés: Az SPA-alkalmazás futtatása
Futtassa a következő parancsokat a parancshéjban:
npm install
npm ./index.js
- Nyissa meg a következőt: https://localhost:6420.
- Válassza a Bejelentkezés lehetőséget.
- Fejezze be a regisztrációt vagy a bejelentkezési folyamatot.
A sikeres hitelesítést követően az elemzési azonosító jogkivonata megjelenik a képernyőn. Válassza ki Call API
az API-végpont meghívásához.