2

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

Community
  • 1
  • 1
Rey
  • 3,663
  • 3
  • 32
  • 55

0 Answers0