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

如何在React前端与C#后端应用中限制API访问?含MSAL授权示例需求

在React+MSAL的应用中为C#后端API添加授权机制

核心思路是:React客户端通过MSAL获取后端API的访问令牌,请求API时将令牌放在请求头中;C#后端验证令牌的合法性,仅允许携带有效令牌的请求访问受保护资源。以下是具体实现步骤和示例:

React客户端:传递MSAL访问令牌到后端API

1. 初始化MSAL时配置后端API作用域

确保MSAL实例包含后端API的授权作用域(需提前在Azure AD门户中为后端API定义该作用域):

import { PublicClientApplication, InteractionRequiredAuthError } from '@azure/msal-browser';

const msalConfig = {
  auth: {
    clientId: '你的React应用客户端ID',
    authority: 'https://login.microsoftonline.com/你的租户ID',
    redirectUri: '/',
  },
};

// 后端API的作用域,格式为 api://{后端API客户端ID}/{自定义作用域名}
const apiScopes = ['api://你的后端API客户端ID/access_as_user'];
const msalInstance = new PublicClientApplication(msalConfig);

2. 封装带令牌的API调用函数

在调用后端API前,静默获取访问令牌并附加到请求头:

async function callProtectedApi(apiUrl) {
  try {
    const activeAccount = msalInstance.getActiveAccount();
    if (!activeAccount) throw new Error('当前无登录用户');

    // 静默获取访问令牌
    const tokenResponse = await msalInstance.acquireTokenSilent({
      account: activeAccount,
      scopes: apiScopes,
    });

    // 发送请求时携带Bearer令牌
    const response = await fetch(apiUrl, {
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${tokenResponse.accessToken}`,
        'Content-Type': 'application/json',
      },
    });

    if (!response.ok) throw new Error('API请求失败');
    return await response.json();
  } catch (error) {
    // 处理令牌获取失败(比如需要交互登录)
    if (error instanceof InteractionRequiredAuthError) {
      await msalInstance.acquireTokenPopup({ scopes: apiScopes });
      return callProtectedApi(apiUrl); // 重试请求
    }
    throw error;
  }
}

C#后端(ASP.NET Core):验证MSAL令牌并授权

1. 安装依赖包

通过NuGet安装Azure AD认证相关包:

dotnet add package Microsoft.Identity.Web

2. 配置认证服务

在Program.cs中添加Azure AD令牌验证配置:

var builder = WebApplication.CreateBuilder(args);

// 添加Azure AD API认证服务
builder.Services.AddMicrosoftIdentityWebApiAuthentication(builder.Configuration)
    .EnableTokenAcquisitionToCallDownstreamApi()
    .AddInMemoryTokenCaches();

// 添加控制器服务
builder.Services.AddControllers();

var app = builder.Build();

// 启用认证和授权中间件(顺序不能错)
app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();

3. 配置appsettings.json

添加Azure AD相关配置,确保与客户端和后端API的Azure AD信息一致:

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "你的租户ID",
    "ClientId": "你的后端API客户端ID",
    "Audience": "api://你的后端API客户端ID" // 需与令牌的aud字段匹配
  }
}

4. 保护API端点

在控制器或方法上添加[Authorize]属性,限制仅认证用户可访问:

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;

[ApiController]
[Route("api/[controller]")]
[Authorize] // 整个控制器的所有接口都需要授权
public class ProtectedDataController : ControllerBase
{
    [HttpGet]
    public IActionResult GetUserInfo()
    {
        // 从令牌中获取当前用户信息
        var userId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
        var userName = User.FindFirst(ClaimTypes.Name)?.Value;
        return Ok(new 
        { 
            Message = "这是受保护的API数据", 
            UserId = userId, 
            UserName = userName 
        });
    }

    // 可选:验证特定作用域
    [HttpGet("scope-protected")]
    [Authorize(Policy = "RequireAccessAsUserScope")]
    public IActionResult GetScopeProtectedData()
    {
        return Ok(new { Message = "该接口需要access_as_user作用域权限" });
    }
}

5. 可选:自定义作用域验证策略

如果需要验证请求令牌包含特定作用域,可在Program.cs中添加授权策略:

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("RequireAccessAsUserScope", policy =>
    {
        policy.RequireClaim("scp", "access_as_user");
    });
});

关键注意事项

  • 确保Azure AD门户中,后端API已正确暴露access_as_user作用域,且React应用已被授予该作用域的权限
  • 客户端和后端的租户ID、后端API客户端ID必须完全一致
  • 后端会自动验证令牌的签名、过期时间、受众等信息,无需手动处理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 09:00:18