0

I'm having trouble getting some simple role based security to work in an ASP.NET MVC5 SPA in VS2017 Community.

Here's the top of my controller:

namespace ManagementWebSite.Controllers
{
    [Authorize(Roles = "Administrator")]
    public class SystemManagementController : ApiController

Controller works fine with no Authorize attribute, but I want to lock it down to an Administrator app role. I added the role to my test@test.com user like so in Startup.cs:

    void ConfigureRolesandUsers()
    {
        ApplicationDbContext context = new ApplicationDbContext();
        var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
        var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));

        if (!roleManager.RoleExists("Administrator"))
        {
            var role = new IdentityRole();
            role.Name = "Administrator";
            roleManager.Create(role);

            var user = userManager.FindByEmail("test@test.com");
            if (user != null)
            {
                if (user.Roles.Where(b => b.RoleId == role.Id).Count() == 0)
                {
                    userManager.AddToRole(user.Id, "Administrator");
                }
            }
        }
    }

Seems to get the role claim on login, but still, if I login as test@test.com and try to use the controller in the browser I get a 401 Unauthorized, and I'm not sure why because the user has the Administrator role and is getting the claim on login.

Logging out and back in, restarting VS, removing (and later re-adding) the RoleManager module didn't work.

So the next thing I tried was subclassing the AuthorizeAttribute like so:

public class RoleAuthorizeAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);
    }

    protected override HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext)
    {
        return base.OnCacheAuthorization(httpContext);
    }

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        return base.AuthorizeCore(httpContext);
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        base.HandleUnauthorizedRequest(filterContext);
    }
}

And setting breakpoints on each method. None of the breakpoints get hit while trying to debug, but now the app lets it through, so I'm wondering what's going on and if it's even checking the role properly like it should. How do I debug when I need to see what's going on upstream from the controller action like this? Seems like the AuthorizeAttribute alone should just work without subclassing since it has a Roles property to use, is this not the case?

John Ernest
  • 785
  • 1
  • 8
  • 20
  • The Authorize attribute works after I realized my Controller was using the System.Web.Http namespace, but I'm still quite concerned that my custom RoleAuthorizeAttribute won't hit any breakpoints on my override methods. I'd like to be able to debug those appropriately when the situation arises that I need to make my own custom attributes. – John Ernest Jul 19 '17 at 05:26
  • Your [Authorize(Roles = "Administrator")] attribute looks all right. When you log in do you have a claim for role specifying as "Administrator"? Have you saved your role information the the database? – TejSoft Jul 19 '17 at 06:01
  • Yes and yes. There is a claim for the role when authenticating. The role is saved in the DB (looking at the localdb right now in SQL Mgmt Studio). When I changed my Authorize attribute call to: [System.Web.Mvc.Authorize(Roles = "Administrator")] (just to be explicit in clarification), I'm no longer getting 401 Unauthorized. It's also not even trying to authorize. I can hit that controller directly while unauthenticated. A user without the Administrator can also hit the controller action, so something is definitely wrong. – John Ernest Jul 19 '17 at 06:34
  • Looking a little at this video: https://channel9.msdn.com/Blogs/Seth-Juarez/ASPNET-Core-Authorization-with-Barry-Dorrans they said something to the effect that a lot of people in MVC5 wrote their own custom authorize attributes (and many left gaping security holes in their apps). Is that pretty much the only answer here is to scrap it and write your own authorization implementation? (and I'm not using ASP.NET Core in this app because I needed access to some Win32 specific things like WMI that were removed in .NET Core/Standard to be cross-platform compatible) – John Ernest Jul 19 '17 at 06:38
  • Things are starting to make a little more sense now. This stack is highly important to read because my controller is an ApiController so I do need to derive from System.Web.Http instead of System.Web.Mvc: https://stackoverflow.com/questions/19152109/system-web-http-authorize-versus-system-web-mvc-authorize – John Ernest Jul 19 '17 at 14:57

0 Answers0