'Authorize(Roles = "Admin") not working in .net core 3.0

I have been struggling with the Authorization bit in my .net core 3.0 application. My User.IsInRole("Admin") returns true but if I add [Authorize(Roles="Admin")] to the controller then the admin user cannot access the page. Here is the code in my startup.cs file and controller : Startup.cs :

public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<ICanDBContext>(options => options.UseSqlServer(Configuration.GetConnectionString("ICanDBConnection")));
            var cultureInfo = new CultureInfo("en-GB");
            CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
            CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;

            services.AddIdentity<User, IdentityRole>()
                .AddRoles<IdentityRole>()
            .AddEntityFrameworkStores<ICanDBContext>();

            services.AddAuthorization(options =>
            options.AddPolicy("Role",
                policy => policy.RequireClaim(claimType: ClaimTypes.Role,"Admin")));

            services.AddControllersWithViews(options =>
            {
                var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
                options.Filters.Add(new AuthorizeFilter(policy));
            });

            services.AddAutoMapper(typeof(Startup));
            services.AddSingleton<IConfiguration>(Configuration);
        }


public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseDeveloperExceptionPage();

                //app.UseExceptionHandler("/Home/Error");
            }

            app.UseRouting();
            app.UseStaticFiles();
            app.UseHttpsRedirection();
            
            app.UseAuthorization();
            app.UseAuthentication();

            app.UseEndpoints(endpoints =>

Login Page :

if (!ModelState.IsValid)
            {
                return View(model);
            }

            var user = await _userManager.FindByEmailAsync(model.Email);
            if (user != null && user.IsActive &&
                await _userManager.CheckPasswordAsync(user, model.Password))
            {
                var role = _userManager.GetRolesAsync(user).Result.First();
                var identity = new ClaimsIdentity(IdentityConstants.ApplicationScheme);
                identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
                identity.AddClaim(new Claim(ClaimTypes.Name, user.UserName));
                identity.AddClaim(new Claim(ClaimTypes.Role, role));
                await HttpContext.SignInAsync(IdentityConstants.ApplicationScheme,
                    new ClaimsPrincipal(identity));

                return RedirectToLocal(returnUrl);
            }
            else
            {
                ModelState.AddModelError("", "Invalid UserName or Password");
                return View();
            }

And My AdminController is decorated like this :

[Authorize(Roles = ("Admin"))]
    public class AdminController : Controller
    {

Here's the DBContext class

public partial class StoreDBContext : IdentityDbContext<User, IdentityRole, string>
    {

Here is the claims value in debug mode :

enter image description here



Solution 1:[1]

The problem was in the order of Authentication and Authorization in the pipeline, Authentication should always be placed before Authorization.

More info: Middleware Order

Solution 2:[2]

you should change authentication place, make it after Authorization

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 HMZ
Solution 2 WARSIDES