web-dev-qa-db-fra.com

comment puis-je obtenir Identity UserID dans le contrôleur juste après un résultat de connexion réussi?

J'utilise Identity v2 et MVC 5 pour la connexion externe.

Dans ma fonction de rappel de connexion externe, je connecte l'utilisateur avec

var result = await SignInManager.ExternalSignInAsync(loginInfo, isPersistent: false);

alors il y a un commutateur pour le result, et j'ai besoin d'accéder à l'ID de l'utilisateur dans le cas success, mais User.Identity.GetUserId(); me donne null ici.

Comment puis-je accéder à l'ID utilisateur dans ce cas?

20
A. Burak Erbora

Pour obtenir les données de réclamation et autres informations sur l'identité signée immédiatement lors d'une connexion réussie, sans accéder à la base de données, il suffit d'accéder à signinManager.AuthenticationManager.AuthenticationResponseGrant.Identity .

Par exemple,

switch (result) { case SignInStatus.Success: var userId = signinManager.AuthenticationManager.AuthenticationResponseGrant .Identity.GetUserId(); // ...

Vous pouvez également le voir utilisé dans la réponse à cette autre question pour ajouter de nouvelles revendications à une identité immédiatement après la connexion - AuthenticationManager.AuthenticationResponseGrant.Identity.AddClaims(freshClaims);

36
Wayne Bloss

J'utilise System.Security.Claims.ClaimTypes.NameIdentifier objet pour conserver mon identifiant

Et j'ai créé une classe d'aide pour atteindre les valeurs qu'il contient

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;
    }
  }

et je l'appelle avec

var user = UserHelper.GetUserId();
4
Project Mayhem

vous pouvez utiliser le code ci-dessous.

Ajouter une fonction à la classe ApplicationSignInManager dans Identity.Config.cs

 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);
}

Essayez ce code

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;
        }
1

OK, j'ai trouvé one way; Je peux l'obtenir via:

var userID = UserManager.FindByEmail(loginInfo.Email).Id;

Mais, je ne pense pas que ce soit la meilleure solution car il semble que j'ai frappé la base de données avec deux requêtes. Quelqu'un peut-il offrir une meilleure solution?

1
A. Burak Erbora