2
\$\begingroup\$

I have a controller that returns data about users. I want to set the authorization such that an admin can access this controller and retrieve data for any user, and a non-admin user can access the controller and retrieve data for themselves.

I've ruled out using [Authorize (Roles = "Admin")] because this means users can't get their own data. So I've inserted the following logic into the controller action:

var userId = _httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.Name).Value;
var roles = _httpContextAccessor.HttpContext.User.FindAll(ClaimTypes.Role);

var query = roles.Select(r => r.Value).Contains("Admin");

Customer customer =await _context.Customers.FindAsync(id);

if (!(customer.EmailAddress == userId || query))
 return Unauthorized();

This is roughly equivalent to this Stack Overflow answer, but for ASP.Net Core rather than MVC.

My question is, is there a way to do this with an Authorization Policy? Adding the RequireRole check is straightforward and covered in the MS Documentation as well as countless blogs, but I couldn't find or figure out a way to use a policy to check that the data the user is trying to access is their own.

I'm sure this isn't an uncommon requirement, is there a way to do this, or is what I'm currently doing OK? The only other approach I could think of was to have two separate endpoints, but both options seem inelegant.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ For this to make sense, cold you please show the entire method, including attributes - also on the controller class level? \$\endgroup\$ Commented Sep 12, 2019 at 14:23
  • \$\begingroup\$ @HenrikHansen I don't think that's necessary. I really would just like to know whether good design would require separate endpoints, and if not whether the logic can be handled by an authorization policy. \$\endgroup\$ Commented Sep 13, 2019 at 0:34

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.