Azure Static Web App ADB2C认证调用AKS后端API问题求助
解决方案:Azure Static Web App + ADB2C 对接 AKS 后端 API(无需APIM)
一、从ADB2C获取针对后端API的JWT令牌
前端已通过SWA集成ADB2C认证,直接用MSAL库获取后端API专属访问令牌即可,核心是指定ADB2C中为后端API定义的scope:
// 基于@azure/msal-react的示例 import { useMsal } from "@azure/msal-react"; const getBackendAccessToken = async () => { const { instance, accounts } = useMsal(); const tokenRequest = { account: accounts[0], // 替换为你在ADB2C中为后端API配置的scope scopes: ["https://your-b2c-tenant.onmicrosoft.com/your-backend-api/api.access"] }; try { const response = await instance.acquireTokenSilent(tokenRequest); return response.accessToken; } catch (err) { // 静默获取失败时触发弹窗登录(仅必要场景) const interactiveResponse = await instance.acquireTokenPopup(tokenRequest); return interactiveResponse.accessToken; } };
配置前提:
- 在ADB2C中把后端API注册为「Web API」类型,暴露所需权限(scope)
- 前端SWA对应的ADB2C应用,已被授予访问该后端API scope的权限
二、前端调用AKS API时传递令牌
在每个API请求的Authorization头中携带Bearer令牌:
const callBackendApi = async () => { const accessToken = await getBackendAccessToken(); const apiUrl = "https://your-aks-ingress-domain/api/protected-endpoint"; const response = await fetch(apiUrl, { method: "GET", headers: { "Authorization": `Bearer ${accessToken}`, "Content-Type": "application/json" } }); if (!response.ok) { throw new Error(`API请求失败: ${response.status}`); } return await response.json(); };
三、后端API验证JWT令牌
后端需验证ADB2C颁发JWT的合法性,核心验证签名、有效期、受众(aud)、发行者(iss)。以下是Node.js/Express的实现示例:
const express = require("express"); const jwt = require("jsonwebtoken"); const jwksClient = require("jwks-rsa"); const app = express(); // 初始化JWKS客户端,获取ADB2C公钥用于签名验证 const jwksClientInstance = jwksClient({ // 替换为你的ADB2C租户、策略对应的JWKS地址 jwksUri: "https://your-b2c-tenant.b2clogin.com/your-b2c-tenant.onmicrosoft.com/B2C_1_signup_signin/discovery/v2.0/keys" }); // 获取签名公钥 const getSigningKey = (header, callback) => { jwksClientInstance.getSigningKey(header.kid, (err, key) => { if (err) return callback(err); const signingKey = key.getPublicKey(); callback(null, signingKey); }); }; // JWT验证中间件 const authenticateJwt = (req, res, next) => { const authHeader = req.headers.authorization; const token = authHeader?.split(" ")[1]; if (!token) { return res.status(401).json({ message: "缺少访问令牌" }); } jwt.verify(token, getSigningKey, { // 替换为后端API在ADB2C中的客户端ID audience: "your-backend-api-client-id", // 替换为你的ADB2C发行者地址(格式:https://<租户>.b2clogin.com/<租户ID>/v2.0/) issuer: "https://your-b2c-tenant.b2clogin.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/v2.0/", algorithms: ["RS256"] // ADB2C默认用RS256算法签名 }, (err, decoded) => { if (err) { return res.status(403).json({ message: "令牌验证失败", error: err.message }); } req.user = decoded; next(); }); }; // 受保护的API路由 app.get("/api/protected-endpoint", authenticateJwt, (req, res) => { res.json({ message: "访问受保护资源成功", userInfo: req.user }); }); app.listen(3000, () => console.log("后端API服务启动"));
四、关键注意事项
- AKS API暴露方式:通过Ingress(如NGINX Ingress Controller)暴露公网地址,若需更高安全性,可配合Azure Private Link打通SWA与AKS网络,避免公网暴露
- 令牌生命周期:前端需处理令牌过期问题,MSAL库默认自动刷新令牌,也可在请求返回401时触发重新获取逻辑
- ADB2C配置校验:确保后端API的
aud(受众)参数与ADB2C中注册的客户端ID一致,发行者地址需使用租户ID而非域名(避免域名变更导致验证失败)
内容的提问来源于stack exchange,提问作者LiveSK
相关产品推荐
相关产品推荐

