简体   繁体   中英

Problems extending properties from Identity (ASP.NET Core)

I'm having trouble extending properties from Identity.

The whole reason for this is to have my employee database integrated with the application database (which includes the identity stuff) and use it as one big database.

I tried following this answer , but seems like they are using another version of ASP.NET. I'm using ASP.NET Core, Version: 2.0.3

Here is the code for my ApplicationUser.cs file

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;

namespace src.Models
{
    public class ApplicationUser : IdentityUser
    {

        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) {

            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);

            userIdentity.AddClaim(new Claim("FirstName", this.FirstName.ToString()));
            userIdentity.AddClaim(new Claim("LastName", this.LastName.ToString()));
            userIdentity.AddClaim(new Claim("JobTitle", this.JobTitle.ToString()));
            userIdentity.AddClaim(new Claim("Status", this.Status.ToString()));

            return userIdentity;
        }

        string FirstName { get; set; }
        string LastName { get; set; }
        string JobTitle { get; set; }
        string Status { get; set; }
        int Age { get; set; }
    }
}

I'm getting an error on CreateIdentityAsync , with the error:

'UserManager<ApplicationUser>' does not contain a definition for 'CreateIdentityAsync' 
and no extension method 'CreateIdentityAsync' accepting a first argument of type 
'UserManager<ApplicationUser>' could be found (are you missing a using directive 
or an assembly reference?) [src]

and an error on DefaultAuthenticationTypes , the error:

The name 'DefaultAuthenticationTypes' does not exist in the current context [src]

Is this not possible with ASP.NET Core, or that I'm doing something wrong?

I figured it out myself. What I was trying to do was not possible with ASP.NET Core. I had to do something else.

I created a AppClaimsPrincipalFactory.cs file

public class AppClaimsPrincipalFactory : UserClaimsPrincipalFactory<ApplicationUser, IdentityRole>
{
    public AppClaimsPrincipalFactory(
        UserManager<ApplicationUser> userManager
        , RoleManager<IdentityRole> roleManager
        , IOptions<IdentityOptions> optionsAccessor)
    : base(userManager, roleManager, optionsAccessor)
    { }

    public async override Task<ClaimsPrincipal> CreateAsync(ApplicationUser user)
    {
        var principal = await base.CreateAsync(user);

        if (!string.IsNullOrWhiteSpace(user.FirstName))
        {
        ((ClaimsIdentity)principal.Identity).AddClaims(new[] {
        new Claim(ClaimTypes.GivenName, user.FirstName)
    });
        }

        if (!string.IsNullOrWhiteSpace(user.LastName))
        {
            ((ClaimsIdentity)principal.Identity).AddClaims(new[] {
         new Claim(ClaimTypes.Surname, user.LastName),
    });
        }

        return principal;
    }
}

Added this line to my Startup.cs file

services.AddScoped<Microsoft.AspNetCore.Identity.IUserClaimsPrincipalFactory<ApplicationUser>, AppClaimsPrincipalFactory>();

adding to @remi the original solution is here https://adrientorris.github.io/aspnet-core/identity/extend-user-model.html

public class ApplicationUser : IdentityUser {
    public string FirstName { get; set; }

    public string LastName { get; set; }
}

Create a principale factory

public class AppClaimsPrincipalFactory : UserClaimsPrincipalFactory<ApplicationUser, IdentityRole> {
public AppClaimsPrincipalFactory(
    UserManager<ApplicationUser> userManager
    , RoleManager<IdentityRole> roleManager
    , IOptions<IdentityOptions> optionsAccessor)
: base(userManager, roleManager, optionsAccessor)
{ }

public async override Task<ClaimsPrincipal> CreateAsync(ApplicationUser user)
{
    var principal = await base.CreateAsync(user);

    if (!string.IsNullOrWhiteSpace(user.FirstName))
    {
        ((ClaimsIdentity)principal.Identity).AddClaims(new[] {
    new Claim(ClaimTypes.GivenName, user.FirstName)
});
    }

    if (!string.IsNullOrWhiteSpace(user.LastName))
    {
        ((ClaimsIdentity)principal.Identity).AddClaims(new[] {
     new Claim(ClaimTypes.Surname, user.LastName),
});
    }

    return principal;
}

}

Add in startup class

public void ConfigureServices(IServiceCollection services)
{
    // [...]

    services.AddDbContext<SecurityDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("Security")));

    services.AddIdentity<ApplicationUser, IdentityRole>()
        .AddEntityFrameworkStores<SecurityDbContext>()
        .AddDefaultTokenProviders();

    services.AddScoped<Microsoft.AspNetCore.Identity.IUserClaimsPrincipalFactory<ApplicationUser>, AppClaimsPrincipalFactory>();

    // [...]
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM