This project has moved and is read-only. For the latest updates, please go here.
2
Vote

Unable to implement RoleManager

description

I am using the AzureTable identity library for user logins and want to add Roles to my application.

I added a class ApplicationRole to IndentityModel.cs and the line
app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
to the ConfigureAuth method of Startup.

Then I added ApplicationRoleManager as follows:
    public class ApplicationRoleManager : RoleManager<ApplicationRole>
    {
        public ApplicationRoleManager(IRoleStore<ApplicationRole, string> roleStore)
            : base(roleStore)
        {
        }

        public static ApplicationRoleManager Create(IdentityFactoryOptions<ApplicationRoleManager> options, IOwinContext context)
        {
            return new ApplicationRoleManager(new RoleStore<ApplicationRole>(context.Get<ApplicationDbContext>()));
        }
    }
However, this causes and error since RoleStore<ApplicationRole> constructor takes IdentityCloudContext type but the Get returns the generic typed version.

CS1503 Argument 1: cannot convert from 'QuoteTestWebsite.Security.ApplicationDbContext' to 'ElCamino.AspNet.Identity.AzureTable.IdentityCloudContext' QuoteTestWebsite C:\Workspaces\Fidelity Group\Fidelity Energy\Suppliers\QuoteTestWebsite\App_Start\IdentityConfig.cs 131 Active


I'm not sure how to resolve this conflict ?

comments

ianpowell wrote Mar 2, 2016 at 6:03 AM

It would be a great help if the MVC sample project was updated to show roles being used and maintained (add, delete, list).

This library is great, adding this seemingly minor request would make it awesome.

It would help me too.

erikst wrote Apr 8, 2016 at 11:32 PM

Hey,

I have implemented roles, but I didn't have the need to make a specific ApplicationRoleManager. I will paste my code:

Startup:
            services
                .AddIdentity<ApplicationUser, ApplicationRole>()
                .AddAzureTableStores<ApplicationDbContext>(() =>
               new IdentityConfiguration()
               {
                   StorageConnectionString = Configuration.Get<string>("AppSettings:StorageConnectionString")
        })
                .AddDefaultTokenProviders()
                .AddUserStore<ApplicationUserStore>()
                .AddRoleStore<ApplicationRoleStore>()
                .CreateAzureTablesIfNotExists<ApplicationDbContext>(); //can remove after first run;
IdentityModel:
    public class ApplicationUserStore : 
        UserStore<ApplicationUser, ApplicationRole, ApplicationDbContext>,
        IQueryableUserStore<ApplicationUser>
    {
        public ApplicationUserStore(ApplicationDbContext context)
            : base(context)
        { }

        public IQueryable<ApplicationUser> Users
        {
            get
            {
                //The connection between a user and a role is also stored in the user table. This makes 
                //querying on the user a bit hard. This works (a custom property on user), but is not the most elegant solution.
                return Context.UserTable.CreateQuery<ApplicationUser>().Where(u => u.IsUser == true);
            }
        }
    }
    
    public class ApplicationRoleStore : 
        RoleStore<ApplicationRole, ApplicationDbContext>,
        IQueryableRoleStore<ApplicationRole>
    {
        public ApplicationRoleStore(ApplicationDbContext context)
            : base(context)
        { }

        public IQueryable<ApplicationRole> Roles
        {
            get
            {
                 return Context.RoleTable.CreateQuery<ApplicationRole>();
            }
        }
    }

    // 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 ApplicationUser() : base() { }

        public string FirstName { get; set; }

        public bool IsUser { get; set; }
    }
    
    public class ApplicationRole : IdentityRole
    {
        public ApplicationRole() : base() { }
    }
    
    public class ApplicationDbContext : IdentityCloudContext
    {
        public ApplicationDbContext() : base() { }

        public ApplicationDbContext(IdentityConfiguration config) : base(config) { }
    }
    [Authorize]
    public class RoleController : Controller
    {
        private readonly ILogger _logger;
        private readonly UserManager<ApplicationUser> _userManager;
        private readonly RoleManager<ApplicationRole> _roleManager;

        public RoleController(
            ILoggerFactory loggerFactory,
            UserManager<ApplicationUser> userManager,
            RoleManager<ApplicationRole> roleManager)
        {
            _logger = loggerFactory.CreateLogger<AccountController>();
            _userManager = userManager;
            _roleManager = roleManager;
        }
This should be all you need to get started, but I agree. It would be great if it was in the sample.