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

如何通过代码限制Azure AD多租户Razor Pages应用仅允许指定租户登录

解决方法

你可以直接通过代码实现指定租户/域名访问限制,不需要使用Azure付费的租户限制功能,以下是两种可行的实现方案:

方案1:在身份验证流程中直接校验(推荐)

该方案在用户登录完成、令牌校验通过后立刻做域名/租户校验,不满足条件直接返回403,无需后续流程处理,性能最高,无需修改其他业务代码。
修改你ConfigureServices方法中的身份验证配置即可:

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
        .AddMicrosoftIdentityWebApp(options =>
        {
            // 绑定原有AzureAd配置
            Configuration.Bind("AzureAd", options);
            // 添加令牌校验通过后的事件处理
            options.Events = new OpenIdConnectEvents
            {
                OnTokenValidated = context =>
                {
                    // 与你的伪代码逻辑一致:校验邮箱后缀
                    var userEmail = context.Principal.Identity?.Name;
                    // 可以配置多个允许的域名
                    var allowedDomains = new[] { "@alloweddomain.com" };
                    if (userEmail == null || !allowedDomains.Any(domain => 
                        userEmail.EndsWith(domain, StringComparison.OrdinalIgnoreCase)))
                    {
                        context.Fail("访问权限不足");
                        context.Response.StatusCode = 403;
                        return Task.CompletedTask;
                    }

                    // 可选更安全的校验逻辑:直接校验租户ID,避免同域名其他租户用户访问
                    // var tenantId = context.Principal.FindFirstValue("http://schemas.microsoft.com/identity/claims/tenantid");
                    // var allowedTenantIds = new[] { "你的允许租户ID1", "你的允许租户ID2" };
                    // if (tenantId == null || !allowedTenantIds.Contains(tenantId))
                    // {
                    //     context.Fail("访问权限不足");
                    //     context.Response.StatusCode = 403;
                    //     return Task.CompletedTask;
                    // }

                    return Task.CompletedTask;
                }
            };
        });

    // 原有授权配置保持不变即可
    services.AddAuthorization(options =>
    {
        options.FallbackPolicy = options.DefaultPolicy;
    });
    services.AddRazorPages()
        .AddMvcOptions(options => { })
        .AddMicrosoftIdentityUI();
}

方案2:自定义全局授权策略

如果你希望把校验逻辑放在授权层统一管理,可以通过自定义授权策略实现,所有页面默认生效:

  1. 先定义自定义授权要求和处理逻辑:
// 自定义授权要求标记类
public class AllowedAccessRequirement : IAuthorizationRequirement { }

// 授权校验逻辑处理类
public class AllowedAccessHandler : AuthorizationHandler<AllowedAccessRequirement>
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, AllowedAccessRequirement requirement)
    {
        var userEmail = context.User.Identity?.Name;
        var allowedDomains = new[] { "@alloweddomain.com" };
        if (userEmail != null && allowedDomains.Any(domain => 
            userEmail.EndsWith(domain, StringComparison.OrdinalIgnoreCase)))
        {
            context.Succeed(requirement);
        }
        else
        {
            context.Fail();
        }
        return Task.CompletedTask;
    }
}
  1. 修改ConfigureServices中的授权配置:
services.AddAuthorization(options =>
{
    options.AddPolicy("AllowedAccessPolicy", policy =>
    {
        policy.RequireAuthenticatedUser();
        policy.AddRequirements(new AllowedAccessRequirement());
    });
    // 全局生效:所有请求默认使用该策略校验
    options.FallbackPolicy = options.GetPolicy("AllowedAccessPolicy");
});
// 注册自定义授权处理程序
services.AddScoped<IAuthorizationHandler, AllowedAccessHandler>();

两种方案都可以实现你需要的效果,无需额外付费,也不需要修改现有页面的业务代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 17:09:03