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

如何在ASP.NET Core MVC应用中基于Azure AD用户查询信息

实现基于Azure AD认证的用户信息查询与复用方案

1. 创建用户信息实体与查询服务

先定义数据库对应的用户实体(假设你已有类似结构),再实现一个可注入的服务类,用于从数据库获取当前认证用户的扩展信息:

// 数据库用户实体示例
public class AppUser
{
    public string Id { get; set; }
    public string PreferredUsername { get; set; }
    public string PhoneNumber { get; set; }
    // 自定义权限标识,用于授权判断
    public bool IsAllowedToViewRestrictedContent { get; set; }
}

// 可注入的当前用户信息服务
public class CurrentAppUser
{
    private readonly AppDbContext _dbContext;
    private readonly ClaimsPrincipal _currentUser;
    private AppUser _cachedUser;

    public CurrentAppUser(AppDbContext dbContext, IHttpContextAccessor httpContextAccessor)
    {
        _dbContext = dbContext;
        _currentUser = httpContextAccessor.HttpContext?.User 
            ?? throw new InvalidOperationException("当前无有效用户上下文");
    }

    // 延迟加载用户信息,避免重复查询数据库
    public AppUser UserInfo => _cachedUser ??= _dbContext.AppUsers
        .FirstOrDefault(u => u.PreferredUsername == _currentUser.FindFirstValue("preferred_username"))
        ?? throw new KeyNotFoundException("数据库中未找到当前用户");

    // 封装授权判断逻辑
    public bool IsRequirementBasedOnLookedUpInformation => UserInfo.IsAllowedToViewRestrictedContent;
}

2. 注册依赖注入服务

在Program.cs中注册所需服务(保持你的Azure AD认证配置不变):

// 注册Http上下文访问器,用于获取当前请求的用户信息
builder.Services.AddHttpContextAccessor();

// 将CurrentAppUser注册为Scoped,每个请求生成一个实例
builder.Services.AddScoped<CurrentAppUser>();

// 你的Azure AD认证配置保留
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureB2C"));

3. 在控制器中注入使用

直接在控制器构造函数中注入CurrentAppUser,即可获取用户扩展信息:

public class CashFlowAnalysisController : Controller
{
    private readonly AppDbContext _dbContext;
    private readonly CurrentAppUser _currentAppUser;

    public CashFlowAnalysisController(AppDbContext dbContext, CurrentAppUser currentAppUser)
    {
        _dbContext = dbContext;
        _currentAppUser = currentAppUser;
    }

    public IActionResult Index()
    {
        // 获取用户手机号
        var userPhone = _currentAppUser.UserInfo.PhoneNumber;
        // 判断权限
        var hasAccess = _currentAppUser.IsRequirementBasedOnLookedUpInformation;
        return View();
    }
}

4. 实现自定义授权策略

创建授权需求与处理器,用于支持[Authorize]特性的策略判断:

// 授权需求类
public class UserInfoBasedRequirement : IAuthorizationRequirement { }

// 授权处理器
public class UserInfoBasedRequirementHandler : AuthorizationHandler<UserInfoBasedRequirement>
{
    private readonly CurrentAppUser _currentAppUser;

    public UserInfoBasedRequirementHandler(CurrentAppUser currentAppUser)
    {
        _currentAppUser = currentAppUser;
    }

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, UserInfoBasedRequirement requirement)
    {
        if (_currentAppUser.IsRequirementBasedOnLookedUpInformation)
        {
            context.Succeed(requirement);
        }
        return Task.CompletedTask;
    }
}

在Program.cs中注册授权策略与处理器:

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("IsRequirementBasedOnLookedUpInformation", policy =>
        policy.Requirements.Add(new UserInfoBasedRequirement()));
});

builder.Services.AddScoped<IAuthorizationHandler, UserInfoBasedRequirementHandler>();

之后即可在控制器/Action上使用该策略:

[Authorize(Policy = "IsRequirementBasedOnLookedUpInformation")]
public IActionResult RestrictedAction()
{
    return View();
}

5. 在Razor视图中使用

在视图顶部注入CurrentAppUser,直接通过属性控制视图渲染:

@inject CurrentAppUser CurrentUser

@if (CurrentUser.IsRequirementBasedOnLookedUpInformation)
{
    <div class="authorized-content">
        <p>您有权限查看此内容</p>
        <p>绑定手机号:@CurrentUser.UserInfo.PhoneNumber</p>
    </div>
}
else
{
    <p>您无权限访问此内容</p>
}

关键注意事项

  • 你之前尝试的IUserClaimsPrincipalFactory属于ASP.NET Identity框架组件,而你使用的是Azure AD的OpenID Connect认证,未集成Identity,因此会缺失UserManager等依赖导致报错,本方案完全基于Azure AD认证的ClaimsPrincipal,无需依赖Identity。
  • 确保Azure AD返回的Claims中包含preferred_username,若未包含,需在Azure AD应用配置中添加对应的声明映射。
  • CurrentAppUser采用延迟加载逻辑,仅在首次访问UserInfo时查询数据库,减少不必要的数据库请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 01:25:26