asp.net - route - Agregue reclamos en el inicio de sesión exitoso y recupérelo en otra parte de la aplicación
razor partial (5)
Necesito ayuda para implementar una forma personalizada de asignar reclamaciones a usuarios autenticados. En el inicio de sesión exitoso,
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
//Get the user
ApplicationUser user = UserManager.FindByEmail(model.Email);
//Ends here
ClaimsIdentity identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = true }, identity);
Utilizo userId para obtener el rol y otra información sobre el usuario del almacén de datos. Después de eso, debo agregar reclamos sobre el usuario con información como correo electrónico, rol, nombre, apellido, género, etc. antes de redirigir al panel de control del usuario. Esta es la forma en que trato de hacerlo, pero el problema es que incluso después de agregar las reclamaciones en el método de inicio de sesión, no puedo recuperarlo en la vista de la máquina de afeitar parcial _login
Por ejemplo, cuando quiero mostrar el valor de reclamo de correo electrónico en el inicio de sesión parcial como este
var claims = ClaimsPrincipal.Current.Claims;
var principal = (ClaimsPrincipal)Thread.CurrentPrincipal;
var email = principal.Claims.Where(c => c.Type == ClaimTypes.Email).Select(c => c.Value).SingleOrDefault();
Vuelve nulo.
Por lo tanto, como resultado, solo puedo acceder a ellos con el mismo método de inicio de sesión después de agregarlos, pero necesito poder acceder a ellos desde cualquier lugar de la aplicación. Agradeceré cualquier ayuda sobre cómo poder recuperar estas reclamaciones en cualquier otro lugar a lo largo de la aplicación.
Gracias.
¿No puede acceder a User.Identity
desde la vista?
Para recuperar reclamos para un usuario, ha sido tan simple como esto para mí:
var identity = (ClaimsIdentity) User.Identity
Y luego acceda a la identity.Claims
. Reclama y usa LINQ para recuperar reclamos específicos.
Debe agregar sus reclamaciones antes de iniciar sesión no después. Considera este ejemplo:
public async Task<ActionResult> Login(LoginViewModel model,string returnUrl)
{
var user = UserManager.Find(model.Email, model.Password);
if(user!=null)
{
var ident = UserManager.CreateIdentity(user,
DefaultAuthenticationTypes.ApplicationCookie);
ident.AddClaims(new[] {
new Claim("MyClaimName","MyClaimValue"),
new Claim("YetAnotherClaim","YetAnotherValue"),
});
AuthenticationManager.SignIn(
new AuthenticationProperties() { IsPersistent = true },
ident);
return RedirectToLocal(returnUrl);
}
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
Ahora que hemos inyectado nuestros reclamos al iniciar sesión, tenemos acceso a los reclamos donde queramos:
((ClaimsIdentity)User.Identity).FindFirst("MyClaimName");
También puede agregar sus reclamaciones en el método ApplicationUser.GenerateUserIdentityAsync()
. Al agregar sus reclamos en este método, puede usar el método SignInManager.PasswordSignInAsync()
para SignInManager.PasswordSignInAsync()
sesión en los usuarios sin ninguna modificación al método de acción de Login
predeterminado.
public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
userIdentity .AddClaims(new[] {
new Claim("MyClaimName","MyClaimValue"),
new Claim("YetAnotherClaim","YetAnotherValue"),
});
return userIdentity;
}
}
En la identidad 2, esto se hace de manera muy diferente y simplemente creando una fábrica principal de reclamaciones y luego conectándola a los servicios de configuración de inicio como se muestra a continuación ...
public class CustomClaimsPrincipalFactory : UserClaimsPrincipalFactory<IUser, IApplicationRole>
{
public CustomClaimsPrincipalFactory(UserManager<IUser> userManager, RoleManager<IApplicationRole> roleManager,
IOptions<IdentityOptions> optionsAccessor)
: base(userManager, roleManager, optionsAccessor)
{
}
public async override Task<ClaimsPrincipal> CreateAsync(IUser user)
{
var principal = await base.CreateAsync(user);
// Add your claims here
((ClaimsIdentity)principal.Identity).AddClaims(new[] { new Claim(ClaimTypes.Email, user.Email),
new Claim(ClaimTypes.Gender, user.Gender),
new Claim(ClaimTypes.GivenName, user.FirstName),
new Claim(ClaimTypes.Surname, user.LastName)
});
return principal;
}
}
Luego lo conectaría en los servicios de configuración justo después de llamar a AddIdentity de esta manera ...
services.AddIdentity<IUser, IApplicationRole>()
.AddDefaultTokenProviders();
// Add Custom Claims processor
services.AddScoped<IUserClaimsPrincipalFactory<IUser>, CustomClaimsPrincipalFactory>();
Aquí hay un muy buen artículo sobre el tema ...
https://www.codeguru.com/csharp/csharp/cs_misc/security/asp.net-core-and-claim-based-security.html
La propiedad Claim de IdentityUser le ofrece una colección IC con esa colección a la que puede llamar el siguiente método de C #:
public string GetCustomClaimValue(ICollection<IdentityUserClaim> claimCollection, string customClaimType)
{
string claimValue = "";
foreach (IdentityUserClaim claim in claimCollection)
{
if (claim.ClaimType == customClaimType)
{
claimValue = claim.ClaimValue;
break;
}
}
return claimValue;
}
Luego en la página de visualización
@(((ClaimsIdentity)User.Identity).FindFirstValue("firstName"))
Se mostrará el nombre de usuario autenticado.
e importe los siguientes paquetes en la parte superior de la página
@using Microsoft.AspNet.Identity
@using System.Security.Claims;