Skip to content

Role-Based authorization not working in asp.net core 2.1 #11413

Closed
@Danni-Ke

Description

@Danni-Ke

Describe the bug

I followed the instruction on documentation and online about the role authorization, but the authorize since doesn't work even after I add the role type to my database. It always lets the user access the resources no matter what the user role is. I don't see why and have not idea what I am missing in my startup. Any helps will be appreciated.

To Reproduce

Steps to reproduce the behavior:

  1. Using this version of ASP.NET Core '2.1'
  2. Run this code '....'
  3. With these arguments '....'
  4. See error

Expected behavior

It should reject the user request to the API, but it doesn't.

My startup.cs

    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        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.UseMySql(Configuration.GetConnectionString("DefaultConnection")));
            //role service
            services.AddIdentity<IdentityUser, IdentityRole>()
                .AddRoles<IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();

            services.AddTransient<IEmailSender, AuthMessageSender>();
            //Disable the Password Hash 
            services.AddScoped<IPasswordHasher<IdentityUser>, MyPasswordHasher>();

            var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
            //using the aspnetIdentity, the server will read the userdata via identity API

            services.AddIdentityServer()
                  .AddDeveloperSigningCredential()
                  .AddConfigurationStore(options =>
                  {
                      options.ConfigureDbContext = builder =>
                       builder.UseMySql(Configuration.GetConnectionString("DefaultConnection"),
                       sql => sql.MigrationsAssembly(migrationsAssembly));
                  })
                  .AddOperationalStore(options =>
                   {
                       options.ConfigureDbContext = builder =>
                           builder.UseMySql(Configuration.GetConnectionString("DefaultConnection"),
                           sql => sql.MigrationsAssembly(migrationsAssembly));

                       // this enables automatic token cleanup. this is optional.
                       options.EnableTokenCleanup = false;
                       options.TokenCleanupInterval = 30;
                   })
                    .AddAspNetIdentity<IdentityUser>();
     


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

        private void AddAspNetIdentity<T>()
        {
            throw new NotImplementedException();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider serviceProvider)
        {
            if (env.IsDevelopment())
            {
                //InitDatabase(app);
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }
            app.UseAuthentication();
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();
            app.UseIdentityServer();
           
            
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
            //CreateRoles(serviceProvider).Wait();
            
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="serviceProvider"></param>
        /// <returns></returns>
        private async Task CreateRoles(IServiceProvider serviceProvider)
        {
            var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
            var UserManager = serviceProvider.GetRequiredService<UserManager<IdentityUser>>();
            IdentityResult roleResult;
            string[] roleNames = { "Admin", "User" };
            foreach (var roleName in roleNames)
            {
                var roleExist = await RoleManager.RoleExistsAsync(roleName);
                if (!roleExist)
                {
                    roleResult = await RoleManager.CreateAsync(new IdentityRole(roleName));
                }
            }
            await AddRoles("pineappleman520@gmail.com", "Admin", serviceProvider);
            await AddRoles("1111@qq.com", "User", serviceProvider);
            await AddRoles("985@qq.com", "User", serviceProvider);
            await AddRoles("dannike19980521@gmail.com", "User", serviceProvider);
            await AddRoles("dxk5418@psu.edu", "User", serviceProvider);

        }
        private async Task AddRoles(string Email,string Role ,IServiceProvider serviceProvider)
        {
            var UserManager = serviceProvider.GetRequiredService<UserManager<IdentityUser>>();
            IdentityUser user = await UserManager.FindByNameAsync(Email);
            await UserManager.AddToRoleAsync(user, Role);
        }


### The API I want to protect
[Authorize(Roles = "Admin")]
        public IActionResult About()
        {
            ViewData["Message"] = "Your application description page.";

            return View();
        }

Additional context

Thanks, guys. I will update more information later.

Metadata

Metadata

Assignees

Labels

Needs: Author FeedbackThe author of this issue needs to respond in order for us to continue investigating this issue.area-authIncludes: Authn, Authz, OAuth, OIDC, Bearer

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions