Custom authorization approach for WebApi - api

I am going to implement Authorization for my Web API project. For that I have been reading various blogs, stack overflow answers about authorization in WebApi.
Two ways I saw recommended is either use Custom Authorization filter or use Web API Message Handler which gets executed before any filters.
I have very distinct requirement for my project.
1) I have third party authentication service implemented. Request will come to web API pipeline only when authenticated. I just need to perform authorization.
2) All actions in all my controllers are needs to authorize. (No anonymous access)
3) There are three levels of authorization I need to perform.
a) Module Level (to see if user has access to said module)
b) Record Level (if user has access to module see if he has access to particular resource accessing)
c) Action Level (if user has access on both see if user can perform the said action [View/edit/delete/create]
4) All my url follow some predefined pattern {api/module/resource/resourceid} & action GET, POST, PUT, DELETE
My requirement is, I don't want to register any attribute over any of action or controller & I want to infer the all incoming request and authorize user based on it. (using delegate handler)
I am trying to use below approach :
1) from the incoming request url extract module name, resource name , resource id & User Id from cookies and pass this info to a function which will return true or based on some business rules.
Examples:
GET API - api/modulename1/resource1/id -> This URL will check VIEW access to modulename1,resource1 & resource id
POST API - api/modulename1/resource1 -> This URL will check CREATE access to modulename1,resource1
Same thing for delete & edit also.
I want to ask experts here a question if this approach will work or if there are any limitations with this approach.

Related

Putting the calling user-id into the header of a REST-API

I am exposing REST API's via an API Gateway so the requests go
Client => API Gateway => Back-end.
My back-end REST API's need to know about 2 users
1: Target User (on some requests)
the API needs this data for its action eg: groups/{abc}/add-user needs to know which user to add to a group
2: Calling User (on every request):
the API needs to check that this user is allowed to perform the action eg: only a group admin may add another user to the group.
I don't want other developers to get confused when looking \ adding to my API's so I want to create a convention. Is it a good idea to add the calling user ID as a header on every request?
eg: "user-context": "12345"
Before everyone screams "INSECURE!!!!", I should add some info to put your minds at ease
The calling user is allowed to know their user-id. It's not a problem
The target user is not identified by their real user-ID but by an obfuscated ID
The calling-user-id is actually passed in a signed JWT to my API Gateway. The API-Gateway validates the JWT, takes the calling-user-id and adds it to the back-end request. What i'm really asking here is whether the API-Gateway should put the calling-user-id in the header (eg: "user context": "12345") or the query string /myapi/?calling-user-id=12345
I've tried both approaches and they both work. I'm wanting to know which approach makes the most sense to other developers.

Scopes for Web api in Openid connect

I am using Identityserver4 for AuthZ and AuthN and trying to understand the purpose of scopes for a webapi
I am implementing a first party application an internal application which will works in intranet. so there will be no consent page.
image : application architecture
I have 3 users
User X : who can perform read and write operation on Web API ‘A’ Only
User Y : who can perform read and write operation on Web API ‘B’ Only
User Z : who can perform read and write operation on both Web API ‘A’ and ‘B’
Since all the user will log in using the ‘Angular front end’. In the front at the time of login the scopes requested must be like below
{
response: code
scopes : ‘openid A:read A:write B:read B:write’
}
As I said earlier, I am using Identityserver4 once the user successful logins the client will receive Id_token and access_token.
I understood from different article that api will check for the scope to provide access to an operation like read and write. So,
If User X logs in, access_token should contain scope only A:read, A:write
If User Y logs in, access_token should contain scope only B:read, B:write
If User Z logs in, access_token should contain scope only A:read, A:write, B:read, B:write
Since ‘Angular front UI’ is same for all the 3 users (X, Y, Z) in my case.
Client will request all the scopes (A:read, A:write, B:read, B:write) is this correct ?
Do I need to write any custom logic when access_token is getting generated, its should include only scope that user is entitled too?
If I have to write this custom logic which interface I need to implement. is it IProfileService?. i have to use something like role to find out the scopes?
Lastly, in other word, scopes for an web api is nothing but permissions am I right?
In IdentityServer I would create one ApiScope (perhaps named ApiAccess). Then I would create two ApiResources, one for each API and associate them with the ApiScope created earlier.
Then have a UserClaim (perhaps named access) associated with the ApiScope, that contains the particular users access (read or write).
the value for the access claim is then retrieved from the user database.
Also, do see my answer here for a clarification between ApiSope, ApiResources and IdentityResources.
To complement this answer, I write a blog post that goes into more detail about this topic:
IdentityServer – IdentityResource vs. ApiResource vs. ApiScope

How can I use auth0 to register users and protect my API, but get the user_id

I am using auth0 to register users on my application, and hope to also use their api auth.
However, I have some endpoints like POST /api/v1/events which requires a authenticated user.
In the application side, each event has a createdByUserID which is the user id of the requestor. I would like to get the userID from each request that comes in.
How can I accomplish this? I'm trying to follow their docs but I am having a pretty hard time.
You can use a rule in Auth0 to call your application when a user is registered. See this forum post. You can access details about the newly registered user in your rule, to extract data to pass to your application - see the Auth0 doc.

Look up the user with bearer token with Openiddict Core

I am currently using Openiddict, Identity and Entity Framework to manage my users and assign Bearer tokens to users to protect my API.
My infrastructure is currently using ASP.NET Core Web API in the back end and a separate React application in the front end. The React application makes HTTP calls to my API to retrieve it's data. There is no server side HTML rendering at all in the back end.
Everything works as I need it to for the most part. I can register users and retrieve tokens from the API. These tokens are included in my HTTP call in the Authorization header. My AuthorizationController uses this: https://github.com/openiddict/openiddict-samples/blob/dev/samples/PasswordFlow/AuthorizationServer/Controllers/AuthorizationController.cs with a few minor tweaks. My Startup.cs also uses almost exactly this https://github.com/openiddict/openiddict-samples/blob/dev/samples/PasswordFlow/AuthorizationServer/Startup.cs
In some instances, I need to make API calls to the endpoints that are specific to the user. For instance, if I need to know if a user has voted on a comment or not. Instead of passing along the users ID in a query string to get the user details, I would like to use the Bearer token I received that they use to make the API call for that endpoint. I am not sure how to do this though.
In some research I have done it looks like some samples use ASP.NET Core MVC as opposed to the API to retrieve the user with the User variable as seen here https://github.com/openiddict/openiddict-samples/blob/dev/samples/PasswordFlow/AuthorizationServer/Controllers/ResourceController.cs#L20-L31 however this seems not to apply to my infrastructure.
My question is how do I look up a user based on the Bearer token passed to the API to look up a users details from my database? I am assuming that all of the tokens passed out by the API are assigned to that specific user, right? If that's the case it should be easy to look them up based on the Bearer token.
The question is: How with Openiddict can you look up a user based on the token that was assigned to them for API calls? I need to get the user details before anything else can be done with the application first. Is there something baked internally or do I have to write my own support for this?
When you create an AuthenticationTicket in your authorization controller (which is later used by OpenIddict to generate an access token), you have to add a sub claim that corresponds to the subject/entity represented by the access token.
Assuming you use the user identifier as the sub claim, you can easily extract it from your API endpoints using User.FindFirst(OpenIdConnectConstants.Claims.Subject)?.Value and use it to make your DB lookup.

RESTful API for authroization, plan features control

I am working on a web app. Front-end only interacts with back-end through RESTful API(it's called SOA architecture), and back-end only sends data to front-end in JSON.
My question is:
1) is it the best practice to design the authorization through RESTful API? or it is best to check authorization (user-> role -> privilege) at back-end code?
e.g.: do we ask user /checkPrivilege/{...} every time before executing other API?
2) How it is usually to implement 3 plans with different features & UI in RESTful API?
e.g.: do we use api to limits 5 users for this plan? or we do it at back-end code?
This is an old question, but I'll answer this anyway just in case some looks it up.
The short answer is you do it through the backend. The URI you are requesting should not contain any information about the user. Any session/identifying data should be sent in HTTP Headers.
Your RESTful API is always going to be loaded through a front controller like index.php. This is where you will want to bootstrap an authorization tool to check every single page request for credentials before executing the rest of your code.
Those credentials, at a MINIMUM, should contain a unique authorization token for the user who is making the request, and this token needs to be sent in every request (again, I recommend via an HTTP header). Bonus points if you grant a temporary access token that will expire, so as to prevent unauthorized access at a later date.
But for simplicity, let's say you are just using a permanent unique token per user. You would then store this token along with all the other data about the user, that other data should include an account_id for the account that user is a part of.
So for each request you would:
grab the user token from the HTTP Header
Look up the user based on that token.
If the user is found, then use their account_id to look up the master account their personal account is associated with
If it matches, grant them access
But remember, your URL should never contain this information in anyway. RESTful URLs are stateless.