【问题标题】:Calling an API with MSAL React使用 MSAL React 调用 API
【发布时间】:2021-11-10 22:13:03
【问题描述】:

我正在尝试使用 Azure AD 保护 API 并从 React SPA 调用它,但我遇到了 401 Not Authorized 错误。我不太确定自己做错了什么。

在 appsettings.json 中

"AzureAD": {
    "Instance": "https://login.microsoft.com",
    "Domain": "<MyAdDomain>",
    "TenantId": "<MyTenantId>",
    "ClientId": "<MyApiAppId>",
    "Scope": "<MyApiScope>"
  }

然后是 StartUp.cs

            var tenantId = $"{Configuration["AzureAD:TenantId"]}";
            var authority = $"{Configuration["AzureAD:Instance"]}/{tenantId}";

            var audience = new List<string>
            {
                $"{Configuration["AzureAD:ClientId"]}",
                $"{Configuration["AzureAD:Scope"]}"
            };

            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options =>
                {
                    options.Authority = authority;
                    options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
                    {
                        ValidAudiences = audience,
                        ValidIssuers = new List<string>
                        {
                            $"https://sts.windows.net/{tenantId}",
                            $"https://sts.windows.net/{tenantId}/v2.0",
                        }
                    };
                });

同时,在我的 React 应用程序中,我使用 MsalProvider 和这个配置来保护它:

authConfig.ts

export const msalConfig: Configuration = {
  auth: {
    clientId: "<MyClientApiId>",
    authority:
      "https://login.microsoftonline.com/<MyTenantId>",
    redirectUri: "/",
  },
  cache: {
    cacheLocation: "sessionStorage",
    storeAuthStateInCookie: false,
  },
// other code

App.tsx

const msalInstance = new PublicClientApplication(msalConfig);

function App() {
  return (
    <MsalProvider instance={msalInstance}>
      <BrowserRouter>
        <Routes>
          <Route path="/" element={<HomePage />} />
          <Route path="/dealer/:accountNumber" element={<DealerContainer />} />
        </Routes>
      </BrowserRouter>
    </MsalProvider>
  );

然后在 HomePage.tsx 中:

  const getCompanies = useCallback(async () => {
    if (isAuthenticated) {
      const silentRequest: SsoSilentRequest = {
        scopes: ["<MyApiScope>"],
        loginHint: instance.getActiveAccount()?.username,
      };

      const token = await instance.ssoSilent(silentRequest);
      const companies = await getCompaniesAsync(token);

      setCompaniesList(companies);
      setFullCompaniesList(companies);
    }
  }, [instance, isAuthenticated]);

任何关于我在这里做错了什么的见解?谢谢!

【问题讨论】:

  • 可以参考this answer吗?我在那里提供了一个样本。
  • 谢谢!这让我对出了什么问题有了一些了解!

标签: reactjs asp.net-core asp.net-web-api msal.js


【解决方案1】:

从 Tiny Wang 的评论中获得一些见解,我最终涉足了一些其他文档并进行了一些 Postman 测试

在 HomePage.tsx 内:

 const getCompanies = useCallback(async () => {
    if (isAuthenticated) {
      const account = instance.getAllAccounts()[0];

      const silentRequest = {
        scopes: ["api://<MyApiAppId>/access_user_data"],
        account: account,
      };

      const token: AuthenticationResult = await instance.acquireTokenSilent(
        silentRequest
      );
      const companies = await getCompaniesAsync(token.accessToken);
      // rest of the code here
  "AzureAd": {
    "Instance": "https://login.microsoft.com",
    "Domain": "<MyDomain>",
    "TenantId": "<MyTenantId>",
    "ClientId": "api://<MyApiAppId>",
    "Audience": "<MyFrontEndAppId>",
    "Scope": "api://<MyApiAppId>/access_user_data"
  },

出于某种原因,ClientId 请求的是 URI 而不仅仅是 ID。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-12-06
    • 2021-09-14
    • 1970-01-01
    • 1970-01-01
    • 2020-06-02
    • 2019-05-03
    • 1970-01-01
    • 2017-11-08
    相关资源
    最近更新 更多