在控制器之外获取当前用户

问题描述 投票:0回答:2

在 ASP.NET Core 2.2 控制器上,我有以下内容:

var principal = this.User as ClaimsPrincipal;

var authenticated = this.User.Identity.IsAuthenticated;

var claims = this.User.Identities.FirstOrDefault().Claims;

var id = this.User.FindFirstValue(ClaimTypes.NameIdentifier);

我能够检查用户是否是

authenticated
并获得
claims
包括
id
.

我怎么能在我没有

Controller
this.User
之外做同样的事情?

c# asp.net-core asp.net-core-2.2
2个回答
18
投票

注入

IHttpContextAccessor
接口到目标类。这将允许通过
User
访问当前
HttpContext

这提供了一个机会,通过创建一个服务来提供您想要的信息(这是当前登录的用户)来抽象此功能

public interface IUserService {
    ClaimsPrincipal GetUser();
}

public class UserService : IUserService {
    private readonly IHttpContextAccessor accessor;

    public UserService(IHttpContextAccessor accessor) {
        this.accessor = accessor;
    }

    public ClaimsPrincipal GetUser() {
        return accessor?.HttpContext?.User as ClaimsPrincipal;
    }
}

您现在需要在

IHttpContextAccessor
中设置
Startup.ConfigureServices
以便能够注入它:

services.AddHttpContextAccessor();
services.AddTransient<IUserService, UserService>();

并在需要的地方注入您的服务。

重要的是要注意

HttpContext
可能是null。只是因为 你有
IHttpContextAccessor
,不代表你会 居然总能搞定
HttpContext
。重要的是,代码在哪里 你正在使用这个must以某种方式在请求管道内或者
HttpContext
将是 null.

信用@ChrisPratt通过评论


0
投票

您不想将

IHttpContextAccessor
接口注入非 Web 服务,因为这使它依赖于 ASP.NET Core,使其在 Web 请求的上下文之外无法使用。

相反,从您所在的控制器或页面中解析用户:

var user = await _userManager.FindByNameAsync(User.Identity!.Name);

// or by Id
var userId = User.FindFirst(Claims.UserId).Value;
var user = await _userManager.FindByIdAsync(userId);

现在你有一个

ApplicationUser
实例(或任何你命名你的身份用户实体),你可以将它传递给适当的服务:

await otherService.DoSomething(foo, bar, user);
© www.soinside.com 2019 - 2024. All rights reserved.