Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Gilt für: Mitarbeitermieter
Externe Mieter (weitere Informationen)
Dieser Artikel ist Teil 2 einer Reihe, die veranschaulicht, wie die Profilbearbeitungslogik in einer Node.js-Web-App hinzugefügt wird. In Teil 1 dieser Reihe richten Sie Ihre App für die Profilbearbeitung ein.
In diesem Leitfaden erfahren Sie, wie Sie die Microsoft Graph-API für die Profilbearbeitung aufrufen.
Voraussetzungen
- Führen Sie die Schritte im zweiten Teil dieser Anleitungsreihe aus, Einrichten einer Node.js-Webanwendung für die Profilbearbeitung.
Abschließen der Client-Web-App
In diesem Abschnitt fügen Sie den identitätsbezogenen Code für die Client-Web-App hinzu.
Aktualisieren der „authConfig.js“-Datei
Aktualisieren Sie die Datei authConfig.js für die Client-Web-App:
Öffnen Sie in Ihrem Code-Editor die Datei App/authConfig.js, und fügen Sie dann drei neue Variablen hinzu –
GRAPH_API_ENDPOINT
,GRAPH_ME_ENDPOINT
undeditProfileScope
. Stellen Sie sicher, dass Sie die drei Variablen exportieren://... const GRAPH_API_ENDPOINT = process.env.GRAPH_API_ENDPOINT || "https://graph.microsoft.com/"; // https://learn.microsoft.com/graph/api/user-update?tabs=http const GRAPH_ME_ENDPOINT = GRAPH_API_ENDPOINT + "v1.0/me"; const editProfileScope = process.env.EDIT_PROFILE_FOR_CLIENT_WEB_APP || 'api://{clientId}/EditProfileService.ReadWrite'; module.exports = { //... editProfileScope, GRAPH_API_ENDPOINT, GRAPH_ME_ENDPOINT, //... };
Die Variable
editProfileScope
stellt eine MFA-geschützte Ressource dar, also die App der mittleren Ebene (EditProfileService-App).GRAPH_ME_ENDPOINT
ist der Microsoft Graph-API-Endpunkt.
Ersetzen Sie den Platzhalter
{clientId}
durch die Anwendungs-ID (Client) der zuvor von Ihnen registrierten App der mittleren Ebene (EditProfileService-App).
Abrufen eines Zugriffstokens in der Client-Web-App
Öffnen Sie in Ihrem Code-Editor die Datei App/auth/AuthProvider.js, und aktualisieren Sie dann die Methode getToken
in der Klasse AuthProvider
:
class AuthProvider {
//...
getToken(scopes, redirectUri = "http://localhost:3000/") {
return async function (req, res, next) {
const msalInstance = authProvider.getMsalInstance(authProvider.config.msalConfig);
try {
msalInstance.getTokenCache().deserialize(req.session.tokenCache);
const silentRequest = {
account: req.session.account,
scopes: scopes,
};
const tokenResponse = await msalInstance.acquireTokenSilent(silentRequest);
req.session.tokenCache = msalInstance.getTokenCache().serialize();
req.session.accessToken = tokenResponse.accessToken;
next();
} catch (error) {
if (error instanceof msal.InteractionRequiredAuthError) {
req.session.csrfToken = authProvider.cryptoProvider.createNewGuid();
const state = authProvider.cryptoProvider.base64Encode(
JSON.stringify({
redirectTo: redirectUri,
csrfToken: req.session.csrfToken,
})
);
const authCodeUrlRequestParams = {
state: state,
scopes: scopes,
};
const authCodeRequestParams = {
state: state,
scopes: scopes,
};
authProvider.redirectToAuthCodeUrl(
req,
res,
next,
authCodeUrlRequestParams,
authCodeRequestParams,
msalInstance
);
}
next(error);
}
};
}
}
//...
Die Methode getToken
verwendet den angegebenen Bereich, um ein Zugriffstoken abzurufen. Der redirectUri
-Parameter ist die Umleitungs-URL, nachdem die App ein Zugriffstoken abgerufen hat.
Aktualisieren der „users.js“-Datei
Öffnen Sie in Ihrem Code-Editor die Datei App/routes/users.js, und fügen Sie dann die folgenden Routen hinzu:
//...
var { fetch } = require("../fetch");
const { GRAPH_ME_ENDPOINT, editProfileScope } = require('../authConfig');
//...
router.get(
"/gatedUpdateProfile",
isAuthenticated,
authProvider.getToken(["User.Read"]), // check if user is authenticated
async function (req, res, next) {
const graphResponse = await fetch(
GRAPH_ME_ENDPOINT,
req.session.accessToken,
);
if (!graphResponse.id) {
return res
.status(501)
.send("Failed to fetch profile data");
}
res.render("gatedUpdateProfile", {
profile: graphResponse,
});
},
);
router.get(
"/updateProfile",
isAuthenticated, // check if user is authenticated
authProvider.getToken(
["User.Read", editProfileScope],
"http://localhost:3000/users/updateProfile",
),
async function (req, res, next) {
const graphResponse = await fetch(
GRAPH_ME_ENDPOINT,
req.session.accessToken,
);
if (!graphResponse.id) {
return res
.status(501)
.send("Failed to fetch profile data");
}
res.render("updateProfile", {
profile: graphResponse,
});
},
);
router.post(
"/update",
isAuthenticated,
authProvider.getToken([editProfileScope]),
async function (req, res, next) {
try {
if (!!req.body) {
let body = req.body;
fetch(
"http://localhost:3001/updateUserInfo",
req.session.accessToken,
"POST",
{
displayName: body.displayName,
givenName: body.givenName,
surname: body.surname,
},
)
.then((response) => {
if (response.status === 204) {
return res.redirect("/");
} else {
next("Not updated");
}
})
.catch((error) => {
console.log("error,", error);
});
} else {
throw { error: "empty request" };
}
} catch (error) {
next(error);
}
},
);
//...
Sie lösen die Route
/gatedUpdateProfile
aus, wenn der Kundenbenutzer den Link Profilbearbeitung auswählt. Die App:- Erwirbt ein Zugriffstoken mit der Berechtigung User.Read.
- Ruft die Microsoft Graph-API auf, um das Profil des angemeldeten Benutzers zu lesen.
- Zeigt die Benutzerdetails auf der gatedUpdateProfile.hbs-Benutzeroberfläche an.
Sie lösen die Route
/updateProfile
aus, wenn der Benutzer seinen Anzeigenamen aktualisieren möchte, d. h. er wählt die Schaltfläche Profil bearbeiten aus. Die App:- Ruft die App der mittleren Ebene (EditProfileService-App) mithilfe des Bereichs editProfileScope auf. Durch einen Aufruf der App der mittleren Ebene (EditProfileService-App) muss der Benutzer eine MFA-Überprüfung ausführen, sofern dies noch nicht geschehen ist.
- Zeigt die Benutzerdetails auf der updateProfile.hbs-Benutzeroberfläche an.
Sie lösen die
/update
-Route aus, wenn der Benutzer die Schaltfläche Speichern entweder in gatedUpdateProfile.hbs oder updateProfile.hbs auswählt. Die App:- Ruft das Zugriffstoken für die App-Sitzung ab. Sie erfahren im nächsten Abschnitt, wie die App der mittleren Ebene (EditProfileService-App) das Zugriffstoken erhält.
- Sammelt alle Benutzerdetails.
- Ruft die Microsoft Graph-API auf, um das Profil des Benutzers zu aktualisieren.
Aktualisieren der „fetch.js“-Datei
Die App verwendet die Datei App/fetch.js, um die eigentlichen API-Aufrufe vorzunehmen.
Öffnen Sie in Ihrem Code-Editor die Datei App/fetch.js, und fügen Sie dann die PATCH-Vorgangsoption hinzu. Nachdem Sie die Datei aktualisiert haben, sollte die resultierende Datei dem folgenden Code ähneln:
var axios = require('axios');
var authProvider = require("./auth/AuthProvider");
/**
* Makes an Authorization "Bearer" request with the given accessToken to the given endpoint.
* @param endpoint
* @param accessToken
* @param method
*/
const fetch = async (endpoint, accessToken, method = "GET", data = null) => {
const options = {
headers: {
Authorization: `Bearer ${accessToken}`,
},
};
console.log(`request made to ${endpoint} at: ` + new Date().toString());
switch (method) {
case 'GET':
const response = await axios.get(endpoint, options);
return await response.data;
case 'POST':
return await axios.post(endpoint, data, options);
case 'DELETE':
return await axios.delete(endpoint + `/${data}`, options);
case 'PATCH':
return await axios.patch(endpoint, ReqBody = data, options);
default:
return null;
}
};
module.exports = { fetch };
Abschließen der App der mittleren Ebene
In diesem Abschnitt fügen Sie den identitätsbezogenen Code für die App der mittleren Ebene (EditProfileService-App) hinzu.
Öffnen Sie in Ihrem Code-Editor die Datei Api/authConfig.js, und fügen Sie dann den folgenden Code hinzu:
require("dotenv").config({ path: ".env.dev" }); const TENANT_SUBDOMAIN = process.env.TENANT_SUBDOMAIN || "Enter_the_Tenant_Subdomain_Here"; const TENANT_ID = process.env.TENANT_ID || "Enter_the_Tenant_ID_Here"; const REDIRECT_URI = process.env.REDIRECT_URI || "http://localhost:3000/auth/redirect"; const POST_LOGOUT_REDIRECT_URI = process.env.POST_LOGOUT_REDIRECT_URI || "http://localhost:3000"; /** * Configuration object to be passed to MSAL instance on creation. * For a full list of MSAL Node configuration parameters, visit: * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-node/docs/configuration.md */ const msalConfig = { auth: { clientId: process.env.CLIENT_ID || "Enter_the_Edit_Profile_Service_Application_Id_Here", // 'Application (client) ID' of the Edit_Profile Service App registration in Microsoft Entra admin center - this value is a GUID authority: process.env.AUTHORITY || `https://${TENANT_SUBDOMAIN}.ciamlogin.com/`, // Replace the placeholder with your external tenant name clientSecret: process.env.CLIENT_SECRET || "Enter_the_Client_Secret_Here ", // Client secret generated from the app registration in Microsoft Entra admin center }, system: { loggerOptions: { loggerCallback(loglevel, message, containsPii) { console.log(message); }, piiLoggingEnabled: false, logLevel: "Info", }, }, }; const GRAPH_API_ENDPOINT = process.env.GRAPH_API_ENDPOINT || "graph_end_point"; // Refers to the user that is single user singed in. // https://learn.microsoft.com/en-us/graph/api/user-update?tabs=http const GRAPH_ME_ENDPOINT = GRAPH_API_ENDPOINT + "v1.0/me"; module.exports = { msalConfig, REDIRECT_URI, POST_LOGOUT_REDIRECT_URI, TENANT_SUBDOMAIN, GRAPH_API_ENDPOINT, GRAPH_ME_ENDPOINT, TENANT_ID, };
Suchen Sie den Platzhalter:
Enter_the_Tenant_Subdomain_Here
, und ersetzen Sie dies durch die Unterdomäne des Verzeichnisses (Mandant). Wenn Ihre primäre Mandantendomäne z. B.contoso.onmicrosoft.com
ist, verwenden Siecontoso
. Wenn Sie Ihren Mandantennamen nicht kennen, lesen Sie die Informationen unter Abrufen der Details des externen Mandanten.Enter_the_Tenant_ID_Here
und ersetzen Sie sie durch die Mandanten-ID. Wenn Sie Ihre Mandanten-ID nicht kennen, erfahren Sie hier, wie Sie die Mandantendetails abrufen.Enter_the_Edit_Profile_Service_Application_Id_Here
, und ersetzen Sie dies durch den Wert der Anwendungs-ID (Client-ID) des zuvor registrierten EditProfileService.- Ersetzen Sie
Enter_the_Client_Secret_Here
durch den Wert des EditProfileService-App-Geheimnisses, den Sie zuvor kopiert haben. graph_end_point
, und ersetzen Sie sie durch den Microsoft Graph-API-Endpunkt,https://graph.microsoft.com/
.
Öffnen Sie in Ihrem Code-Editor die Datei Api/fetch.js, und fügen Sie dann den Code aus der Datei Api/fetch.js ein. Die Funktion
fetch
verwendet ein Zugriffstoken und den Ressourcenendpunkt, um den eigentlichen API-Aufruf zu tätigen.Öffnen Sie in Ihrem Code-Editor die Datei Api/index.js, und fügen Sie dann den Code aus der Datei Api/index.js ein.
Abrufen eines Zugriffstokens mithilfe von acquireTokenOnBehalfOf
In der Datei Api/index.js erwirbt die App der mittleren Ebene (EditProfileService-App) ein Zugriffstoken mithilfe der Funktion acquireTokenOnBehalfOf. Damit wird das Profil im Namen dieses Benutzers aktualisiert.
async function getAccessToken(tokenRequest) {
try {
const response = await cca.acquireTokenOnBehalfOf(tokenRequest);
return response.accessToken;
} catch (error) {
console.error("Error acquiring token:", error);
throw error;
}
}
Der Parameter tokenRequest
wird wie im folgenden Code dargestellt definiert:
const tokenRequest = {
oboAssertion: req.headers.authorization.replace("Bearer ", ""),
authority: `https://${TENANT_SUBDOMAIN}.ciamlogin.com/${TENANT_ID}`,
scopes: ["User.ReadWrite"],
correlationId: `${uuidv4()}`,
};
In derselben Datei, API/index.js, führt die Mid-Tier-App (EditProfileService-App) einen Aufruf an die Microsoft Graph-API aus, um das Profil des Benutzers zu aktualisieren:
let accessToken = await getAccessToken(tokenRequest);
fetch(GRAPH_ME_ENDPOINT, accessToken, "PATCH", req.body)
.then((response) => {
if (response.status === 204) {
res.status(response.status);
res.json({ message: "Success" });
} else {
res.status(502);
res.json({ message: "Failed, " + response.body });
}
})
.catch((error) => {
res.status(502);
res.json({ message: "Failed, " + error });
});
Teste deine App
Führen Sie die folgenden Schritte aus, um Ihre App zu testen:
Um die Client-App auszuführen, navigieren Sie im Terminalfenster zum Verzeichnis App, und führen Sie dann den folgenden Befehl aus:
npm start
Um die Client-App auszuführen, navigieren Sie im Terminalfenster zum Verzeichnis API, und führen Sie dann den folgenden Befehl aus:
npm start
Öffnen Sie Ihren Browser, und navigieren Sie zu http://localhost:3000.. Wenn SSL-Zertifikatfehler auftreten, erstellen Sie eine
.env
-Datei, und fügen Sie die folgende Konfiguration hinzu:# Use this variable only in the development environment. # Remove the variable when you move the app to the production environment. NODE_TLS_REJECT_UNAUTHORIZED='0'
Wählen Sie die Schaltfläche Anmelden aus, und melden Sie sich an.
Geben Sie auf der Anmeldeseite Ihre E-Mail-Adresse ein, wählen Sie Weiter aus, geben Sie Ihr Kennwort ein und wählen Sie dann Anmelden aus. Wenn Sie kein Konto besitzen, wählen Sie den Link Kein Konto? Erstellen Sie eins aus, um den Registrierungsflow zu starten.
Um das Profil zu aktualisieren, wählen Sie den Link Profilbearbeitung aus. Die daraufhin angezeigte Seite sieht in etwa wie im folgenden Screenshot aus:
Um das Profil zu bearbeiten, wählen Sie die Schaltfläche Profil bearbeiten aus. Wenn Sie dies noch nicht getan haben, werden Sie von der App aufgefordert, eine MFA-Überprüfung durchzuführen.
Nehmen Sie Änderungen an den Profildetails vor, und wählen Sie dann die Schaltfläche Speichern aus.
Verwandte Inhalte
- Erfahren Sie mehr über die Microsoft Identity Plattform und den OAuth 2.0 On-Behalf-Of Flow.