如何配置客户端可读的 MS Entra ID 令牌所在的域?

问题描述 投票:0回答:1

我们决定希望使用 JWT 机制来保护我们的端点之一。 身份验证是通过 Microsoft Identity Platform 使用 Microsoft Entra ID 完成的。 (这是我第一次集成这样的系统,并且之前没有关于 JWT 的一般经验,特别是整个 MS Azure 身份验证世界。)

现在,我已成功将 MSAL 集成到我的前端中,并完成了测试用户的登录过程,并且被正确重定向到我开始登录旅程的位置。 但是我在

localStorage
中找不到获取的Entra ID令牌(根据我的
msalConfig
应该在哪里)。

我怀疑这是因为令牌存储在不同的域下,因此我无法读取它。 但我需要阅读它,以便我可以将其作为不记名令牌按预期发送到端点。

是的,我阅读了文档(但不是全部),但对所有新术语感到非常头晕。那么这可能与文档中不断出现的

audience
有关吗? 在
claims
scopes
audience
authority
tenants
clientId
等之间。我必须承认我有点迷失。

这是我的

msalConfig
和我的
loginRequest

export const msalConfig = {
  auth: {
    clientId: globals.meta.config.MSAL_CLIENT_ID,
    authority: 'https://galactus.some-example-authority.com/',
    redirectUri: 'https://example.org/pages/galactus-login',
    postLogoutRedirectUri: '/',
    navigateToLoginRequestUrl: false,
  },
  cache: {
    cacheLocation: 'localStorage',
    storeAuthStateInCookie: false,
  },
}
export const loginRequest = {
  scopes: [],
}
azure-active-directory jwt microsoft-entra-id msal-react ms-identity
1个回答
0
投票

最初,我注册了一个应用程序,其中

API permissions

enter image description here

在“身份验证”选项卡中,我在“单页应用程序”平台中将重定向 URI 添加为 http://localhost:3000:

enter image description here启用

public-client

流选项,如下所示:

enter image description here 在我的例子中,我使用了下面的代码文件,并通过成功调用 MS Graph API 获得了带有登录用户详细信息的令牌,如下所示:

authConfig.js:

// src/authConfig.js export const msalConfig = { auth: { clientId: "appId", authority: "https://login.microsoftonline.com/tenantId", redirectUri: "http://localhost:3000", // Redirect URI registered in Azure AD }, cache: { cacheLocation: "localStorage", storeAuthStateInCookie: false, }, }; export const loginRequest = { scopes: ["User.Read", "openid"], // Scopes for MS Graph API or custom API };

App.js:

// src/App.js import React, { useEffect, useState } from "react"; import { msalConfig, loginRequest } from "./authConfig"; import { PublicClientApplication } from "@azure/msal-browser"; import axios from "axios"; const msalInstance = new PublicClientApplication(msalConfig); const App = () => { const [accessToken, setAccessToken] = useState(""); const [idToken, setIdToken] = useState(""); const [userProfile, setUserProfile] = useState(null); const [userName, setUserName] = useState(""); // Initialize MSAL on app load useEffect(() => { const initializeMSAL = async () => { try { await msalInstance.initialize(); console.log("MSAL initialized successfully"); } catch (error) { console.error("MSAL initialization failed: ", error); } }; initializeMSAL(); }, []); const loginAndGetToken = async () => { try { const loginResponse = await msalInstance.loginPopup(loginRequest); console.log("Login successful!", loginResponse); // Set the active account after successful login msalInstance.setActiveAccount(loginResponse.account); // Access tokens and ID token const newAccessToken = loginResponse.accessToken; const newIdToken = loginResponse.idToken; // Get the ID token setAccessToken(newAccessToken); setIdToken(newIdToken); setUserName(loginResponse.account.name); // Call the Graph API to fetch user profile info await callGraphAPI(newAccessToken); } catch (error) { console.error("Login failed: ", error); alert(`Login failed: ${error.message}`); } }; const callGraphAPI = async (token) => { try { const response = await axios.get("https://graph.microsoft.com/v1.0/me", { headers: { Authorization: `Bearer ${token}`, }, }); console.log("Graph API Response:", response.data); setUserProfile(response.data); } catch (error) { console.error("Graph API call failed:", error); } }; const logout = () => { msalInstance.logoutPopup(); }; return ( <div> <h1>MSAL Login</h1> {!accessToken ? ( <button onClick={loginAndGetToken}>Login</button> ) : ( <div> <h2>Logged in as: {userName}</h2> {/* Display user's name */} <button onClick={logout}>Logout</button> </div> )} {accessToken && ( <div> <h2>Access Token:</h2> <p>{accessToken}</p> </div> )} {idToken && ( <div> <h2>ID Token:</h2> <p>{idToken}</p> </div> )} {userProfile && ( <div> <h2>User Profile:</h2> <p><strong>Name:</strong> {userProfile.displayName}</p> <p><strong>Email:</strong> {userProfile.mail || userProfile.userPrincipalName}</p> <p><strong>Job Title:</strong> {userProfile.jobTitle}</p> </div> )} </div> ); }; export default App;

输出:

enter image description here 您还可以通过将上面的访问令牌粘贴到

jwt.ms

网站来解码它,并检查 aud

scp
等声明来验证它:

enter image description here 如果您公开了任何具有自定义范围的 API,请确保在获取令牌时使用

scopes

参数值作为 api://appId/scopename

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.