12

Visual Studio 2015 scaffolding uses UserManager<TUser> which cannot be used to create ClaimsIdentity. Does anyone have a working example on how to do this?

The VS2015 scaffolding throws errors:

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
    return userIdentity;
}

N.B.: I have added properties to ApplicationUser which do not conflict with IdentyUser.

Tseng
  • 61,549
  • 15
  • 193
  • 205
Ungaro
  • 522
  • 6
  • 15
  • What error does the scaffolding throw and where? The method you posted shows that it is returning a `ClaimsIdentity` – Nkosi Apr 10 '16 at 11:27
  • UserManager does not contain a definition for CreateIdentityAsync or DefaultAuthenticationTypes – Ungaro Apr 10 '16 at 17:38
  • To reproduce: VS2015 create a new ASP.NET web project with the MVC 6 template. Under Models in ApplicationUser.cs, add references to System.Security.Claims and Micosoft.AspNet.Identity and insert the code above into the ApplicationUser class. See the errors described in the comment above. – Ungaro Apr 10 '16 at 17:48
  • What you are describing will work in mvc 5 not mvc 6/core. checking now to see how it has changed in the new version – Nkosi Apr 10 '16 at 17:50
  • 1
    Please use the proper tags in future! When your quesiton is related to ASP.NET Core use "asp.net-core" tag ! NOT "asp.net" and "core", both are completely unrelated to your question. Please read the tag descriptions before adding them – Tseng Jun 05 '16 at 10:41

2 Answers2

16

UserManager has changed in the MVC6 version. You will need to modify your code...

public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) {
    var authenticationType = "Put authentication type Here";
    var userIdentity = new ClaimsIdentity(await manager.GetClaimsAsync(this), authenticationType);

    // Add custom user claims here
    return userIdentity;
}
Nkosi
  • 235,767
  • 35
  • 427
  • 472
  • 3
    AuthenticationType: https://msdn.microsoft.com/en-us/library/system.security.claims.authenticationtypes(v=vs.110).aspx – Ungaro Apr 11 '16 at 04:43
  • I was learning how to add DAL/DTO classes to a new project based on ASPNETCORE from the public demo project Altostratus and noticed they have two of these async methods, one takes only `UserManager manager` and the other takes `UserManager manager, string authenticationType` are they both needed? As I see in yours you just hard code the type message. – Edward Feb 12 '17 at 19:59
  • That depends on your needs. If there is no need for multiple types and it is unlikely to change then no. Otherwise do what works for your code. – Nkosi Feb 12 '17 at 20:02
  • If I have a MS SQL database that has user authentication setup already, do I put anything there or shouldn't it just be generic from the project template on aspnetcore EF? Tables being aspnetroles, aspnetuserclaims, aspnetuserlogins, aspnetroles, and aspnetusers. – Edward Feb 12 '17 at 20:06
  • Then use the default templates provided when you created the project. There are examples already available for when using multiple authentication providers. – Nkosi Feb 12 '17 at 20:12
  • This answer was based on the original question asked. If the default template using another format go with that. – Nkosi Feb 12 '17 at 20:13
2

.net core

the answer has changed, per here and here, both authors state the use UserClaimsPrincipalFactory<ApplicationUser> which is the default implementation for core 2.2. The first article says that the method you are looking for has moved. However, as stated you must register your implementation of UserClaimsPrincipalFactory in services like so and a sample class implementation is below. Please take that we have to register MyUserClaimsPrincipalFactory so our service collection knows where to find it. Which means in the constructor of SignInManager<ApplicationUser> it is also referring to IUserClaimsPrincipalFactory<ApplicationUser> but service will resolve it:

services
.AddIdentity<ApplicationUser, ApplicationRole>()              
.AddClaimsPrincipalFactory<MyUserClaimsPrincipalFactory>() // <======== HERE

services.AddScoped<IUserClaimsPrincipalFactory<ApplicationUser>, MyUserClaimsPrincipalFactory>();

And here is is the class below:

public class MyUserClaimsPrincipalFactory : UserClaimsPrincipalFactory<ApplicationUser>
{
    public MyUserClaimsPrincipalFactory(UserManager<ApplicationUser> userManager, 
        IOptions<IdentityOptions> optionsAccessor)
        : base(userManager, optionsAccessor)
    {
    }

    protected override async Task<ClaimsIdentity> GenerateClaimsAsync(ApplicationUser user)
    {
        var identity = await base.GenerateClaimsAsync(user);
        identity.AddClaim(new Claim("ContactName", "John Smith"));
        return identity;
    }
}
petrosmm
  • 528
  • 9
  • 23