Answered by:
Create User & Role: ApplicationUser doesn't inherit from or implement the contraints type 'IdentityUser'

Question
-
User-1352156089 posted
Hi All,
I am trying to implement role based authentication with asp.net identity and went through many sites and tutorials and I think I am almost there but something is missing as per below.
FYI, I changed my Identity code so that all primary keys are of Integer type instead of String.
With that said, following some tutorials and examples (i.e. https://code.msdn.microsoft.com/ASPNET-MVC-5-Security-And-44cbdb97), I have added in my Startup.vb class the following code in order to create an admin and a user roles:
Imports Microsoft.AspNet.Identity Imports Microsoft.AspNet.Identity.EntityFramework Imports Microsoft.Owin Imports Owin Imports System.Security.Claims <Assembly: OwinStartupAttribute(GetType(Startup))> Partial Public Class Startup Public Sub Configuration(app As IAppBuilder) ConfigureAuth(app) CreateRolesandUsers() End Sub ' https://code.msdn.microsoft.com/ASPNET-MVC-5-Security-And-44cbdb97 Private Sub CreateRolesandUsers() Dim context As ApplicationDbContext = New ApplicationDbContext() Dim roleManager = New RoleManager(Of IdentityRole)(New RoleStore(Of IdentityRole)(context)) Dim UserManager = New UserManager(Of ApplicationUser, Integer)(New UserStore(Of ApplicationUser)(context)) If Not roleManager.RoleExists("Admin") Then Dim role = New Microsoft.AspNet.Identity.EntityFramework.IdentityRole() role.Name = "Admin" roleManager.Create(role) Dim user = New ApplicationUser() user.UserName = "MyAdmin" user.Email = "myemail@gmail.com" Dim userPWD As String = "Testing@DRFFG" Dim chkUser = UserManager.Create(user, userPWD) If chkUser.Succeeded Then Dim result1 = UserManager.AddToRole(user.Id, "Admin") End If End If If Not roleManager.RoleExists("User") Then Dim role = New Microsoft.AspNet.Identity.EntityFramework.IdentityRole() role.Name = "User" roleManager.Create(role) End If End Sub End Class
In red, I have highlighted where the error is fired: Create User & Role: ApplicationUser doesn't inherit from or implement the contraints type 'IdentityUser'
Any idea about what could possibly be wrong?
Thanks
Saturday, March 23, 2019 5:34 PM
Answers
-
User-1352156089 posted
Hi Ackerly,
thanks for your feedback.
This has been solved. I ll share the code for future reference since there is really scattered documentation about how to implement quickly role management with WebForms.
In IdentityModels.vb I had to modify the code to take Integer as primary key:
Imports System Imports System.Threading.Tasks Imports System.Security.Claims Imports Microsoft.AspNet.Identity Imports Microsoft.AspNet.Identity.EntityFramework Imports Microsoft.AspNet.Identity.Owin Imports Microsoft.Owin.Security Imports Microsoft.Owin Public Class ApplicationUser Inherits IdentityUser(Of Integer, CustomUserLogin, CustomUserRole, CustomUserClaim) Public Async Function GenerateUserIdentityAsync(ByVal manager As UserManager(Of ApplicationUser, Integer)) As Task(Of ClaimsIdentity) Dim userIdentity = Await manager.CreateIdentityAsync(Me, DefaultAuthenticationTypes.ApplicationCookie) Return userIdentity End Function End Class Public Class ApplicationDbContext Inherits IdentityDbContext(Of ApplicationUser, CustomRole, Integer, CustomUserLogin, CustomUserRole, CustomUserClaim) Public Sub New() MyBase.New("MyConnectionString") End Sub Public Shared Function Create() As ApplicationDbContext Return New ApplicationDbContext() End Function End Class Public Class ApplicationRoleManager Inherits RoleManager(Of CustomRole, Integer) Public Sub New(ByVal CustomRoleStore As IRoleStore(Of CustomRole, Integer)) MyBase.New(CustomRoleStore) End Sub Public Shared Function Create(ByVal options As IdentityFactoryOptions(Of ApplicationRoleManager), ByVal context As IOwinContext) As ApplicationRoleManager Return New ApplicationRoleManager(New RoleStore(Of CustomRole, Integer, CustomUserRole)(context.[Get](Of ApplicationDbContext)())) End Function End Class Public Class CustomUserStore Inherits UserStore(Of ApplicationUser, CustomRole, Integer, CustomUserLogin, CustomUserRole, CustomUserClaim) Implements IUserStore(Of ApplicationUser, Integer), IDisposable Public Sub New() Me.New(New ApplicationDbContext()) MyBase.DisposeContext = True End Sub Public Sub New(ByVal context As ApplicationDbContext) MyBase.New(context) End Sub End Class Public Class CustomRoleStore Inherits RoleStore(Of CustomRole, Integer, CustomUserRole) Implements IQueryableRoleStore(Of CustomRole, Integer), IRoleStore(Of CustomRole, Integer), IDisposable Public Sub New() Me.New(New ApplicationDbContext()) MyBase.DisposeContext = True End Sub Public Sub New(ByVal context As ApplicationDbContext) MyBase.New(context) End Sub End Class Public Class CustomUserRole Inherits IdentityUserRole(Of Integer) End Class Public Class CustomUserClaim Inherits IdentityUserClaim(Of Integer) End Class Public Class CustomUserLogin Inherits IdentityUserLogin(Of Integer) End Class Public Class CustomRole Inherits IdentityRole(Of Integer, CustomUserRole) Public Sub New() End Sub Public Sub New(ByVal Name As String) Name = Name End Sub End Class
In Startup.Auth.vb I added:
app.CreatePerOwinContext(Of ApplicationRoleManager)(AddressOf ApplicationRoleManager.Create)
In IdentityConfig.vb I changed the code as follows:
Imports System.Security.Claims Imports System.Threading.Tasks Imports Microsoft.AspNet.Identity Imports Microsoft.AspNet.Identity.EntityFramework Imports Microsoft.AspNet.Identity.Owin Imports Microsoft.Owin Imports Microsoft.Owin.Security Public Class EmailService Implements IIdentityMessageService Public Function SendAsync(message As IdentityMessage) As Task Implements IIdentityMessageService.SendAsync ' Plug in your email service here to send an email. Return Task.FromResult(0) End Function End Class Public Class SmsService Implements IIdentityMessageService Public Function SendAsync(message As IdentityMessage) As Task Implements IIdentityMessageService.SendAsync ' Plug in your SMS service here to send a text message. Return Task.FromResult(0) End Function End Class ' Configure the application user manager used in this application. UserManager is defined in ASP.NET Identity and is used by the application. Public Class ApplicationUserManager Inherits UserManager(Of ApplicationUser, Integer) Public Sub New(ByVal store As IUserStore(Of ApplicationUser, Integer)) MyBase.New(store) End Sub Public Shared Function Create(ByVal options As IdentityFactoryOptions(Of ApplicationUserManager), ByVal context As IOwinContext) As ApplicationUserManager Dim manager = New ApplicationUserManager(New CustomUserStore(context.[Get](Of ApplicationDbContext)())) manager.UserValidator = New UserValidator(Of ApplicationUser, Integer)(manager) With { .AllowOnlyAlphanumericUserNames = False, .RequireUniqueEmail = False } manager.PasswordValidator = New PasswordValidator With { .RequiredLength = 6, .RequireNonLetterOrDigit = True, .RequireDigit = True, .RequireLowercase = True, .RequireUppercase = True } manager.RegisterTwoFactorProvider("PhoneCode", New PhoneNumberTokenProvider(Of ApplicationUser, Integer) With { .MessageFormat = "Your security code is: {0}" }) manager.RegisterTwoFactorProvider("EmailCode", New EmailTokenProvider(Of ApplicationUser, Integer) With { .Subject = "Security Code", .BodyFormat = "Your security code is: {0}" }) manager.EmailService = New EmailService() manager.SmsService = New SmsService() Dim dataProtectionProvider = options.DataProtectionProvider If dataProtectionProvider IsNot Nothing Then manager.UserTokenProvider = New DataProtectorTokenProvider(Of ApplicationUser, Integer)(dataProtectionProvider.Create("ASP.NET Identity")) End If Return manager End Function End Class Public Class ApplicationSignInManager Inherits SignInManager(Of ApplicationUser, Integer) Public Sub New(userManager As ApplicationUserManager, authenticationManager As IAuthenticationManager) MyBase.New(userManager, authenticationManager) End Sub Public Overrides Function CreateUserIdentityAsync(user As ApplicationUser) As Task(Of ClaimsIdentity) Return user.GenerateUserIdentityAsync(DirectCast(UserManager, ApplicationUserManager)) End Function Public Shared Function Create(options As IdentityFactoryOptions(Of ApplicationSignInManager), context As IOwinContext) As ApplicationSignInManager Return New ApplicationSignInManager(context.GetUserManager(Of ApplicationUserManager)(), context.Authentication) End Function End Class
In Startup.vb I changed the code as follows:
Imports Microsoft.AspNet.Identity Imports Microsoft.AspNet.Identity.EntityFramework Imports Microsoft.Owin Imports Owin Imports System.Security.Claims <Assembly: OwinStartupAttribute(GetType(Startup))> Partial Public Class Startup Public Sub Configuration(app As IAppBuilder) ConfigureAuth(app) CreateRolesandUsers() End Sub Private Sub CreateRolesandUsers() Dim context As ApplicationDbContext = New ApplicationDbContext() Dim roleManager = New RoleManager(Of CustomRole, Integer)(New RoleStore(Of CustomRole, Integer, CustomUserRole)(context)) Dim UserManager = New UserManager(Of ApplicationUser, Integer)(New UserStore(Of ApplicationUser, CustomRole, Integer, CustomUserLogin, CustomUserRole, CustomUserClaim)(context)) If Not roleManager.RoleExists("Administrator") Then Dim role = New CustomRole() role.Name = "Administrator" roleManager.Create(role) Dim user = New ApplicationUser() user.UserName = "xxxxx" user.Email = "xxxxxxxxxx@xxxxx.com" Dim userPWD As String = "Testing@DRFFG" Dim chkUser = UserManager.Create(user, userPWD) If chkUser.Succeeded Then Dim result1 = UserManager.AddToRole(user.Id, "Administrator") End If End If If Not roleManager.RoleExists("User") Then Dim role = New CustomRole() role.Name = "User" roleManager.Create(role) End If End Sub End Class
Thanks
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Friday, March 29, 2019 9:18 AM
All replies
-
User-893317190 posted
Hi Claudio7810,
As the error shows , you should make your ApplicationUser inherit from IdentityUser.
In your sample , the author defines ApplicationUser as follows in C#\shanuMVCUserRoles\Models, please have a refer.
namespace shanuMVCUserRoles.Models { // You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more. public class ApplicationUser : IdentityUser { 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; } } public class ApplicationDbContext : IdentityDbContext<ApplicationUser> { public ApplicationDbContext() : base("DefaultConnection", throwIfV1Schema: false) { } public static ApplicationDbContext Create() { return new ApplicationDbContext(); } } }
Best regards,
Ackerly Xu
Monday, March 25, 2019 2:17 AM -
User-1352156089 posted
Hi Ackerly,
thank you but the error still persists.
Thisa what I have in my Models\IdendityModels.vb file:
Public Class ApplicationUser Inherits IdentityUser(Of Integer, CustomUserLogin, CustomUserRole, CustomUserClaim) Public Async Function GenerateUserIdentityAsync(ByVal manager As UserManager(Of ApplicationUser, Integer)) As Task(Of ClaimsIdentity) Dim userIdentity = Await manager.CreateIdentityAsync(Me, DefaultAuthenticationTypes.ApplicationCookie) Return userIdentity End Function End Class Public Class ApplicationDbContext Inherits IdentityDbContext(Of ApplicationUser, CustomRole, Integer, CustomUserLogin, CustomUserRole, CustomUserClaim) Public Sub New() MyBase.New("MyConnectionString") End Sub Public Shared Function Create() As ApplicationDbContext Return New ApplicationDbContext() End Function End Class
Also my ApplicationUser inherits from IdentityUser and this is why I cannot figure out what is wrong with that.
Thanks a lot
Monday, March 25, 2019 7:04 PM -
User475983607 posted
Also my ApplicationUser inherits from IdentityUser and this is why I cannot figure out what is wrong with that.You've extended Identity stores as well as changing the key to an Id.
Monday, March 25, 2019 7:54 PM -
User-1352156089 posted
Yes and in your opinion this means that my ApplicationUser cannot inherit from the extended identity store considering that I ve also changed the key to Id?Monday, March 25, 2019 8:32 PM -
User475983607 posted
Yes and in your opinion this means that my ApplicationUser cannot inherit from the extended identity store considering that I ve also changed the key to Id?I'm not sure what you're asking.
You've extended several Identity data stores and I assume did not implement the Interfaces.
The error message is explained at the following link.
https://docs.microsoft.com/en-us/dotnet/visual-basic/misc/bc32044
Monday, March 25, 2019 9:55 PM -
User-893317190 posted
Hi Claudio7810,
If you open definition of IdentityUser(Of Integer, CustomUserLogin, CustomUserRole, CustomUserClaim) , you could find code like
Public Class IdentityUser(Of TKey, TLogin As IdentityUserLogin(Of TKey), TRole As IdentityUserRole(Of TKey), TClaim As IdentityUserClaim(Of TKey)) Inherits IUser(Of TKey) End Class
Generic IdentityUser doesn't inherit from IdentityUser , which means it is not of type IdentityUser, please try to change your IdentityUser(Of Integer, CustomUserLogin, CustomUserRole, CustomUserClaim) to IdentityUser without (Of Integer, CustomUserLogin, CustomUserRole, CustomUserClaim).
Best regards,
Ackerly Xu
Tuesday, March 26, 2019 1:11 AM -
User-1352156089 posted
Hi Akerly,
thanks a lot.
One question: if I remove the (of Integer, etc etc) the logic doesn't work because I changed the Identity key to Integer instead of String.
Maybe what I ll need to do is to create a CreateRoleManager class on its own.
What do you think?
Tuesday, March 26, 2019 10:35 AM -
User-893317190 posted
Hi Claudio7810,
It is not easy to change IdentityUser's primary key to integer.
You should not only customize IdentityUser but also customize IdentityUserLogin, IdentityUserRole, IdentityUserClaim to use int as primary key and so on.
For the whole guide , please refer to https://docs.microsoft.com/en-us/aspnet/identity/overview/extensibility/change-primary-key-for-users-in-aspnet-identity
Best regards,
Ackerly Xu
Wednesday, March 27, 2019 1:21 AM -
User-1352156089 posted
Hi Ackerly,
thanks for your feedback.
This has been solved. I ll share the code for future reference since there is really scattered documentation about how to implement quickly role management with WebForms.
In IdentityModels.vb I had to modify the code to take Integer as primary key:
Imports System Imports System.Threading.Tasks Imports System.Security.Claims Imports Microsoft.AspNet.Identity Imports Microsoft.AspNet.Identity.EntityFramework Imports Microsoft.AspNet.Identity.Owin Imports Microsoft.Owin.Security Imports Microsoft.Owin Public Class ApplicationUser Inherits IdentityUser(Of Integer, CustomUserLogin, CustomUserRole, CustomUserClaim) Public Async Function GenerateUserIdentityAsync(ByVal manager As UserManager(Of ApplicationUser, Integer)) As Task(Of ClaimsIdentity) Dim userIdentity = Await manager.CreateIdentityAsync(Me, DefaultAuthenticationTypes.ApplicationCookie) Return userIdentity End Function End Class Public Class ApplicationDbContext Inherits IdentityDbContext(Of ApplicationUser, CustomRole, Integer, CustomUserLogin, CustomUserRole, CustomUserClaim) Public Sub New() MyBase.New("MyConnectionString") End Sub Public Shared Function Create() As ApplicationDbContext Return New ApplicationDbContext() End Function End Class Public Class ApplicationRoleManager Inherits RoleManager(Of CustomRole, Integer) Public Sub New(ByVal CustomRoleStore As IRoleStore(Of CustomRole, Integer)) MyBase.New(CustomRoleStore) End Sub Public Shared Function Create(ByVal options As IdentityFactoryOptions(Of ApplicationRoleManager), ByVal context As IOwinContext) As ApplicationRoleManager Return New ApplicationRoleManager(New RoleStore(Of CustomRole, Integer, CustomUserRole)(context.[Get](Of ApplicationDbContext)())) End Function End Class Public Class CustomUserStore Inherits UserStore(Of ApplicationUser, CustomRole, Integer, CustomUserLogin, CustomUserRole, CustomUserClaim) Implements IUserStore(Of ApplicationUser, Integer), IDisposable Public Sub New() Me.New(New ApplicationDbContext()) MyBase.DisposeContext = True End Sub Public Sub New(ByVal context As ApplicationDbContext) MyBase.New(context) End Sub End Class Public Class CustomRoleStore Inherits RoleStore(Of CustomRole, Integer, CustomUserRole) Implements IQueryableRoleStore(Of CustomRole, Integer), IRoleStore(Of CustomRole, Integer), IDisposable Public Sub New() Me.New(New ApplicationDbContext()) MyBase.DisposeContext = True End Sub Public Sub New(ByVal context As ApplicationDbContext) MyBase.New(context) End Sub End Class Public Class CustomUserRole Inherits IdentityUserRole(Of Integer) End Class Public Class CustomUserClaim Inherits IdentityUserClaim(Of Integer) End Class Public Class CustomUserLogin Inherits IdentityUserLogin(Of Integer) End Class Public Class CustomRole Inherits IdentityRole(Of Integer, CustomUserRole) Public Sub New() End Sub Public Sub New(ByVal Name As String) Name = Name End Sub End Class
In Startup.Auth.vb I added:
app.CreatePerOwinContext(Of ApplicationRoleManager)(AddressOf ApplicationRoleManager.Create)
In IdentityConfig.vb I changed the code as follows:
Imports System.Security.Claims Imports System.Threading.Tasks Imports Microsoft.AspNet.Identity Imports Microsoft.AspNet.Identity.EntityFramework Imports Microsoft.AspNet.Identity.Owin Imports Microsoft.Owin Imports Microsoft.Owin.Security Public Class EmailService Implements IIdentityMessageService Public Function SendAsync(message As IdentityMessage) As Task Implements IIdentityMessageService.SendAsync ' Plug in your email service here to send an email. Return Task.FromResult(0) End Function End Class Public Class SmsService Implements IIdentityMessageService Public Function SendAsync(message As IdentityMessage) As Task Implements IIdentityMessageService.SendAsync ' Plug in your SMS service here to send a text message. Return Task.FromResult(0) End Function End Class ' Configure the application user manager used in this application. UserManager is defined in ASP.NET Identity and is used by the application. Public Class ApplicationUserManager Inherits UserManager(Of ApplicationUser, Integer) Public Sub New(ByVal store As IUserStore(Of ApplicationUser, Integer)) MyBase.New(store) End Sub Public Shared Function Create(ByVal options As IdentityFactoryOptions(Of ApplicationUserManager), ByVal context As IOwinContext) As ApplicationUserManager Dim manager = New ApplicationUserManager(New CustomUserStore(context.[Get](Of ApplicationDbContext)())) manager.UserValidator = New UserValidator(Of ApplicationUser, Integer)(manager) With { .AllowOnlyAlphanumericUserNames = False, .RequireUniqueEmail = False } manager.PasswordValidator = New PasswordValidator With { .RequiredLength = 6, .RequireNonLetterOrDigit = True, .RequireDigit = True, .RequireLowercase = True, .RequireUppercase = True } manager.RegisterTwoFactorProvider("PhoneCode", New PhoneNumberTokenProvider(Of ApplicationUser, Integer) With { .MessageFormat = "Your security code is: {0}" }) manager.RegisterTwoFactorProvider("EmailCode", New EmailTokenProvider(Of ApplicationUser, Integer) With { .Subject = "Security Code", .BodyFormat = "Your security code is: {0}" }) manager.EmailService = New EmailService() manager.SmsService = New SmsService() Dim dataProtectionProvider = options.DataProtectionProvider If dataProtectionProvider IsNot Nothing Then manager.UserTokenProvider = New DataProtectorTokenProvider(Of ApplicationUser, Integer)(dataProtectionProvider.Create("ASP.NET Identity")) End If Return manager End Function End Class Public Class ApplicationSignInManager Inherits SignInManager(Of ApplicationUser, Integer) Public Sub New(userManager As ApplicationUserManager, authenticationManager As IAuthenticationManager) MyBase.New(userManager, authenticationManager) End Sub Public Overrides Function CreateUserIdentityAsync(user As ApplicationUser) As Task(Of ClaimsIdentity) Return user.GenerateUserIdentityAsync(DirectCast(UserManager, ApplicationUserManager)) End Function Public Shared Function Create(options As IdentityFactoryOptions(Of ApplicationSignInManager), context As IOwinContext) As ApplicationSignInManager Return New ApplicationSignInManager(context.GetUserManager(Of ApplicationUserManager)(), context.Authentication) End Function End Class
In Startup.vb I changed the code as follows:
Imports Microsoft.AspNet.Identity Imports Microsoft.AspNet.Identity.EntityFramework Imports Microsoft.Owin Imports Owin Imports System.Security.Claims <Assembly: OwinStartupAttribute(GetType(Startup))> Partial Public Class Startup Public Sub Configuration(app As IAppBuilder) ConfigureAuth(app) CreateRolesandUsers() End Sub Private Sub CreateRolesandUsers() Dim context As ApplicationDbContext = New ApplicationDbContext() Dim roleManager = New RoleManager(Of CustomRole, Integer)(New RoleStore(Of CustomRole, Integer, CustomUserRole)(context)) Dim UserManager = New UserManager(Of ApplicationUser, Integer)(New UserStore(Of ApplicationUser, CustomRole, Integer, CustomUserLogin, CustomUserRole, CustomUserClaim)(context)) If Not roleManager.RoleExists("Administrator") Then Dim role = New CustomRole() role.Name = "Administrator" roleManager.Create(role) Dim user = New ApplicationUser() user.UserName = "xxxxx" user.Email = "xxxxxxxxxx@xxxxx.com" Dim userPWD As String = "Testing@DRFFG" Dim chkUser = UserManager.Create(user, userPWD) If chkUser.Succeeded Then Dim result1 = UserManager.AddToRole(user.Id, "Administrator") End If End If If Not roleManager.RoleExists("User") Then Dim role = New CustomRole() role.Name = "User" roleManager.Create(role) End If End Sub End Class
Thanks
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Friday, March 29, 2019 9:18 AM