跨租户场景下配置可接受Azure AD B2C令牌的Azure Functions App认证
配置步骤
1. 租户A(Azure AD B2C侧)配置
- 在租户A的Azure AD B2C中注册API应用:选择「仅此组织目录中的帐户」,不需要填写重定向URI,注册完成后记录应用程序(客户端)ID。
- 进入刚注册的API应用的「公开API」板块,设置应用ID URI(默认值
api://<API客户端ID>即可),新增自定义范围例如access_as_user,启用用户和管理员同意权限,记录完整范围路径api://<API客户端ID>/access_as_user。 - 找到前端FE在B2C中已注册的应用,进入「API权限」板块,添加权限选择「我的API」,选中刚注册的API应用,勾选
access_as_user范围,提交后点击「授予管理员同意(租户A)」完成授权。 - 进入FE当前使用的B2C用户流/自定义策略配置页,在「应用程序声明」中确认已开启访问令牌的
iss、aud、scp等核心声明返回。
2. 租户B(Azure Functions API侧)配置
2.1 门户内置身份验证配置(无需改代码)
- 进入租户B的Function App资源,左侧菜单找到「设置-身份验证」,点击「添加身份提供程序」。
- 身份提供程序选择「OpenID Connect」,自定义名称例如
AzureADB2C,填写元数据端点:https://<B2C租户名>.b2clogin.com/<B2C租户名>.onmicrosoft.com/<用户流名称>/v2.0/.well-known/openid-configuration。 - 客户端ID填写租户A中注册的API应用的客户端ID,受众填写API应用客户端ID或完整应用ID URI
api://<API客户端ID>,颁发者URL填写https://<B2C租户名>.b2clogin.com/<B2C租户ID>/v2.0/。 - 全局认证设置选择「要求身份验证」,未认证请求处理逻辑选择「返回401未授权」,保存配置即可完成内置校验。
2.2 代码侧手动令牌校验配置
如果需要自定义校验逻辑,可跳过2.1的配置,直接在Node.js代码中实现校验:
首先安装依赖包:npm install jsonwebtoken jwks-rsa
核心校验逻辑示例:
const jwt = require('jsonwebtoken'); const jwksClient = require('jwks-rsa'); // 初始化JWKS客户端,替换为租户A的B2C配置 const client = jwksClient({ jwksUri: 'https://<B2C租户名>.b2clogin.com/<B2C租户名>.onmicrosoft.com/<用户流名称>/discovery/v2.0/keys' }); function getSigningKey(header, callback) { client.getSigningKey(header.kid, (err, key) => { const publicKey = key.getPublicKey() || key.rsaPublicKey; callback(null, publicKey); }); } module.exports = async function (context, req) { const authHeader = req.headers.authorization; // 校验令牌存在性 if (!authHeader || !authHeader.startsWith('Bearer ')) { context.res = { status: 401, body: "缺少有效访问令牌" }; return; } const accessToken = authHeader.split(' ')[1]; try { // 校验令牌有效性 const decodedToken = await new Promise((resolve, reject) => { jwt.verify(accessToken, getSigningKey, { audience: "<API应用客户端ID或api://<API客户端ID>>", issuer: "https://<B2C租户名>.b2clogin.com/<B2C租户ID>/v2.0/" }, (err, decoded) => err ? reject(err) : resolve(decoded)); }); // 校验通过,执行业务逻辑 context.res = { status: 200, body: "认证通过" }; } catch (err) { context.res = { status: 401, body: `令牌校验失败: ${err.message}` }; return; } }
3. 前端FE请求适配
- 调用MSAL获取访问令牌时,scope参数必须填写之前配置的完整API范围
api://<API客户端ID>/access_as_user,不能使用默认的MS Graph范围,否则返回的令牌受众不匹配会导致API校验失败。 - 向API发送请求时,将获取到的访问令牌添加到请求头中,格式为
Authorization: Bearer <访问令牌>。
内容的提问来源于stack exchange,提问作者Dat Nguyen
相关产品推荐
相关产品推荐

