MVC 5 Access Claims Identity User Data

Estoy desarrollando una aplicación web MVC 5 utilizando Entity Framework 5 Database First . Estoy usando OWIN para la autenticación de los usuarios. A continuación se muestra mi método de inicio de sesión dentro de mi controlador de cuenta.

public ActionResult Login(LoginViewModel model, string returnUrl) { if (ModelState.IsValid) { var user = _AccountService.VerifyPassword(model.UserName, model.Password, false); if (user != null) { var identity = new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, model.UserName), }, DefaultAuthenticationTypes.ApplicationCookie, ClaimTypes.Name, ClaimTypes.Role); identity.AddClaim(new Claim(ClaimTypes.Role, "guest")); identity.AddClaim(new Claim(ClaimTypes.GivenName, "A Person")); identity.AddClaim(new Claim(ClaimTypes.Sid, user.userID)); //OK to store userID here? AuthenticationManager.SignIn(new AuthenticationProperties { IsPersistent = model.RememberMe }, identity); return RedirectToAction("Index", "MyDashboard"); } else { ModelState.AddModelError("", "Invalid username or password."); } } // If we got this far, something failed, redisplay form return View(model); } 

Como puede ver, estoy creando una ClaimsIdentity y agregando varias afirmaciones sobre ella, y luego la paso a OWIN utilizando AuthenticationManager para realizar el inicio de sesión.

El problema que estoy teniendo es que no estoy seguro de cómo acceder a los reclamos en el rest de mi aplicación, ya sea en Controladores o en Vistas Razor.

Probé el enfoque que figura en este tutorial

http://brockallen.com/2013/10/24/a-primer-on-owin-cookie-authentication-middleware-for-the-asp-net-developer/

Por ejemplo, intenté esto en mi código de Controller en un bash de obtener acceso a los valores pasados ​​a las Reclamaciones, sin embargo, el usuario.Claims es igual a nulo

 var ctx = HttpContext.GetOwinContext(); ClaimsPrincipal user = ctx.Authentication.User; IEnumerable claims = user.Claims; 

Quizás me estoy perdiendo algo aquí.

ACTUALIZAR

Sobre la base de la respuesta de Darin, agregué su código pero todavía no veo el acceso a las Reclamaciones. Por favor, mira la siguiente captura de pantalla que muestra lo que veo cuando se cierne sobre la identidad. Reclamaciones.

enter image description here

Prueba esto:

 [Authorize] public ActionResult SomeAction() { var identity = (ClaimsIdentity)User.Identity; IEnumerable claims = identity.Claims; ... } 

También puedes hacer esto:

 //Get the current claims principal var identity = (ClaimsPrincipal)Thread.CurrentPrincipal; var claims = identity.Claims; 

Actualizar

Para proporcionar una explicación más detallada según los comentarios.

Si está creando usuarios dentro de su sistema de la siguiente manera:

 UserManager userManager = new UserManager(new UserStore(new SecurityContext())); ClaimsIdentity identity = userManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie); 

Debe tener automáticamente algunas reclamaciones relacionadas con su identidad.

Para agregar notificaciones personalizadas después de que un usuario se autentique, puede hacerlo de la siguiente manera:

 var user = userManager.Find(userName, password); identity.AddClaim(new Claim(ClaimTypes.Email, user.Email)); 

Los reclamos se pueden leer de nuevo como Darin respondió anteriormente o como lo hice.

Las reclamaciones se conservan cuando llamas a continuación y pasas la identidad en:

 AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = persistCookie }, identity); 

Este artículo describe esto con más detalle y es específico de MVC 5, los otros artículos que conozco están dirigidos a MVC 4.

http://kevin-junghans.blogspot.co.uk/2013/12/using-claims-in-aspnet-identity.html

Hago mi propia clase extendida para ver lo que necesito, así que cuando lo necesito en mi controlador o en mi View, solo agrego el uso a mi espacio de nombres de algo como esto:

 public static class UserExtended { public static string GetFullName(this IPrincipal user) { var claim = ((ClaimsIdentity)user.Identity).FindFirst(ClaimTypes.Name); return claim == null ? null : claim.Value; } public static string GetAddress(this IPrincipal user) { var claim = ((ClaimsIdentity)user.Identity).FindFirst(ClaimTypes.StreetAddress); return claim == null ? null : claim.Value; } public .... { ..... } } 

En mi controlador:

 using XXX.CodeHelpers.Extended; var claimAddress = User.GetAddress(); 

En mi razor de afeitar:

 @using DinexWebSeller.CodeHelpers.Extended; @User.GetFullName() 

Esta es una alternativa si no desea usar reclamos todo el tiempo. Eche un vistazo a este tutorial de Ben Foster.

 public class AppUser : ClaimsPrincipal { public AppUser(ClaimsPrincipal principal) : base(principal) { } public string Name { get { return this.FindFirst(ClaimTypes.Name).Value; } } } 

Entonces puedes agregar un controlador base.

 public abstract class AppController : Controller { public AppUser CurrentUser { get { return new AppUser(this.User as ClaimsPrincipal); } } } 

En tu controlador, harías:

 public class HomeController : AppController { public ActionResult Index() { ViewBag.Name = CurrentUser.Name; return View(); } } 

También puedes hacer esto.

 IEnumerable claims = ClaimsPrincipal.Current.Claims; 

Para seguir tocando la respuesta de Darin, puede acceder a sus reclamos específicos utilizando el método FindFirst :

 var identity = (ClaimsIdentity)User.Identity; var role = identity.FindFirst(ClaimTypes.Role).Value; 
 Request.GetOwinContext().Authentication.User.Claims 

Sin embargo, es mejor agregar los reclamos dentro del método “GenerateUserIdentityAsync”, especialmente si se habilita regenerateIdentity en el Startup.Auth.cs.

Recuerde que para consultar el IEnumerable necesita hacer referencia a system.linq.
Le dará el objeto de extensión necesario para hacer:

 CaimsList.FirstOrDefault(x=>x.Type =="variableName").toString(); 

La versión más corta y simplificada de la respuesta de @Rosdi Kasim es

 string claimvalue = ((System.Security.Claims.ClaimsIdentity)User.Identity). FindFirst("claimname").Value; 

Claimname es el reclamo que desea recuperar, es decir, si está buscando el reclamo “StreedAddress”, entonces la respuesta anterior será como esta

 string claimvalue = ((System.Security.Claims.ClaimsIdentity)User.Identity). FindFirst("StreedAddress").Value; 

De acuerdo con la clase ControllerBase, puede obtener los reclamos para el usuario que ejecuta la acción.

enter image description here

así es cómo puedes hacerlo en 1 línea.

 var claims = User.Claims.ToList(); 
 var claim = User.Claims.FirstOrDefault(c => c.Type == "claim type here");