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

ASP.NET MVC中Azure AD组授权异常:已在组内仍遭访问拒绝

ASP.NET MVC Azure AD组授权访问被拒绝问题

我在ASP.NET MVC控制器的特定视图页面上使用[Authorize(Policy = "it")]实施授权,明明已经加入了策略中指定的Azure AD组,但一直收到“Access denied”提示。

相关代码

Startup.cs

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
        
    }

    public IConfiguration Configuration { get; }
    
    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        // Get the scopes from the configuration (appsettings.json)
        var initialScopes = Configuration.GetValue<string>("DownstreamApi:Scopes")?.Split(' ');
        

        // Add sign-in with Microsoft
        services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
            .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"))

            // Add the possibility of acquiring a token to call a protected web API
            .EnableTokenAcquisitionToCallDownstreamApi(initialScopes)

            // Enables controllers and pages to get GraphServiceClient by dependency injection
            // And use an in memory token cache
            .AddMicrosoftGraph(Configuration.GetSection("DownstreamApi"))
            .AddDistributedTokenCaches();
        
        services.AddAuthorization(options =>
        {
            options.AddPolicy("it", policy => policy.RequireClaim("groups", "Azure group ID here"));
        });
        
        // Register AadService and PbiEmbedService for dependency injection
        services.AddScoped(typeof(AadService))
                .AddScoped(typeof(PbiEmbedService))
                .AddScoped(typeof(PowerBiServiceApi));

        services.AddControllersWithViews(options =>
        {
            var policy = new AuthorizationPolicyBuilder()
                .RequireAuthenticatedUser()
                .Build();
            options.Filters.Add(new AuthorizeFilter(policy));
        });

        // Enables a UI and controller for sign in and sign out.
        services.AddRazorPages()
            .AddMicrosoftIdentityUI();
        
        // Session/cookie variables etc

        services.AddDistributedMemoryCache();
        services.AddSession();
        
        
        // Loading appsettings.json in C# Model classes
        services.Configure<AzureAd>(Configuration.GetSection("AzureAd"))
                .Configure<PowerBI>(Configuration.GetSection("PowerBI"));
        
        // Add the UI support to handle claims challenges
        services.AddServerSideBlazor()
            .AddMicrosoftIdentityConsentHandler();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }
        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

        app.UseSession();
        
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
            endpoints.MapRazorPages();
        });
    }
}

控制器授权代码

[AuthorizeForScopes(ScopeKeySection = "DownstreamApi:Scopes")]
[Authorize(Policy = "it")]
public Task<IActionResult> Index()

排查与解决方法

  • 确认组声明是否存在于令牌中:Azure AD默认不会在ID令牌中返回所有组,当用户组数量超过限制时,只会返回hasgroups声明。需要在Azure AD应用注册的「令牌配置」中启用组声明,选择「安全组」并设置为「组ID」格式。
  • 检查组ID是否正确:确保策略中填写的是Azure AD组的对象ID(不是显示名称),可在Azure AD组详情页复制正确的对象ID替换代码中的占位符。
  • 清除令牌缓存:用户登录后组变更不会同步到现有令牌,需让用户注销后重新登录,或清除应用会话缓存。
  • 验证声明名称:部分场景下组声明的完整名称是http://schemas.microsoft.com/ws/2008/06/identity/claims/groups,而非groups。可通过调试查看用户Claims集合确认,若为完整URI则修改策略:
    services.AddAuthorization(options =>
    {
        options.AddPolicy("it", policy => 
            policy.RequireClaim("http://schemas.microsoft.com/ws/2008/06/identity/claims/groups", "Azure group ID here"));
    });
    
  • 调试用户声明:在控制器中添加代码查看当前用户的所有声明,确认组ID是否存在:
    public Task<IActionResult> Index()
    {
        var userClaims = User.Claims.Select(c => $"{c.Type}: {c.Value}").ToList();
        // 可将userClaims输出到日志或调试窗口
        return ...;
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 23:31:44