Search code examples
c#.net-coreiis-express

.NET Core 2.1 Windows authentication does not recognise role membership


I have followed the tutorials and Stack Overflow questions I can find but still have a problem where I get a 403 Forbidden on a method that is decorated with the [Authorize] attribute.

This is a method that works and proves Google Chrome is passing my Windows credentials to the site which is running in IISExpress during debugging.

public IActionResult Index()
        {
            ViewBag.UserIdentityIsAuthenticated = User.Identity.IsAuthenticated;
            ViewBag.UserIdentityName = User.Identity.Name;
            ViewBag.UserIsInRoleTechnical = User.IsInRole("ADSecurityGroupOne");
            ViewBag.UserIsInRoleTechnicalPeople = User.IsInRole("ADSecurityGroupOneTwo");

            return View();
        }

This is the method that fails with a 403 which is only supposed to show the view, it is not yet linked to any database.

    [Authorize(Policy = "AllowedOnly")]
    [HttpPost]
    [ValidateAntiForgeryToken]
    public IActionResult Index(AccountViewModel model)
    {
        if (ModelState.IsValid)
        {
            return View();
        }
        else
            return View();
    }

This is the ConfigureServices method from Startup.cs

public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();

            services.AddOptions();
            ApplicationSettings appSettings = new ApplicationSettings();
            Configuration.GetSection("ApplicationSettings").Bind(appSettings);
            
            services.AddAuthentication(IISDefaults.AuthenticationScheme);
            services.AddAuthorization(options => options.AddPolicy("AllowedOnly", policy => policy.RequireRole(appSettings.AllowedToMigrate)));
        }

I have confirmed that the value of AllowedToMigrate is the same as what is specified in appsettings.json.

{
  "ApplicationSettings": {
    "AllowedToMigrate": "ADSecurityGroupOne,ADSecurityGroupTwo"
  },

  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  }
}

Why is [Authorize(Policy = "AllowedOnly"] failing?


Solution

  • Answering my own question because I figured out what I did wrong:

    The roles must be supplied as a string array if there's more than one or just a single string if there's only one. I updated the json application settings file and my ApplicationSettings class so that AllowedToMigrate was a string array.

    {
      "ApplicationSettings": {
        "AllowedToMigrate": [ "ADSecurityGroupOne", "ADSecurityGroupTwo" ]
      },
    
      "Logging": {
        "IncludeScopes": false,
        "LogLevel": {
          "Default": "Warning"
        }
      }
    }
    

    I also fixed a typo of the role name which was the original problem! So the moral of the story is: Make absolutely sure you are using correctly spelled role names and to always try it with different roles when authorization seems wrong for no reason.