如何配置可在客户端读取MS Entra ID令牌的域名?
问题分析与解决方案
一、令牌未存储的核心原因
你的loginRequest里scopes是空数组,这是关键问题。MSAL只有在请求具体权限范围时,才会获取并存储可用于API调用的ID令牌/访问令牌。空scopes只会完成登录跳转流程,但不会返回有效的Bearer令牌。
二、配置修正步骤
1. 补充正确的Scopes
根据你保护自定义后端端点的场景,需要请求对应API的权限范围。格式通常为api://{你的后端API客户端ID}/.default(.default表示请求该API注册的所有默认权限),或者具体的权限名称(如api://{clientId}/access_as_user)。修改loginRequest:
export const loginRequest = { scopes: ['api://YOUR_API_CLIENT_ID/.default'] // 替换为后端API的实际Client ID };
2. 修正Authority配置
你的authority格式不符合Entra ID规范,正确格式应为:
- 单租户(仅组织内用户可登录):
https://login.microsoftonline.com/{你的租户ID} - 多租户(允许外部用户登录):
https://login.microsoftonline.com/common - 组织租户:
https://login.microsoftonline.com/organizations
请确认该URL指向正确的Entra ID租户认证端点,否则MSAL无法正常获取令牌。
3. 正确获取令牌的方式
登录成功后,不要直接读取localStorage(MSAL会加密存储令牌,直接读取无法拿到明文),应通过MSAL的API主动获取:
const tokenRequest = { scopes: ['api://YOUR_API_CLIENT_ID/.default'] }; try { // 静默获取令牌(优先用缓存) const response = await msalInstance.acquireTokenSilent(tokenRequest); const accessToken = response.accessToken; // 此即为可用于后端请求的Bearer令牌 } catch (error) { // 静默失败时弹出窗口重新获取 const response = await msalInstance.acquireTokenPopup(tokenRequest); const accessToken = response.accessToken; }
三、关键术语快速梳理(针对你的场景)
- Client ID:Entra ID中注册应用(前端/后端)的唯一标识,前端用
MSAL_CLIENT_ID,后端API也有独立的Client ID。 - Authority:Entra ID的认证服务器地址,负责验证用户身份、颁发令牌。
- Scopes:应用请求的权限范围,告诉Entra ID你的应用需要访问哪些资源(比如后端API的特定权限)。
- Audience(受众):令牌的合法接收者,即你的后端API,令牌内的
aud字段对应API的Client ID,确保令牌仅能被该API使用。 - Tenant(租户):你的Entra ID实例,包含组织内的用户、应用等资源,单租户仅允许内部用户登录,多租户支持外部用户。
- Claims:令牌内携带的字段,比如用户ID、角色、权限等,后端可通过这些字段验证用户身份与权限。
四、验证令牌存储
修正配置并获取令牌后,MSAL会自动将令牌存储到localStorage(按你的配置),存储键以msal.开头,可在浏览器开发者工具的Application → Local Storage中查看。但不建议直接读取localStorage,始终通过MSAL API获取令牌,避免处理加密逻辑。
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

