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

如何在msal-react中配置多实例(Azure AD与Azure B2C)实现登录?

在React应用中用msal-react实现Azure B2C与Azure AD双登录配置

完全可以通过msal-react实现双身份提供商的登录需求,无需降级使用msal.js。核心思路是创建两个独立的MSAL实例,分别对应Azure B2C和Azure AD,再根据业务场景在不同组件中使用对应的实例或Provider。

1. 创建双MSAL实例

分别定义Azure B2C和Azure AD的配置,生成独立的PublicClientApplication实例:

import { PublicClientApplication } from "@azure/msal-browser";

// Azure B2C 配置
const msalConfigB2C = {
  auth: {
    clientId: "你的B2C客户端ID",
    authority: "https://你的租户.b2clogin.com/你的租户.onmicrosoft.com/B2C_1_注册登录流",
    redirectUri: "/",
    postLogoutRedirectUri: "/"
  }
};

// Azure AD 配置
const msalConfigAAD = {
  auth: {
    clientId: "你的Azure AD客户端ID",
    authority: "https://login.microsoftonline.com/你的AAD租户ID",
    redirectUri: "/",
    postLogoutRedirectUri: "/"
  }
};

// 生成两个独立实例
const msalInstanceB2C = new PublicClientApplication(msalConfigB2C);
const msalInstanceAAD = new PublicClientApplication(msalConfigAAD);

2. 实现分场景登录按钮

在登录页面中,为内外用户分别提供对应实例的登录入口:

// 外部用户(B2C)登录按钮
const B2CLoginButton = () => {
  const handleLogin = async () => {
    await msalInstanceB2C.loginPopup({
      scopes: ["openid", "profile"]
    });
    // 登录成功后的逻辑:比如跳转到外部用户主页
    window.location.href = "/external/dashboard";
  };

  return <button onClick={handleLogin}>外部用户登录(B2C)</button>;
};

// 内部用户(Azure AD)登录按钮
const AADLoginButton = () => {
  const handleLogin = async () => {
    await msalInstanceAAD.loginPopup({
      scopes: ["openid", "profile", "User.Read"]
    });
    // 登录成功后的逻辑:比如跳转到内部用户主页
    window.location.href = "/internal/dashboard";
  };

  return <button onClick={handleLogin}>内部用户登录(Azure AD)</button>;
};

3. 分区域使用MsalProvider

如果部分页面需要依赖特定身份提供商的上下文,可以用MsalProvider分别包裹对应路由组件,让组件内部通过useMsal hook获取实例:

import { MsalProvider, useMsal } from "@azure/msal-react";
import { BrowserRouter, Routes, Route } from "react-router-dom";

// 外部用户专属页面
const ExternalDashboard = () => {
  const { instance, accounts } = useMsal();
  const currentUser = accounts[0];

  return (
    <div>
      <h2>外部用户控制台</h2>
      <p>当前登录用户:{currentUser?.username}</p>
    </div>
  );
};

const ExternalUserRoutes = () => (
  <MsalProvider instance={msalInstanceB2C}>
    <ExternalDashboard />
  </MsalProvider>
);

// 内部用户专属页面
const InternalDashboard = () => {
  const { instance, accounts } = useMsal();
  const currentUser = accounts[0];

  return (
    <div>
      <h2>内部用户控制台</h2>
      <p>当前登录用户:{currentUser?.username}</p>
    </div>
  );
};

const InternalUserRoutes = () => (
  <MsalProvider instance={msalInstanceAAD}>
    <InternalDashboard />
  </MsalProvider>
);

// 主应用路由
const App = () => (
  <BrowserRouter>
    <Routes>
      <Route path="/external/*" element={<ExternalUserRoutes />} />
      <Route path="/internal/*" element={<InternalUserRoutes />} />
      <Route path="/" element={<div><B2CLoginButton /> <AADLoginButton /></div>} />
    </Routes>
  </BrowserRouter>
);

4. 令牌获取与API调用

调用后端API时,使用对应实例获取令牌:

// 获取B2C访问令牌
const getB2CToken = async () => {
  const account = msalInstanceB2C.getActiveAccount();
  if (!account) throw new Error("无外部用户登录");
  
  const response = await msalInstanceB2C.acquireTokenSilent({
    account,
    scopes: ["https://你的租户.onmicrosoft.com/api/外部用户API权限"]
  });
  return response.accessToken;
};

// 获取Azure AD访问令牌
const getAADToken = async () => {
  const account = msalInstanceAAD.getActiveAccount();
  if (!account) throw new Error("无内部用户登录");
  
  const response = await msalInstanceAAD.acquireTokenSilent({
    account,
    scopes: ["api://你的AAD API客户端ID/内部用户API权限"]
  });
  return response.accessToken;
};

这种方案可以严格区分内外用户的登录链路,无需将Azure AD联合到B2C中,完全基于msal-react实现。

内容的提问来源于stack exchange,提问作者mlidal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 10:07:25