Enter additional data, from the bank, into the User's Claims. What is the best time or the right way to do it?

3

I have some extra information that I need to add to user claims that are from other tables and classes.

Given the method generated by the ASP.NET MVC template with Identity in class ApplicationUser :

public class ApplicationUser : IdentityUser
{       
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(
        UserManager<ApplicationUser> manager)
    {
        var userIdentity = await manager.CreateIdentityAsync(
            this, DefaultAuthenticationTypes.ApplicationCookie);            

        userIdentity.AddClaim(new Claim(ClaimsKey.ClaimA, "ClaimA"));
        userIdentity.AddClaim(new Claim(ClaimsKey.ClaimB, "ClaimB"));
        userIdentity.AddClaim(new Claim(ClaimsKey.ClaimC, "ClaimC"));

        return userIdentity;
    }
}

This does not have an EF Context available, and also, this method is generated at times when there is no context yet created in request , as in:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    LoginPath = new PathString("/Account/Login"),
    Provider = new CookieAuthenticationProvider
    {
        OnValidateIdentity = SecurityStampValidator
            .OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                TimeSpan.FromMinutes(30), 
                // aqui, principalmente ao efetuar login.
                // tentei obter o contexto de 
                // HttpContext.Current.GetOwinContext...
                // e obtive um erro por conta de HttpContext.Current 
                // que ainda estava null
                (manager, user) => user.GenerateUserIdentityAsync(manager)) 
    }
});

In% with%, from CreateUserIdentityAsync you can even have, taking into account the moment, which is usually requested after user login:

public override Task<ClaimsIdentity> CreateUserIdentityAsync(Usuario user)
{
    return user.GenerateUserIdentityAsync((AppUserManager)UserManager);
}

Taking these issues into consideration, what is the best time or a good way to add extra data to context-loaded claims?

    
asked by anonymous 10.09.2015 / 02:25

1 answer

2

When creating or editing the user. Claims are pieces of information that uniquely identify a user. A great example is in this answer , which I will format for you.

Note that GenerateUserIdentityAsync does not necessarily update information in persistence. The method only mounts the object with Claims passed by you. I actually think this is a bad example, because everything that is added as Claim in this example is lost when the user's Cookie expires.

A more interesting way would be to use the AddOrUpdateClaim extension method:

As follows:

    public ActionResult AtualizarUsuarioCorrente()
    {
        User.AddOrUpdateClaim("CPF", "123.456.789-01");
        User.AddOrUpdateClaim("RG", "321.654-85");
        User.AddOrUpdateClaim("CNH", "7132654978");
    }

Extension methods are:

    namespace SeuProjeto.Extensions
    {
        public static class ClaimsExtensions
        {
            public static void AddOrUpdateClaim(this IPrincipal principalDoUsuario, string chave, string valor)
            {
                var identity = principalDoUsuario.Identity as ClaimsIdentity;
                if (identity == null)
                    return;

                // Se a Claim já existe, remove. 
                // Claims não são "atualizáveis". É preciso remover uma
                // Claim antiga para inserir uma nova com o mesmo nome.
                var claimExistente = identity.FindFirst(key);
                if (claimExistente != null)
                    identity.RemoveClaim(claimExistente);

                // Aqui adicionamos uma Claim em banco.
                identity.AddClaim(new Claim(key, value));
                var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
                authenticationManager.AuthenticationResponseGrant = new AuthenticationResponseGrant(new ClaimsPrincipal(identity), new AuthenticationProperties() { IsPersistent = true });
            }

            public static string GetClaimValue(this IPrincipal principalDoUsuario, string chave)
            {
                var identity = principalDoUsuario.Identity as ClaimsIdentity;
                if (identity == null)
                    return null;

                var claim = identity.Claims.First(c => c.Type == chave);
                return claim.Value;
            }
        }
    }

After updating the user, Claims can be obtained as follows:

var identity = (ClaimsIdentity)User.Identity;
IEnumerable<Claim> claims = identity.Claims;
    
23.06.2016 / 21:07