How to extend IdentityUser as a claim in ASP.NET Core / MVC 6 / EF7?

asp.net-core asp.net-core-mvc asp.net-identity entity-framework-core

Question

I am building a site that has Users that belong to an Account. The account is identified by an AccountId which is a foreign key for most data in the DB such as Charges (associated to an Account) or Receipts (associated to an Account).

Rather than hitting the DB every time the repository needs to be polled for data to get the user's AccountId, I wanted to add the AccountId as a claim. The goal being to do something like:

_repository.GetAllChargesByAccountId(User.Identity.GetAccountId());

I'm finding only tidbits and partial solutions for this and I haven't been able to resolve some differences between those examples and my specific environment (ASP.NET Core RC1, MVC 6, EF7).

I have derived a class from IdentityUser for adding attributes about the user:

public class UserIdentity : IdentityUser {
    public static object Identity { get; internal set; }
    public int AccountId { get; set; }
}

I have created a UserIdentityContext that derives from IdentityDbContext that I'm using for my EF user store.

And I have the following AuthController:

public class AuthController : Controller {
    private SignInManager<UserIdentity> _signInManager;

    public AuthController(SignInManager<UserIdentity> signInManager) {
        _signInManager = signInManager;
    }

    public IActionResult Login() {
        if (User.Identity.IsAuthenticated)
            return RedirectToAction("Dashboard", "App");

        return View();
    }

    [HttpPost]
    public async Task<ActionResult> Login(LoginViewModel vm, string returnUrl) {
        if (ModelState.IsValid) {
            var signInResult = await _signInManager.PasswordSignInAsync(vm.Username, vm.Password, true, false);
            if (signInResult.Succeeded) {
                if (String.IsNullOrWhiteSpace(returnUrl))
                    return RedirectToAction("Dashboard", "App");
                else return RedirectToAction(returnUrl);
            } else {
                ModelState.AddModelError("", "Username or password is incorrect.");
            }
        }   

        return View();
    }

    public async Task<IActionResult> Logout() {
        if (User.Identity.IsAuthenticated) {
            await _signInManager.SignOutAsync();
        }

        return RedirectToAction("Index", "App");
    }
}

Looking at other posts, it sounds like I need to add an IdentityExtension in order to access the claim as User.Identity.GetAccountId() and generate a custom user identity as in this answer: How to extend available properties of User.Identity but obviously this is done in an older version and many of the method calls are not applicable anymore.

Thanks in advance for any answers or guidance.

1
2
5/23/2017 12:31:59 PM

Popular Answer

if you have added a claim for AccountId you can then easily write an extension method to get it:

public static string GetAccountId(this ClaimsPrincipal principal)
{
    if (principal == null)
    {
        throw new ArgumentNullException(nameof(principal));
    }
    var claim = principal.FindFirst("AccountId");
    return claim != null ? claim.Value : null;
}

if you need help on how to add a custom claim see this question

0
5/23/2017 12:00:10 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow