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

在.NET 8 Blazor Server类中获取Entra Id登录用户信息

在.NET 8 Blazor Server(Entra ID认证)中实现类内获取当前登录用户

核心思路

通过依赖注入直接获取当前用户的ClaimsPrincipal,封装成统一的用户信息服务,避免在组件中重复传递用户参数。以下是具体实现步骤:

1. 注册必要服务(Program.cs)

Blazor Server已原生支持注入ClaimsPrincipal,只需确保认证服务已配置(你已通过Entra ID完成这一步)。若需要额外封装服务,添加:

// 注册自定义用户信息服务(作用域与当前用户会话绑定)
builder.Services.AddScoped<CurrentUserService>();

2. 封装统一的用户信息服务

创建CurrentUserService类,集中处理用户信息的获取逻辑:

using System.Security.Claims;

public class CurrentUserService
{
    private readonly ClaimsPrincipal _currentUser;

    // 直接注入当前用户的ClaimsPrincipal
    public CurrentUserService(ClaimsPrincipal currentUser)
    {
        _currentUser = currentUser;
    }

    // 获取用户名(适配Entra ID常见的Claim类型)
    public string GetUserName()
    {
        // 优先取显示名称,其次取用户主体名(UPN),最后返回默认值
        return _currentUser.FindFirst(ClaimTypes.Name)?.Value 
               ?? _currentUser.FindFirst(ClaimTypes.Upn)?.Value 
               ?? "未知用户";
    }

    // 获取用户唯一ID
    public string GetUserId()
    {
        return _currentUser.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? "未知ID";
    }

    // 扩展:检查用户角色
    public bool HasRole(string roleName)
    {
        return _currentUser.IsInRole(roleName);
    }
}

3. 在普通类(如Building)中使用

通过构造函数注入CurrentUserService,即可在类内获取用户信息,用于错误日志等场景:

public class Building
{
    private readonly CurrentUserService _userService;

    public Building(CurrentUserService userService)
    {
        _userService = userService;
    }

    public void PerformDatabaseOperation()
    {
        try
        {
            // 模拟数据库操作抛出异常
            throw new InvalidOperationException("数据库连接不可用");
        }
        catch (Exception ex)
        {
            // 补充用户元数据后记录日志
            string currentUser = _userService.GetUserName();
            string logContent = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 用户:{currentUser} | 错误:{ex.Message}\n";
            File.AppendAllText("error.log", logContent);
        }
    }
}

4. 在AuthTest类中获取用户名

同样通过注入CurrentUserService实现:

public class AuthTest
{
    private readonly CurrentUserService _userService;

    public AuthTest(CurrentUserService userService)
    {
        _userService = userService;
    }

    public string GetCurrentUserName()
    {
        return _userService.GetUserName();
    }
}

记得在Program.cs注册AuthTest为作用域服务:

builder.Services.AddScoped<AuthTest>();

关键注意事项

  • Blazor Server中,Scoped服务的生命周期与SignalR用户会话绑定,注入的ClaimsPrincipal始终对应当前登录用户。
  • 避免使用IHttpContextAccessor:Blazor Server后续的SignalR交互中HttpContext可能为null,直接注入ClaimsPrincipal是官方推荐的安全方式。
  • Entra ID返回的Claim类型可根据应用注册配置调整,比如部分场景下用ClaimTypes.Email作为用户名,需修改FindFirst的参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 06:22:15