Meh*_*izi 100 c# asp.net-identity asp.net-core
我想让当前用户获取用户的信息,例如电子邮件.但我不能在asp.net核心中这样做.我很困惑这是我的代码.
HttpContext在控制器的构造函数中几乎为null .在每个动作中获得用户并不好.我想获得用户的信息并将其设置为ViewData;
public DashboardController()
{
var user = HttpContext.User.GetUserId();
}
Run Code Online (Sandbox Code Playgroud)
ade*_*lin 127
User.FindFirst(ClaimTypes.NameIdentifier).Value
Run Code Online (Sandbox Code Playgroud)
编辑构造函数
下面代码有效:
public Controller(IHttpContextAccessor httpContextAccessor)
{
var userId = httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value
}
Run Code Online (Sandbox Code Playgroud)
编辑RTM
你应该注册IHttpContextAccessor:
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
Run Code Online (Sandbox Code Playgroud)
Ahm*_*mad 43
简单的方式,我检查.
private readonly UserManager<IdentityUser> _userManager;
public CompetitionsController(UserManager<IdentityUser> userManager)
{
_userManager = userManager;
}
var user = await _userManager.GetUserAsync(HttpContext.User);
Run Code Online (Sandbox Code Playgroud)
那么你可以将这个变量的所有属性都像user.Email.我希望这会对某人有所帮助.
Hek*_*ryk 22
有另一种方法让当前用户进入Asp.NET Core - 我想我在这里看到了它,在SO ^^上
// Stores UserManager
private readonly UserManager<ApplicationUser> _manager;
// Inject UserManager using dependency injection.
// Works only if you choose "Individual user accounts" during project creation.
public DemoController(UserManager<ApplicationUser> manager)
{
_manager = manager;
}
// You can also just take part after return and use it in async methods.
private async Task<ApplicationUser> GetCurrentUser()
{
return await _manager.GetUserAsync(HttpContext.User);
}
// Generic demo method.
public async Task DemoMethod()
{
var user = await GetCurrentUser();
string userEmail = user.Email; // Here you gets user email
string userId = user.Id;
}
Run Code Online (Sandbox Code Playgroud)
该代码转到名为DemoController的控制器.如果没有等待(将不会编译)将无法工作;)
Gra*_*zer 15
截至目前(2017年4月),以下情况似乎如下:
public string LoggedInUser => User.Identity;
Run Code Online (Sandbox Code Playgroud)
至少在一个内部 Controller
Tom*_*kel 14
也许我没有看到答案,但这就是我的做法。
您需要更改这些值
"windowsAuthentication": true, // needs to be true
"anonymousAuthentication": false, // needs to be false
Run Code Online (Sandbox Code Playgroud)
Startup.cs --> ConfigureServices(...)
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
Run Code Online (Sandbox Code Playgroud)
MVC 或 Web Api 控制器
private readonly IHttpContextAccessor _httpContextAccessor;
//constructor then
_httpContextAccessor = httpContextAccessor;
Run Code Online (Sandbox Code Playgroud)
控制器方法:
string userName = _httpContextAccessor.HttpContext.User.Identity.Name;
Run Code Online (Sandbox Code Playgroud)
结果是 userName eg = Domain\username
Sim*_*ver 11
我不得不说我很惊讶HttpContext在构造函数中为null。我确定是出于性能原因。已确认IPrincipal按如下所述使用确实会将其注入到构造函数中。它的作用基本上与接受的答案相同,但是采用的是更界面的方式。
对于任何发现此问题的人,寻找通用“如何获得当前用户?”的答案 您可以User直接从访问Controller.User。但是您只能在操作方法内部执行此操作(我想是因为控制器并不仅出于性能原因而与HttpContexts一起运行)。
但是,如果您在构造函数中需要它(如OP一样),或者需要创建需要当前用户的其他可注入对象,则下面是一种更好的方法:
第一次见到IPrincipal和IIdentity
public interface IPrincipal
{
IIdentity Identity { get; }
bool IsInRole(string role);
}
public interface IIdentity
{
string AuthenticationType { get; }
bool IsAuthenticated { get; }
string Name { get; }
}
Run Code Online (Sandbox Code Playgroud)
IPrincipal并IIdentity代表用户名和用户名。如果“校长”听起来很奇怪,维基百科将为您提供安慰。
重要的是要意识到,不管你得到它IHttpContextAccessor.HttpContext.User,ControllerBase.User或者ControllerBase.HttpContext.User你获得该保证是一个目标ClaimsPrincipal对象,它实现IPrincipal。
ASP.NET User现在没有其他类型的用户(但这并不是说其他无法实现的用户IPrincipal)。
因此,如果您要注入的东西依赖于“当前用户名”,则应该注入IPrincipal而不是绝对注入IHttpContextAccessor。
重要提示:不要浪费时间IPrincipal直接注入控制器或操作方法-这毫无意义,因为User您已经可以使用它了。
在startup.cs:
// Inject IPrincipal
services.AddTransient<IPrincipal>(provider => provider.GetService<IHttpContextAccessor>().HttpContext.User);
Run Code Online (Sandbox Code Playgroud)
然后,在需要用户的DI对象中,只需注入IPrincipal即可获取当前用户。
这里最重要的事情是如果你在做单元测试,你不需要发送一个HttpContext,而只需要模拟IPrincipal 那些可以 代表的东西ClaimsPrincipal。
我不确定100%的另一件重要事情。如果您需要访问的实际索赔,则ClaimsPrincipal需要转换IPrincipal为ClaimsPrincipal。很好,因为我们知道在运行时100%就是这种类型的(因为这就是事实HttpContext.User)。我实际上很喜欢在构造函数中执行此操作,因为我已经确定IPrincipal 可以肯定会有一个ClaimsPrincipal。
如果您要进行模拟,则只需直接创建一个ClaimsPrincipal并将其传递给takes即可IPrincipal。
到底为什么没有接口,IClaimsPrincipal我不确定。我认为MS认为那ClaimsPrincipal只是一个不需要接口的专门“集合”。
Ali*_*odi 10
我知道这里有很多正确的答案,对于所有这些,我介绍这个技巧:
在 StartUp.cs 中
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
Run Code Online (Sandbox Code Playgroud)
然后在任何需要 HttpContext 的地方都可以使用:
var httpContext = new HttpContextAccessor().HttpContext;
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你 ;)
我的问题是将登录用户作为 cshtml 文件中的对象访问。考虑到您想要 ViewData 中的用户,这种方法可能会有所帮助:
在 cshtml 文件中
@using Microsoft.AspNetCore.Identity
@inject UserManager<ApplicationUser> UserManager
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>
@UserManager.FindByNameAsync(UserManager.GetUserName(User)).Result.Email
</title>
</head>
<body>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
除了现有的答案之外,我想补充一点,您还可以在应用程序范围内拥有一个可用的类实例,其中包含与用户相关的数据等UserID。
它可能对重构 有用,例如 您不想UserID在每个控制器操作中获取并UserID在与服务层相关的每个方法中声明额外的参数。
我做了一项研究,这是我的帖子。
DbContext您只需通过添加属性来扩展派生类UserId(或实现Session具有此属性的自定义类)。
在过滤器级别,您可以获取类实例并设置UserId值。
之后,无论您在何处注入实例,它都将具有必要的数据(生命周期必须是每个请求,因此您可以使用AddScoped方法注册它)。
工作示例:
public class AppInitializationFilter : IAsyncActionFilter
{
private DBContextWithUserAuditing _dbContext;
public AppInitializationFilter(
DBContextWithUserAuditing dbContext
)
{
_dbContext = dbContext;
}
public async Task OnActionExecutionAsync(
ActionExecutingContext context,
ActionExecutionDelegate next
)
{
string userId = null;
int? tenantId = null;
var claimsIdentity = (ClaimsIdentity)context.HttpContext.User.Identity;
var userIdClaim = claimsIdentity.Claims.SingleOrDefault(c => c.Type == ClaimTypes.NameIdentifier);
if (userIdClaim != null)
{
userId = userIdClaim.Value;
}
var tenantIdClaim = claimsIdentity.Claims.SingleOrDefault(c => c.Type == CustomClaims.TenantId);
if (tenantIdClaim != null)
{
tenantId = !string.IsNullOrEmpty(tenantIdClaim.Value) ? int.Parse(tenantIdClaim.Value) : (int?)null;
}
_dbContext.UserId = userId;
_dbContext.TenantId = tenantId;
var resultContext = await next();
}
}
Run Code Online (Sandbox Code Playgroud)
更多信息请参阅我的回答。
| 归档时间: |
|
| 查看次数: |
115345 次 |
| 最近记录: |