C#怎么使用ClaimsPrincipal获取用户信息

来源:站长工具作者:落伍者头衔:草根站长
导读:本期聚焦于小伙伴创作的《C#怎么使用ClaimsPrincipal获取用户信息》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C#怎么使用ClaimsPrincipal获取用户信息》有用,将其分享出去将是对创作者最好的鼓励。

在ASP.NET Core的身份认证体系中,ClaimsPrincipal是表示用户身份的核心对象,它包含了用户的所有声明信息,我们可以通过它获取当前登录用户的各类身份数据,比如用户ID、用户名、角色等。

C#怎么使用ClaimsPrincipal获取用户信息

ClaimsPrincipal基础概念

ClaimsPrincipal对象内部包含一个或多个ClaimsIdentity,每个ClaimsIdentity又由多个Claim组成。Claim是最小的身份单元,每个Claim都有一个类型(ClaimType)和对应的值(Value),常见的Claim类型有用户ID、用户名、邮箱、角色等。

我们可以通过ClaimsPrincipalFindFirst方法查找指定类型的声明,也可以通过Claims属性遍历所有声明信息。

控制器中获取当前用户信息

在ASP.NET Core的控制器中,当前用户的ClaimsPrincipal对象可以直接通过User属性获取,这是最常用的获取场景。

获取基础用户信息示例

以下代码演示了在控制器中获取用户ID和用户名的操作:

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;

[Authorize]
[ApiController]
[Route("api/user")]
public class UserController : ControllerBase
{
    [HttpGet("info")]
    public IActionResult GetUserInfo()
    {
        // 获取当前用户的ClaimsPrincipal对象
        ClaimsPrincipal principal = User;
        
        // 获取用户ID,假设用户ID的声明类型为ClaimTypes.NameIdentifier
        string userId = principal.FindFirstValue(ClaimTypes.NameIdentifier);
        
        // 获取用户名,假设用户名的声明类型为ClaimTypes.Name
        string userName = principal.FindFirstValue(ClaimTypes.Name);
        
        // 获取用户邮箱
        string email = principal.FindFirstValue(ClaimTypes.Email);
        
        // 获取用户所有角色
        List<string> roles = principal.FindAll(ClaimTypes.Role).Select(c => c.Value).ToList();
        
        return Ok(new
        {
            UserId = userId,
            UserName = userName,
            Email = email,
            Roles = roles
        });
    }
}

自定义扩展方法简化获取

如果频繁需要获取用户ID等信息,可以编写扩展方法简化操作:

using System.Security.Claims;

public static class ClaimsPrincipalExtensions
{
    // 扩展方法获取用户ID
    public static string GetUserId(this ClaimsPrincipal principal)
    {
        if (principal == null)
        {
            throw new ArgumentNullException(nameof(principal));
        }
        return principal.FindFirstValue(ClaimTypes.NameIdentifier);
    }
    
    // 扩展方法获取用户名
    public static string GetUserName(this ClaimsPrincipal principal)
    {
        if (principal == null)
        {
            throw new ArgumentNullException(nameof(principal));
        }
        return principal.FindFirstValue(ClaimTypes.Name);
    }
}

使用扩展方法后,控制器中的代码可以简化为:

[HttpGet("simple-info")]
public IActionResult GetSimpleUserInfo()
{
    string userId = User.GetUserId();
    string userName = User.GetUserName();
    return Ok(new { UserId = userId, UserName = userName });
}

非控制器场景中获取用户信息

除了控制器,我们还可能在中间件、后台服务、自定义类中需要获取当前用户信息,这时候需要通过注入IHttpContextAccessor来获取HttpContext,进而拿到User对象。

中间件中获取用户信息

首先在Program.cs中注册IHttpContextAccessor

var builder = WebApplication.CreateBuilder(args);

// 注册IHttpContextAccessor
builder.Services.AddHttpContextAccessor();

// 添加身份认证服务(示例,实际根据项目配置)
builder.Services.AddAuthentication();

var app = builder.Build();

// 使用认证中间件
app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();

然后在中间件中获取用户信息:

using Microsoft.AspNetCore.Http;
using System.Security.Claims;
using System.Threading.Tasks;

public class UserMiddleware
{
    private readonly RequestDelegate _next;
    private readonly IHttpContextAccessor _httpContextAccessor;

    public UserMiddleware(RequestDelegate next, IHttpContextAccessor httpContextAccessor)
    {
        _next = next;
        _httpContextAccessor = httpContextAccessor;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        // 获取当前HttpContext
        HttpContext currentContext = _httpContextAccessor.HttpContext;
        if (currentContext != null && currentContext.User.Identity.IsAuthenticated)
        {
            ClaimsPrincipal principal = currentContext.User;
            string userId = principal.FindFirstValue(ClaimTypes.NameIdentifier);
            // 这里可以添加自定义逻辑,比如记录用户操作日志
        }
        await _next(context);
    }
}

后台服务中获取用户信息

后台服务如果需要获取用户信息,同样需要依赖IHttpContextAccessor,但要注意后台服务可能没有活跃的HttpContext,因此需要在有请求上下文的场景下使用:

using Microsoft.AspNetCore.Http;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

public class UserBackgroundService : BackgroundService
{
    private readonly IHttpContextAccessor _httpContextAccessor;
    private readonly ILogger<UserBackgroundService> _logger;

    public UserBackgroundService(IHttpContextAccessor httpContextAccessor, ILogger<UserBackgroundService> logger)
    {
        _httpContextAccessor = httpContextAccessor;
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            // 注意:后台服务默认没有HttpContext,这里的示例仅适用于有上下文注入的场景
            HttpContext context = _httpContextAccessor.HttpContext;
            if (context != null && context.User.Identity.IsAuthenticated)
            {
                ClaimsPrincipal principal = context.User;
                string userName = principal.FindFirstValue(ClaimTypes.Name);
                _logger.LogInformation("当前登录用户:{UserName}", userName);
            }
            await Task.Delay(1000, stoppingToken);
        }
    }
}

自定义声明添加与读取

实际开发中我们经常需要添加自定义的声明,比如用户的部门、手机号等,然后在使用时读取这些自定义声明。

登录时添加自定义声明

在用户登录生成身份票据时,可以添加自定义声明:

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using System.Security.Claims;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;

[HttpPost("login")]
public async Task<IActionResult> Login(string userName, string password)
{
    // 这里假设验证用户名密码通过
    List<Claim> claims = new List<Claim>
    {
        new Claim(ClaimTypes.NameIdentifier, "1001"),
        new Claim(ClaimTypes.Name, userName),
        // 自定义声明:用户部门
        new Claim("Department", "技术部"),
        // 自定义声明:用户手机号
        new Claim("PhoneNumber", "13800138000")
    };
    
    ClaimsIdentity identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
    ClaimsPrincipal principal = new ClaimsPrincipal(identity);
    
    // 登录,生成认证Cookie
    await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);
    
    return Ok("登录成功");
}

读取自定义声明

读取自定义声明的方式和读取系统声明一致,只需要指定对应的声明类型即可:

[HttpGet("custom-claims")]
public IActionResult GetCustomClaims()
{
    ClaimsPrincipal principal = User;
    // 读取自定义部门声明
    string department = principal.FindFirstValue("Department");
    // 读取自定义手机号声明
    string phoneNumber = principal.FindFirstValue("PhoneNumber");
    
    return Ok(new
    {
        Department = department,
        PhoneNumber = phoneNumber
    });
}

注意事项

  • 获取用户信息前要确保用户已经通过身份认证,否则User对象可能为空或者没有对应的声明,建议配合[Authorize]特性使用,或者在获取前判断User.Identity.IsAuthenticated的值。
  • 声明类型尽量使用系统预定义的ClaimTypes中的常量,比如ClaimTypes.NameIdentifierClaimTypes.Name,避免自定义字符串出现拼写错误。
  • 如果项目使用了JWT认证,声明的类型可能和Cookie认证有差异,需要根据实际的token载荷中的字段来调整查找的声明类型。
  • 在非请求上下文的场景下,比如完全没有Http请求的后台任务,无法通过IHttpContextAccessor获取用户信息,需要重新设计信息传递方式。

C#ClaimsPrincipalASP.NET_Core用户信息获取修改时间:2026-07-17 08:57:45

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。