che*_*ica 6 asp.net asp.net-mvc asp.net-identity-2
我正在使用ASP.NET身份和a ClaimsIdentity来验证我的用户.对用户进行身份验证时,该属性User.Identity包含一个ClaimsIdentity实例.
但是,在登录请求期间不是这种情况:
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, false, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
var identity = User.Identity;
------------> // identity is of type WindowsIdentity <------------
return RedirectToLocal(returnUrl);
Run Code Online (Sandbox Code Playgroud)
如您所见,即使登录成功,该属性User.Identity尚未设置为ClaimsIdentity实例.我认为这是合理的,这意味着SignInManager不会更新属性,所以我们必须等到下一个请求才能看到登录结果.
但是,我必须在方法之后执行其他逻辑PasswordSignInAsync,因此我需要一种方法来获取switch语句ClaimsIdentity的.Success分支中的实例.
在检查SignInManager调试器时,我看到它是类型的Microsoft.Owin.Security.AuthenticationManager,它具有SignInEntry.Item1包含ClaimsIdentity我正在寻找的属性.
但是,类型Microsoft.Owin.Security.AuthenticationManager不公开,所以唯一的方法似乎是使用反射的黑客.
有更好的方法吗?
我同意PasswordSignInAsync不会将用户实例作为out参数返回太糟糕了.如果您查看源代码,您可以看到它用于this.UserManager.FindByNameAsync(userName)通过userName查找用户,然后用于this.UserManager.CheckPasswordAsync(user, password)验证密码,但用户存储在本地变量中.
我认为这应该被提议作为SignInManager类的改进.
一种可能(且效率低下)的解决方法是再次查询用户,然后以与SignInManager.SignInAsync相同的方式创建声明标识yourselft:
ApplicationUser user = await UserManager.FindByNameAsync(model.Email);
ClaimsIdentity claimsIdentity = await SignInManager.CreateUserIdentityAsync(user);
Run Code Online (Sandbox Code Playgroud)
身份通过AuthenticationResponseGrant属性公开:
ClaimsIdentity identity = SignInManager.AuthenticationManager.AuthenticationResponseGrant.Identity;
Run Code Online (Sandbox Code Playgroud)