我正在使用Identity v2和MVC 5进行外部登录。
在我的外部登录回调函数中,我使用以下代码将用户登录:
var result = await SignInManager.ExternalSignInAsync(loginInfo, isPersistent: false);
然后有一个用于result
的开关,我需要在success
情况下访问用户的ID,但是User.Identity.GetUserId();
在这里为null。
我该如何在这种情况下访问用户的ID?
我正在使用Identity v2和MVC 5进行外部登录。
在我的外部登录回调函数中,我使用以下代码将用户登录:
var result = await SignInManager.ExternalSignInAsync(loginInfo, isPersistent: false);
然后有一个用于result
的开关,我需要在success
情况下访问用户的ID,但是User.Identity.GetUserId();
在这里为null。
我该如何在这种情况下访问用户的ID?
成功登录后,如果想即时获取有关已登录身份的索赔数据和其他信息而不需要访问数据库,只需访问signinManager.AuthenticationManager.AuthenticationResponseGrant.Identity
。
例如,
switch (result)
{
case SignInStatus.Success:
var userId = signinManager.AuthenticationManager.AuthenticationResponseGrant
.Identity.GetUserId();
// ...
您还可以在此其他问题的答案中看到它被用于在登录后立即向标识添加新声明 - AuthenticationManager.AuthenticationResponseGrant.Identity.AddClaims(freshClaims);
System.Security.Claims.ClaimTypes.NameIdentifier
对象来保存我的用户ID。public class UserHelper
{
public static string GetUserId()
{
var identity = (System.Security.Claims.ClaimsPrincipal)System.Threading.Thread.CurrentPrincipal;
var principal = System.Threading.Thread.CurrentPrincipal as System.Security.Claims.ClaimsPrincipal;
var userId = identity.Claims.Where(c => c.Type == System.Security.Claims.ClaimTypes.NameIdentifier).Select(c => c.Value).SingleOrDefault();
return userId;
}
public static string GetUserName()
{
var identity = (System.Security.Claims.ClaimsPrincipal)System.Threading.Thread.CurrentPrincipal;
var principal = System.Threading.Thread.CurrentPrincipal as System.Security.Claims.ClaimsPrincipal;
var name = identity.Claims.Where(c => c.Type == System.Security.Claims.ClaimTypes.Name).Select(c => c.Value).SingleOrDefault();
return name;
}
public static string GetUserMail()
{
var identity = (System.Security.Claims.ClaimsPrincipal)System.Threading.Thread.CurrentPrincipal;
var principal = System.Threading.Thread.CurrentPrincipal as System.Security.Claims.ClaimsPrincipal;
var mail = identity.Claims.Where(c => c.Type == System.Security.Claims.ClaimTypes.Email).Select(c => c.Value).SingleOrDefault();
return mail;
}
}
我称之为,并使用以下方式调用:
var user = UserHelper.GetUserId();
好的,我找到了一种方法;我可以通过以下方式获取它:
onevar userID = UserManager.FindByEmail(loginInfo.Email).Id;
但是,我认为这不是最好的解决方案,因为它似乎需要使用两个查询来访问数据库。有没有人能提供更好的解决方案呢?
public override Task SignInAsync(ApplicationUser user, bool isPersistent, bool rememberBrowser)
{
var claims = new List<Claim>()
{
new Claim(ClaimTypes.NameIdentifier, user.Id),
new Claim(ClaimTypes.Email, user.Email)
};
this.AuthenticationManager.User.AddIdentity(new ClaimsIdentity(claims));
return base.SignInAsync(user, isPersistent, rememberBrowser);
}
private ClaimsPrincipal GetCurrentUser()
{
var context = HttpContext.GetOwinContext();
if (context == null)
return null;
if (context.Authentication == null || context.Authentication.User == null)
return null;
return context.Authentication.User;
}
private string GetUserId()
{
var user = GetCurrentUser();
if (user == null)
return null;
var claim = user.Claims.FirstOrDefault(o => o.Type == ClaimTypes.NameIdentifier);
if (claim == null)
return null;
return claim.Value;
}
private string GetUserEmail()
{
var user = GetCurrentUser();
if (user == null)
return null;
var claim = user.Claims.FirstOrDefault(o => o.Type == ClaimTypes.Email);
if (claim == null)
return null;
return claim.Value;
}
var result =
await _signInManager.PasswordSignInAsync(model.UserName, model.Password, true, lockoutOnFailure: true);
if (result.Succeeded)
{
var userId = _signInManager.UserManager.Users.FirstOrDefault()?.Id; }