Architecture Question: Best way to secure different resources behind an API exposed via AzureAD

Jason Ipock 6 Reputation points
2021-10-17T12:33:45.983+00:00

I have an API I want to expose to consumers that is currently secured via Azure AD. I have successfully configured an auth-code OAuth2 configuration, using an Angular application as the client and a .NET 5 WebAPI. I currently have roles configured, along with policies, to ensure that all users can access a Get method, and only a few others can use the upsert/delete methods. I'll be calling them 'widgets' here.

The issue I have is that I need to limit which widgets I return, based upon their permissions. These widgets all have a factory, along with a factoryId they were created in. There are plenty of cases where I'll need admins to be able to see all the widgets from all the factories, some users only be able see the widgets from the factory they work, and then a very small set of people who see no widgets at all via the get.

I could do this by creating a permissions table, manually searching this table based upon an authenticated name, and doing a join. This seems to be an inelegant solution. I am using roles, so, in theory, I could have a role per factory, but this will be a maintenance nightmare for hundreds of factories. Not to mention, I think there's a hard limit to how many roles I can put in. Especially if there's a supervisor, who is not an admin, but has rights to 50 factories. The security token would be huge.

What would be a good way to safely, securely, and efficiently secure an API like this?

Microsoft Entra ID
Microsoft Entra ID
A Microsoft Entra identity service that provides identity management and access control capabilities. Replaces Azure Active Directory.
19,457 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Jason Ipock 6 Reputation points
    2021-10-28T15:50:10.64+00:00

    I'm not quite certain I follow. I understand you're saying i should use a combination of Claims and Role-based authorization, but where would each part be checked? I'll try to elaborate.

    Let's use the example I have described above. As I am building a WebAPI, with the expectation that an authenticated user is attempting to obtain a list of Widgets that they have to work with for some reason.

    If this was a simple request for a single user, I could make a WidgetController.cs class, with an HttpGet attribute and check for a Role that permits access to Widgets.

    But, in my case, the list of Widgets needed is based upon authentication:

    • A StandardUser would get all of the Widgets from their factory
    • A RegionalManager would get all of the Widgets from their region (many factories)
    • A GlobalAdmin would get all of the Widgets from the whole company.
    • There are edge cases where a specific user would need access to factories not normally associated with their role

    Is the suggestion having a Role for each factory? If so, where should the AuthZ check be? If I make middleware, we somehow need to know the factoryId related to the request. Putting a factory in a header seems kludgy, so we'd need to possibly be consistent with a Query String variable and grab that value of that parameter in the middleware?

    You mention claims - how do you envision a claim appearing for each type of user? And where would these claims get populated? If it's Azure AD, we might end up having hundreds of factories, which would mean 100s of claims.

    Can you elaborate a bit more, please? Thx

    0 comments No comments