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

多租户场景下基于MSAL实现授权码流及Graph API调用方案咨询

多租户场景下授权码流的实现方案

1. Azure AD应用注册配置

  • 注册一个支持SPA和Web API的多租户应用:在Azure AD中创建应用,将“支持的账户类型”设为“任何组织目录中的账户和个人Microsoft账户”。
  • 配置SPA参数:添加Angular前端的重定向URI,启用授权码流(保留PKCE,这是SPA的安全要求,MSAL Angular默认支持)。
  • 配置Web API参数:添加客户端密钥(作为机密客户端凭证),设置API权限为Graph API的委托权限(如User.Read、Mail.Read),并完成管理员同意(多租户场景下需全局管理员操作)。
  • 记录应用的客户端ID、客户端密钥、授权机构地址(https://login.microsoftonline.com/common/)。

2. Angular前端获取授权码并传递给Web API

  • 使用MSAL Angular库初始化,仅配置授权码获取逻辑,禁用自动令牌交换:
    MsalModule.forRoot(new PublicClientApplication({
      auth: {
        clientId: '你的SPA客户端ID',
        authority: 'https://login.microsoftonline.com/common/',
        redirectUri: 'Angular前端地址',
      },
      cache: {
        cacheLocation: BrowserCacheLocation.LocalStorage,
        storeAuthStateInCookie: false,
      }
    }), {
      interactionType: InteractionType.Redirect,
      authRequest: {
        responseType: 'code', // 仅获取授权码
        scopes: ['User.Read', 'Mail.Read']
      }
    })
    
  • 用户登录后,通过MSAL的回调或路由参数捕获授权码,再通过POST请求将授权码发送至Web API的指定接口。

3. .NET 6 Web API交换授权码并存储令牌

  • 安装Microsoft.Identity.Client和Microsoft.Graph NuGet包。
  • 编写接口接收授权码,使用MSAL.NET交换获取访问令牌、刷新令牌:
    [HttpPost("exchange-code")]
    public async Task<IActionResult> ExchangeAuthorizationCode([FromBody] string code)
    {
        var confidentialClient = ConfidentialClientApplicationBuilder
            .Create("Web API客户端ID")
            .WithClientSecret("Web API客户端密钥")
            .WithAuthority("https://login.microsoftonline.com/common/")
            .WithRedirectUri("Web API的重定向URI(需与Azure AD配置完全一致)")
            .Build();
    
        var result = await confidentialClient.AcquireTokenByAuthorizationCode(
            new[] { "User.Read", "Mail.Read" },
            code
        ).ExecuteAsync();
    
        // 将令牌(AccessToken、RefreshToken)、过期时间、关联用户ID存入SQL数据库
        // 注意:令牌需加密存储,避免明文泄露
        return Ok(new { Success = true });
    }
    

4. .NET 6 Windows服务调用Graph API并自动刷新令牌

  • 安装Microsoft.Identity.Client和Microsoft.Graph NuGet包。
  • 从SQL数据库读取用户的刷新令牌,使用MSAL.NET刷新获取新令牌:
    private async Task<string> GetValidAccessToken(string refreshToken)
    {
        var confidentialClient = ConfidentialClientApplicationBuilder
            .Create("Web API客户端ID")
            .WithClientSecret("Web API客户端密钥")
            .WithAuthority("https://login.microsoftonline.com/common/")
            .Build();
    
        var result = await confidentialClient.AcquireTokenByRefreshToken(
            new[] { "User.Read", "Mail.Read" },
            refreshToken
        ).ExecuteAsync();
    
        // 更新数据库中的新AccessToken、RefreshToken和过期时间
        return result.AccessToken;
    }
    
  • 调用Graph API逻辑:
    private async Task CallGraphApi(string accessToken)
    {
        var graphClient = new GraphServiceClient(
            new DelegateAuthenticationProvider(req =>
            {
                req.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
                return Task.CompletedTask;
            })
        );
    
        var userProfile = await graphClient.Me.Request().GetAsync();
        // 处理Graph API返回结果
    }
    
  • 自动刷新机制:
    • 定时检查数据库中令牌的过期时间,提前5分钟触发刷新;
    • 调用Graph API时捕获ServiceException,判断是否为令牌过期错误,若则刷新令牌后重试请求。

关键注意事项

  • 权限一致性:前端、Web API、Windows服务使用的权限范围必须完全一致,否则令牌无法用于Graph API调用。
  • 安全存储:客户端密钥、数据库中的令牌需加密存储,避免泄露;Windows服务使用AD身份验证访问SQL数据库。
  • 多租户适配:授权机构统一使用common,确保任何租户用户都能完成授权流程。
  • 版本兼容:使用最新版的MSAL.NET和MSAL Angular,避免出现兼容性问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 05:12:46