2015-07-02 11 views
17

Używam Identity v2 i MVC 5 do logowania zewnętrznego.Jak mogę uzyskać Identyfikator użytkownika tożsamości w kontrolerze zaraz po pomyślnym wyniku logowania?

W moim zewnętrznym funkcji logowania zwrotnego, zalogować użytkownika na z

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

to nie jest przełącznik dla result i muszę uzyskać dostęp do identyfikatora użytkownika w przypadku success, ale User.Identity.GetUserId(); daje mi tutaj null.

Jak mogę uzyskać dostęp do identyfikatora użytkownika w tym przypadku?

+0

Trzeba tworzyć niestandardowe ExternalSignInAsync methiod który powróci model z ID użytkownika i wyników sukcesu. Sprawdź pakiet Install-Package Microsoft.AspNet.Identity.Samples nuget, aby uzyskać więcej informacji. – DSR

+0

Możliwy duplikat [Używanie tożsamości MVC 5, nie można uzyskać nazwy użytkownika zaraz po zalogowaniu] (http://stackoverflow.com/questions/30429373/using-mvc-5s-identity-cant-get-user-name- zaraz po zalogowaniu) –

Odpowiedz

31

aby uzyskać dane roszczeń i inne informacje o podpisane w tożsamości natychmiast po pomyślnym zalogowaniu, bez przechodzenia do bazy danych, wystarczy uzyskać dostęp do signinManager.AuthenticationManager.AuthenticationResponseGrant.Identity.

Na przykład

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

Można również zobaczyć, że wykorzystywane w this other question's answer dodawać nowe roszczenia do tożsamości natychmiast po login - AuthenticationManager.AuthenticationResponseGrant.Identity.AddClaims(freshClaims);

+0

To zdecydowanie jest najłatwiejsze rozwiązanie! – kloarubeek

+0

Dziękuję - Dokładnie tego chciałem. – Aaron

+0

Szukałem tego przez wieki. Użyłem: Dim IDClaim jako Claim = signInManager.AuthenticationManager.AuthenticationResponseGrant.Identity.Claims.FirstOrDefault (Funkcja (o) o.Type = ClaimTypes.NameIdentifier) ​​ Dim UserID jako Integer = Convert.ToInt32 (IDClaim.Value). Dzięki! – Resource

0

OK, znalazłem jeden sposób; Mogę dostać to przez:

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

Ale nie sądzę, że jest to najlepsze rozwiązanie, ponieważ wydaje mi się, że trafiłem w DB z dwoma pytaniami. Czy ktokolwiek może zaoferować lepsze rozwiązanie?

+0

Niezbyt dobry sposób. Nie idź do bazy danych dla UserID.UserId, e-mail już istnieje w roszczeń tożsamości. –

+0

@Serdar Çatalpınar: Dokładnie mój punkt w pytaniu o lepszy sposób. Dziękuję za odpowiedź. –

2

możesz użyć poniższego kodu.

funkcji Dodaj do klasy ApplicationSignInManager w 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); 
} 

Spróbuj ths kod

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

Niestety, zbyt szybko to zaakceptowałem. Cokolwiek robię, Tożsamość.GetUserId (); nie daje mi nic oprócz zerowego zaraz po sukcesie logowania. Domyślam się, że czeka na pewien etap procesu logowania. –

+0

Problem polega na tym, że gdy metoda signinmanager jest wywoływana i zwraca wynik pomyślny, nie aktualizuje obiektu tożsamości użytkownika, który ma zostać uwierzytelniony. Masz pomysł, jak mogę go zmusić do aktualizacji? –

+0

możesz spróbować w powyższym kodzie. Zmieniłem linie kodu. –

1

używam System.Security.Claims.ClaimTypes.NameIdentifier obiekt zachować mój identyfikator użytkownika

I stworzyłem klasę pomocników, aby osiągnąć wartości w niej

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

i wzywam go

var user = UserHelper.GetUserId(); 
+0

Dzięki, rozwiązałem mój problem – Parveen

Powiązane problemy