Search code examples
c#asp.netasp.net-identity-2

Security.Principal.IIdentity extension method for getting user email


Inside my project ASP I'm using ASP.NET Identity 2.2.1. In many places I must get current (logged-in) user email. Right now I'm finding that user using this:

var user = await UserManager.FindByIdAsync(User.Identity.GetUserId<int>());
var email = user.Email;

I've noticed that GetUserId<T> is an extension method that can be found inside IdentityExtensions class inside Microsoft.AspNet.Identity

I've created my own extension method that simplifies getting email by allowing to get it as:

var email = User.Identity.GetUserEmail()

Below is my extension:

public static class MyIIdentityExtensions
{
    public static string GetUserEmail(this IIdentity identity)
    {
        if (identity == null)
        {
            throw new ArgumentNullException("identity");
        }
        var ci = identity as ClaimsIdentity;
        if (ci == null) return null;
        var um = HttpContext.Current.GetOwinContext().GetUserManager<UserManager>();
        if (um == null) return null;
        var user = um.FindById(ci.GetUserId<int>());
        if (user == null) return null;
        return user.Email;
    }
}

But it is much more complicated than build-in extension methods

Can I simplify this? Maybe there is build in method for doing this? What I want is simple way to get Email for current logged in user from User.Identity.


Solution

  • If you use UserManager, you hit the database each time you call GetUserEmail method.

    Instead you can add the email as Claim. Inside ApplicationUser class there is GenerateUserIdentityAsync method

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
         // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
         var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
         // Add custom user claims here
         userIdentity.AddClaim(new Claim(ClaimTypes.Email, this.Email));
         return userIdentity;
    }
    

    Then your extension method to get it

    public static class IdentityExtensions
    {
        public static string GetUserEmail(this IIdentity identity)
        {
            if (identity == null)
            {
                throw new ArgumentNullException("identity");
            }
            var ci = identity as ClaimsIdentity;
            if (ci != null)
            {
                return ci.FindFirstValue(ClaimTypes.Email);
            }
            return null;
        }
    }