asp.net - net - MVC 5 Access Claims Identity User Data
identity roles vs claims (11)
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 resto de mi aplicación, ya sea en Controladores o en Vistas Razor.
Probé el enfoque que figura en este tutorial
Por ejemplo, intenté esto en mi código de Controller en un intento 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<Claim> 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.
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();
}
}
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 navaja de afeitar:
@using DinexWebSeller.CodeHelpers.Extended;
@User.GetFullName()
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;
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;
Prueba esto:
[Authorize]
public ActionResult SomeAction()
{
var identity = (ClaimsIdentity)User.Identity;
IEnumerable<Claim> claims = identity.Claims;
...
}
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();
También puedes hacer esto.
IEnumerable<Claim> claims = ClaimsPrincipal.Current.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<applicationuser> userManager = new UserManager<applicationuser>(new UserStore<applicationuser>(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
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.
var claim = User.Claims.FirstOrDefault(c => c.Type == "claim type here");