You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 23:16:34