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

ASP.NET Core页面兼容Azure AD与本地用户并调用Microsoft Graph的问题

解决方案

问题分析

核心问题在于:当页面同时允许Cookie(本地用户)和OpenIdConnect(Azure AD用户)两种认证Scheme时,Microsoft Identity Web无法自动确定使用哪个Scheme获取Azure AD令牌,导致调用Graph时抛出IDW10503异常;同时之前的双[Authorize]配置要求用户同时通过两种认证,不符合"任一认证通过即可访问"的需求。

关键修改点

  1. 调整页面授权规则:将双[Authorize]改为单个[Authorize]并通过逗号分隔两种Scheme,实现"任一认证通过即可访问"的逻辑。
  2. 明确指定Graph令牌的认证Scheme:调用Graph时,强制使用OpenIdConnectDefaults.AuthenticationScheme获取令牌,避免自动推断错误。
  3. 正确识别Azure AD用户:通过用户身份的AuthenticationScheme判断是否为Azure AD认证用户。

完整代码修改

1. 认证配置(添加Graph服务支持)

var builder = WebApplication.CreateBuilder(args);

// 配置认证,默认Scheme为Cookie
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddNegotiate() // 本地用户名密码认证
    .AddMicrosoftIdentityWebApp(builder.Configuration, "Authentication:AzureAD")
    // 添加Graph服务支持,配置所需权限
    .EnableTokenAcquisitionToCallDownstreamApi(new[] { "Mail.Read" })
    .AddMicrosoftGraph(builder.Configuration.GetSection("Graph"))
    .AddInMemoryTokenCaches();

builder.Services.AddRazorPages()
    .AddMicrosoftIdentityUI();

var app = builder.Build();

app.UseSession();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.Run();

2. Razor页面代码调整

using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.Identity.Web;
using Microsoft.Graph;

// 允许Cookie或OpenIdConnect认证的用户访问页面
[Authorize(AuthenticationSchemes = $"{CookieAuthenticationDefaults.AuthenticationScheme},{OpenIdConnectDefaults.AuthenticationScheme}")]
public class GraphCMSModel : PageModel
{
    private readonly ITokenAcquisition _tokenAcquisition;
    private readonly GraphServiceClient _graphClient;

    public string Message { get; set; } = string.Empty;

    public GraphCMSModel(ITokenAcquisition tokenAcquisition, GraphServiceClient graphClient)
    {
        _tokenAcquisition = tokenAcquisition;
        _graphClient = graphClient;
    }

    public async Task OnGetAsync()
    {
        // 判断当前用户是否通过Azure AD认证
        bool isAzureAdUser = User.Identity?.AuthenticationScheme == OpenIdConnectDefaults.AuthenticationScheme;
        
        if (isAzureAdUser)
        {
            try
            {
                // 明确指定使用OpenIdConnect Scheme获取Graph访问令牌
                var accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(
                    new[] { "Mail.Read" },
                    authenticationScheme: OpenIdConnectDefaults.AuthenticationScheme);
                
                // 使用令牌调用Graph获取未读邮件
                var unreadMessages = await _graphClient.Me.MailFolders["Inbox"].Messages
                    .Request()
                    .Filter("isRead ne true")
                    .WithBearerToken(accessToken)
                    .GetAsync();
                
                Message = $"你有 {unreadMessages.Count} 封未读邮件";
            }
            catch (Exception ex)
            {
                Message = $"获取邮件信息失败: {ex.Message}";
            }
        }
        else
        {
            Message = "暂无Graph相关信息";
        }
    }
}

补充说明

确保appsettings.json中已配置Azure AD和Graph的相关参数:

"Authentication": {
  "AzureAD": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "your-domain.onmicrosoft.com",
    "TenantId": "your-tenant-id",
    "ClientId": "your-client-id",
    "CallbackPath": "/signin-oidc"
  }
},
"Graph": {
  "BaseUrl": "https://graph.microsoft.com/v1.0",
  "Scopes": "Mail.Read"
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 00:17:45