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?

6 Answers 6

29

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.

Sign up to request clarification or add additional context in comments.

8 Comments

Awesome! I can confirm that this does what I want. Thanks for the quick response.
You are the legend. I was stuck on this issue and was looking for solution from many days. This solution solved my all problems.
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?
@variable 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 automatically
Sorry I meant HttpContext.User. What I am confused is that - whether I can use the roles (IsInRole, etc) without having Identity.
|
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.

1 Comment

Is AddRoles and AddRoleManager really required? or at least, is it required for .NET Core 2.2? See: stackoverflow.com/a/55361961/764307
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

1 Comment

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>();
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).

Comments

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>(); 

1 Comment

thank you this kinda helped me to reenable the roles
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>(); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.