How to use Roles in ASP.NET Core 2.1?
Asked Answered
C

6

19

I've created a test project using:

dotnet new razor --auth Individual --output Test

This creates a Startup.cs that contains:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        // This lambda determines whether user consent for non-essential cookies is needed for a given request.
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlite(
            Configuration.GetConnectionString("DefaultConnection")));

    services.AddDefaultIdentity<IdentityUser>()
        .AddEntityFrameworkStores<ApplicationDbContext>();

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

I want to seed some users and roles. Both users and roles will use the same store (SQLite). I'm using a static class for seeding which it's called from Program.

I can seed users, but not roles, since the above does not seem to inject a RoleManager.

In ASP.NET Core 2.0 the following is used:

services.AddIdentity<IdentityUser, IdentityRole>()

I'm guessing AddDefaultIdentity is new in 2.1 but the problem is that it does not inject a RoleMnager, so what should I do?

Colour answered 19/5, 2018 at 14:20 Comment(0)
F
28

It seems that finally Microsoft understood that not every application needs roles and separated them.

Notice that AddDefaultIdentity is declared as:

public static IdentityBuilder AddDefaultIdentity<TUser>(this IServiceCollection services) where TUser : class;

So, you can continue to configure Identity options through that IdentityBuilder. What you want to do is:

services.AddDefaultIdentity<IdentityUser>().AddRoles<IdentityRole>();

Fortunately, they also removed the IUser and IRole constrains, so now you can use models in a completely separate assembly without having to install hundreds of NuGet packages.

Felsite answered 19/5, 2018 at 15:8 Comment(8)
Awesome! I can confirm that this does what I want. Thanks for the quick response.Colour
You are the legend. I was stuck on this issue and was looking for solution from many days. This solution solved my all problems.Gustin
Is roles tied to Identity? What if I don't use identity and my JWT token has got the roles inside it? Then can I use the .AddRoles?Matchless
@Matchless That's completely unrelated to Identity then - i.e. you can't use AddRoles nor anything else in this Q&A. If ASP.NET Core is properly configured, though, you can get it to use roles in JWTs automaticallyFelsite
In that case can I use AuthorizationHandlerContext.User.IsInRole? If not then should I use HttpContext.Current.User...?Matchless
@Matchless Well, that depends where you want to check for the role and what for. HttpContext.Current doesn't exist in ASP.NET Core thoughFelsite
Sorry I meant HttpContext.User. What I am confused is that - whether I can use the roles (IsInRole, etc) without having Identity.Matchless
@Matchless Yes, you can. Google something like "asp.net core roles -identity site:stackoverflow.com" - a similar search should get you on the right path. Notice that where the roles are in the JWT affect how you configure the startup for your application thoughFelsite
F
14

Might help someone else: If you add asp.net identity through scaffolding to an existing project, you'll need to edit the IdentityHostingStartup.cs and change the services there instead of in your startup class:

services.AddIdentity<AppUser, IdentityRole>()
                .AddDefaultUI()
                .AddRoles<IdentityRole>()
                .AddRoleManager<RoleManager<IdentityRole>>()
                .AddDefaultTokenProviders()
                .AddEntityFrameworkStores<authContext>();

And then you can use the role manager in your seeding.

Fortenberry answered 21/6, 2018 at 20:10 Comment(1)
Is AddRoles and AddRoleManager really required? or at least, is it required for .NET Core 2.2? See: https://mcmap.net/q/145811/-addidentity-vs-addidentitycoreCyrstalcyrus
S
6

In addition to the answers already provided, despite adding .AddRoles<Identity>(), I still could not get Authorization when use Authorize(Roles = "Administrator") on my controllers. For some reason,the "role claim doesn't seem to affect IsUserInRole or AuthorizeAttribute with a role name."

To make use of roles I would suggest that one use the ASP.NET 2.0 way like below:

services.AddIdentity<IdentityUser, IdentityRole>()
            .AddDefaultUI()
            .AddDefaultTokenProviders()
            .AddEntityFrameworkStores<ApplicationDbContext>();

This way, you get to use your roles and also get the Identity pages scaffolded for you.

Refer to this issue on aspnet github: Issue 1813

Subterrane answered 16/7, 2018 at 7:20 Comment(1)
I had stumbled across this too but didn't update my response above. My IdentityHostingStartup.cs file now contains: services.AddIdentity<AppUser, IdentityRole>() .AddDefaultUI() .AddRoles<IdentityRole>() .AddRoleManager<RoleManager<IdentityRole>>() .AddDefaultTokenProviders() .AddEntityFrameworkStores<authContext>();Fortenberry
S
4

Starting in .Net Core 2.1, AddDefaultIdentity is the same as calling:

  • AddIdentity
  • AddDefaultUI
  • AddDefaultTokenProviders

To add role functionality, go to Startup.cs under ConfigureServices you can use .AddRoles like so:

services.AddDefaultIdentity<IdentityUser>()
    .AddRoles<IdentityRole>()            //<-- This line
    .AddEntityFrameworkStores<ApplicationDbContext>();

That's all that is needed. It is crucial to logout and login again.

For the record (and just to test), I tried services.AddIdentity:

IServiceCollection does not contain a defintion for 'AddIdentity'...

and services.AddIdentityCore (no error until Debug and displaying the page):

InvalidOperationException: No authenticationScheme was specified, and there was no DefaultChallengeScheme found. The default schemes can be set using either AddAuthentication(string defaultScheme) or AddAuthentication(Action configureOptions).

There may be more you can do to get the latter two working, but the code I posted for AddDefaultIdentity is all I needed in order to get User.IsInRole and other role functionality working in .NET Core 2.1 (and 3.1).

Shellashellac answered 10/4, 2020 at 17:49 Comment(0)
E
1

I also fought with this problem a while ago. I couldn't make roles to work.

In my project I used ASP.NET Core 2.1 (it could be fixed in 2.2, see link) and also scaffolded some pages.

After long searches on the internet I found this solution (which is also mentioned above in Issue 1813)

The solution was for me (as proposed in the article) to add the following line with IUserClaimsPrincipalFactory:

        services.AddScoped<IUserClaimsPrincipalFactory<IdentityUser>, 
            UserClaimsPrincipalFactory<IdentityUser, IdentityRole>>();

        services.AddDefaultIdentity<IdentityUser>()
            .AddRoles<IdentityRole>()
            .AddRoleManager<RoleManager<IdentityRole>>()
            .AddDefaultTokenProviders()
            .AddEntityFrameworkStores<TranslatorDbContext>();
Endblown answered 6/7, 2019 at 19:39 Comment(1)
thank you this kinda helped me to reenable the rolesMegaphone
F
0

Also note that this code is order sensitive. If you put AddRoles after Add EntityFrameworkStore you will get an exception.

So make sure the order is like this:

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddRoles<IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>();
Fourway answered 11/12, 2022 at 12:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.