I am trying to save a Guid
value in a cookie. The way I want to save it is by setting a Claim
for the user and getting it back in every controller for validation purposes.
Before going on the subject I have seen this question here but it did not solve my problem!
Here is my code in login controller:
public async Task<ActionResult> Login_Post(LoginViewModel loginViewModel)
{
if (ModelState.IsValid)
{
var user = IdentityManager.UserManager.FindByName(loginViewModel.Username);
if (user != null)
{
IdentityManager.SignInManager.AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
var status = SignInStatus.Failure;
if (!user.IsApproved)
{
status = SignInStatus.Failure;
}
if (!await IdentityManager.UserManager.IsEmailConfirmedAsync(user.Id))
{
status = SignInStatus.EmailNotConfirmed;
}
status = (SignInStatus)await IdentityManager.SignInManager
.PasswordSignInAsync(loginViewModel.Username, loginViewModel.Password, loginViewModel.RememberMe, true);
if (status == SignInStatus.Failure)
{
await IdentityManager.UserManager.AccessFailedAsync(user.Id);
if (await IdentityManager.UserManager.IsLockedOutAsync(user.Id))
{
status = SignInStatus.LockedOut;
}
}
switch (status)
{
case SignInStatus.Success:
var identity = await IdentityManager.UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
var permissions = IdentityManager.ApplicationDbContext.UserVesselPermissions(Guid.Parse(identity.GetUserId()), DateTime.Now).ToList();
var userVesselPermissionsResult = permissions.FirstOrDefault();
identity.AddClaim(userVesselPermissionsResult != null
? new Claim(SealogicalClaimUtility.VesselId, userVesselPermissionsResult.VesselId.ToString())
: new Claim(SealogicalClaimUtility.VesselId, ""));
IdentityManager.SignInManager.AuthenticationManager.SignIn(identity);
return RedirectToAction("Index", "HomeDashboard", new {area = "Dashboard"});
case SignInStatus.Failure:
ModelState.AddModelError("", "Login failed, username or password is incorrect.");
break;
case SignInStatus.RequiresVerification:
ModelState.AddModelError("", "Your account needs verification");
break;
case SignInStatus.LockedOut:
ModelState.AddModelError("",
"Login failed, this account has been locked. Contact administrator for further information.");
break;
case SignInStatus.EmailNotConfirmed:
ModelState.AddModelError("",
"Login failed, activate this account by clicking the email sent to your email account.");
break;
default:
ModelState.AddModelError("",
"Login failed, unkwon error. Contact administrator for further information");
break;
}
}
}
return View("Login", loginViewModel);
}
I am using PasswordSignInAsync()
method for login validation because I need to get back that SignInStatus
in order show a proper message to the user.
After that I read this question in here and they say to create a ClaimsIdentity
and then use again the AuthenticationManager
to sign in with that ClaimsIdentity
object as I did here:
case SignInStatus.Success:
var identity = await IdentityManager.UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
var permissions = IdentityManager.ApplicationDbContext.UserVesselPermissions(Guid.Parse(identity.GetUserId()), DateTime.Now).ToList();
var userVesselPermissionsResult = permissions.FirstOrDefault();
identity.AddClaim(userVesselPermissionsResult != null
? new Claim(SealogicalClaimUtility.VesselId, userVesselPermissionsResult.VesselId.ToString())
: new Claim(SealogicalClaimUtility.VesselId, ""));
IdentityManager.SignInManager.AuthenticationManager.SignIn(identity);
return RedirectToAction("Index", "HomeDashboard", new {area = "Dashboard"});
SealogicalClaimUtility
as a static class as below:
public static class SealogicalClaimUtility
{
public const string VesselId = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/vesselid";
}
Until now everything is working fine but when I try to get back that Claim
it does not exist at all.
To get back that clam I use a custom property as below:
public static Guid? UserSelectedVesselId
{
get
{
var hasVesselClaim = ((ClaimsIdentity) HttpContext.Current.User.Identity)
.HasClaim(claim => claim.Type == SealogicalClaimUtility.VesselId);
if (hasVesselClaim)
{
var vesselClaim = ((ClaimsIdentity) HttpContext.Current.User.Identity).Claims.FirstOrDefault(
claim => claim.Type == SealogicalClaimUtility.VesselId);
if (vesselClaim != null)
{
Guid vesselId;
if (Guid.TryParse(vesselClaim.Value, out vesselId))
{
return vesselId;
}
}
return null;
}
var currentUserPermission = UserVesselPermissions.FirstOrDefault();
return currentUserPermission?.VesselId;
}
}
Any idea what I am doing wrong in here ?
Thanks in advance!
I am using ASP.NET Identity version 2