MSAL Azure B2C授权API请求时应发送哪个字段作为Bearer令牌
问题解答
你现在拿不到有效访问令牌的核心原因是调用acquireTokenSilent时传入的scopes参数为空数组,这时候MSAL只会返回登录流程自带的ID令牌,不会生成可用于访问后端API的访问令牌,你看到返回结果里accessToken字段为空就是这个原因。
1. 用作API请求授权的Bearer令牌
- 你需要先在Azure B2C的应用注册页面为你的ASP.NET Core后端API注册对应的应用,为该API暴露授权范围(Scope),再在你的Next.js前端对应的B2C应用注册中,添加对该后端API Scope的访问权限。
- 修改
acquireTokenSilent的入参,将scopes替换为你后端API对应的Scope值,调用成功后返回结果中的**accessToken字段值**就是你需要的Bearer令牌。发请求时将其放到请求头中即可,格式为:Authorization: Bearer <accessToken字段的值> - 不要用当前返回的
idToken当Bearer令牌传给后端:ID令牌的受众(aud声明)是你的前端应用ID,是给前端识别用户登录状态用的,不符合OAuth2规范中访问令牌的使用要求,后续ASP.NET Core配置JWT Bearer校验时会因为受众不匹配直接拒绝请求。也不要用idp_access_token,这个是Azure B2C从Google侧拿到的第三方身份源令牌,仅供B2C自身拉取第三方用户信息使用,不是给你的业务API授权用的。
2. 用作数据库存储的用户唯一标识
- 不要用邮箱、用户名、
sub声明作为用户唯一标识:邮箱和用户名支持修改,sub声明是针对特定令牌受众生成的标识,不同应用拿到的同个用户的sub值可能不一致。 - 你应该使用令牌声明中的**
oid(对象ID)**作为用户唯一标识存入数据库:这个值是Azure B2C为每个租户下的用户实体分配的全局唯一、永久不变的标识符,不管后续你新增多少种身份提供商(比如本地账号、微软账号、其他社交账号),只要是绑定到同一个B2C用户实体,oid值就不会变,非常适合作为用户表的主键关联业务数据。
修正后的代码示例
const Home: NextPage = () => { const { instance, accounts } = useMsal(); useEffect(() => { if (!accounts.length) return; instance .acquireTokenSilent({ // 替换为你自己后端API在B2C中暴露的Scope scopes: ["https://<你的B2C租户名>.onmicrosoft.com/<后端API应用ID>/API.Access"], account: accounts[0], }) .then((response) => { // 取访问令牌 const bearerToken = response.accessToken; // 取用户唯一标识 const userId = response.account.idTokenClaims.oid; // 后续携带令牌发API请求即可 console.log("access token:", bearerToken, "user oid:", userId); }); }); return ( <div className={styles.container}> <button onClick={handleClick(instance)}>login</button> </div> ); }; export default Home;
内容的提问来源于stack exchange,提问作者arda beyoglu
相关产品推荐
相关产品推荐

