Multiple authentication levels in a RESTful API - api

Scenario
We are building a new RESTful API for our web application. This API will serve our mobile applications, our web application and authorised customers.
We are using Apigility to build the API and are making use of the OAuth2 implementation it provides.
Currently, our web application relies on a users table, with permissions assigned to each user. These users simply log-in using a web form, and the session is then stored and appropriate permissions checked upon access.
We want to be able to authenticate API access (such as our web app, and authorised customers), so no unauthorised access to the API can happen. However, we also want to authorize the permissions at a user level, therefore some sort of user authentication must also happen as well.
Any authorised access to the API may use a different user, so relying on a single user per client will not work, especially since the permissions are on a per user basis. We also do not want any user to be able to use the API without prior authentication, so wanted to avoid adding every user as a client to OAuth2.
For example:
The web app is authenticated with the API with two users using it:
UserA has user management permissions
UserB does not have user management permissions
Therefore, UserA can POST to /users and receive a 200 OK while UserB should receive a 403 Forbidden.
What we have tried
We have created an example application, and have successfully set up authentication using OAuth2 for the high-level clients and can make calls as expected. But we have not been able to create an authorization model for our users based on this.
We though adding a custom HTTP header with a user token that is provided after an authenticated call to /user/login. But we are not sure if this is the correct method.
The question
How can we both authenticate the high-level clients (such as our web app, or authorised customers) but then authorize access based on the user actually using the system?

You have a few options available to you:
Token-level permissions
You can provide different tokens for each user account, and tie permissions to the token. This runs the risk of the wrong tokens being mixed up with the wrong users. However, this also has the advantage of not having to maintain a user<->token relationship, as the permission is decided at the token level. How you decide which token to generate can be tricky.
User-level permissions
You can tie a user account to a token and that user can then be given read/write permissions. This reduces the risk of a user having a wrong token as they're linked. With this method, you can use the same method of token generation for all user accounts as the token is ignorant of the permission, but does allow them "access" to the API (thus preventing unauthorised access).
I've deliberately avoided mentioning specific types of authentication tokens, as these two concepts can apply to most of the popular choices on the web (token-based, OAuth based).

OAuth has no concept of Identity.
You should look into using OpenID Connect which is a profile on top of Oauth 2.0.

Related

Add user claims after authentication against IdentityServer 4

I have the following projects:
Identity Server 4, with ASP.NET Identity as a user store for all users of all my apps.
.NET Core 5 Web API
Xamarin app
The flow goes like this:
User logins from the Xamarin app (3) and is authenticated against IdentityServer (1)
User receives an access token from Identity Server, that contains the sub claim
User makes a request to the Web API (2) using the access token
The Web API (2) checks its own database for user permissions
----QUESTION/PROBLEM IS HERE-----
Should the Web API add these user claims (permissions) to the access token, OR should the Web API always check the database for the user permissions on every request made from the client?
Maybe I could add the claims before authenticating with IdentityServer, but this would mean that IdentityServer would have access to the Web API's database. I believe this is not a good practice because of separation of concerns.
Another solution would be to introduce a caching mechanism when the Web API validates the token, so that it doesn't always check the database.
Using claims transformation, it is my understanding that I can add the claims to this 1 request only, meaning that the next time a client makes a request, claims transformation should happen again, since it doesn't return a new access token to the user.
Ideally, I would like the Web API to add the claims to the access token so that the Web API can trust these claims on all subsequent requests. I cannot find a way to do so, though. I've searched for Claims Transformation, IssueJwtAsync (IdentityServerTools), IProfileService, but I think none of these are solutions to this problem.
Is this good architecture? Please do share your opinions on this subject and potential solutions.
Thank you very much!
You need to add these permissions in web api, because users need to access the corresponding resources according to these granted permissions. And permissions are granted when the user logs in for the first time, without the need to access the database in every request.
In this case, you can use Claims Transformation. This link has more detailed steps which can solve this problem.

MicroServices Authentication / Authorisation

We are looking to implement a Micro Services architecture in the future. We don't want permissions at the API gateway to be very clunky and restricted to GET, PUT, POST etc.
We want granular application permissions to be stored and managed centrally, so apps only have to fetch them and not manage them.
I have included a picture of the draft architecture I have in my head as well as logic flow below.
My Question
Can this design pattern be implemented using any of the existing authentication/authorisation specifications such as OAuth2? If not, is it acceptable to create your own Authentication / Authorisation pattern for use with in a private network?
App Life cycle
A developer creates WebApp1
WebApp1 is registered in the Web App Registry Server by the developer. He/She also registers the custom permissions that the App exposes.
Users can have access granted or revoked to the granular permissions exposed by the App by an IT Administrator.
In the example above WebApp1 exposes two permissions CreatePost & DeletePost user1 only has permission to CreatePost
User Process Flow
An unauthenticated user accesses WebApp1 and is redirect to the Login screen.
The user's credentials are validated against LDAP and a UUID Authorisation token is generated. The token is stored in a Security Token Server and the user redirected back to WebApp1 with the token included in an Authorization Header.
WebApp1 requests the permissions this user has from the Web App Registry server, this can be done every x minutes and stores them in local state. The Web App Registry Server also checks the Authorization token is still valid.
WebApp1 checks every x minutes that the users token is still valid, if not the user is requested to login again (or a refresh token could be included with the original token that was sent to the app when the user Authenticated).
Interesting question - some thoughts below on achieving your goals via OAuth based design patterns:
AUTHORIZATION GOAL
The desired end state is usually to give yourself choices:
Use a pattern that enables any API component to do authorization
Sometimes you need to be close to the data source to enforce permissions.
Other times you may want some types of rule to be enforced via a dedicated service
MAPPING TOKENS TO PERMISSIONS
I like this way of doing things. In effect it is a Claims Based Architecture, and the information you need for authorization won't come solely from tokens.
My API Authorization Post describes an extensible pattern that starts with defining a claims / principal object in each API. Here is some sample code, where the Authorizer class provides an overview of behaviour on each API request.
WEB APP REGISTRY
I would be careful about creating components that could come under heavy load and become a bottleneck for your whole software platform - should you need one of these?
CLAIMS AND MICROSERVICES
A pattern that can work well is to design 2 levels of API. Interestingly, both of these can use claims and you can put authorization responsibilities anywhere you want - and give yourself choices:
Entry point APIs: exposed to the internet, do OAuth validation and naturally lock down what clients can do with access tokens:
Microservices: run in a locked down network and can freely call each other without OAuth plumbing
My API Platform Architecture
post explores this option, where claims are passed between microservices via headers.
ACCESS TOKEN VALIDITY
You can often simplify code by following the below rules, since there can be multiple reasons for tokens becoming invalid:
Keep access tokens short lived ~60 minutes
Handle 401 errors in the client as in this code

Should the ID Token or Access Token be used to authorize SPA functionality?

Context
I have a Single Page Application which communicates with a backend REST API. This REST API is made specifically to serve the SPA. In order to navigate or use any functionality of the SPA beyond the home page, users must log in first. I am using OIDC with Okta to authenticate users. Users can either have an Admin role, or a User role. Their role will be used to authorize which SPA pages they are allowed to navigate to, and which REST API calls they are allowed to make.
Questions
After a user logs in, my application receives an ID token and and Access token from Okta. I have the option for including the user's role as a custom claim in either the ID token, or the Access token. Which token should include this information in? Both?
The UI needs to make some authorization decisions based on the user role.
For example, which HTML elements to show or hide, and which SPA routes are navigatable. Should these decisions be made by inspecting the ID token, or the Access token? Other?
When calling my backend API via the SPA should I forward the ID token and Access token that my SPA received? Just the Access token? Or should I set up a different authorization server for my backend REST API, and have my SPA reach out for another access token?
Some answers:
The id token is just an assertion to the SPA that the user is authenticated. If you are going to put the role in a token, use the access token, whose purpose is authorization
The API should be controlling authorization. Your SPA should ask your API, about authorized areas and the API can answer based on the access token contents. Your SPA should not read the access token directly.
Only send the access token to the API, which is the standard recommended behaviour
RESPONSIBILITIES
Generally:
UIs can make UI decisions on which elements to show
Of course the data they use for this needs to come from a trusted source
UIs can read a role from id tokens and use that to control what to show
But the API also needs the role information, to authorize requests
If you want to use role information in both UI and API, then a default option is to add the role to both the id token and the access token.
However, this does not scale well, since in a real business app you are likely to add multiple similar rules over time, and keep needing to add claims to tokens.
EXTENSIBILITY
A better option that is easier to manage over time, is for the UI to ask its API for the role + other data - since the API needs the same role information anyway.
Also, tokens do not need to be the only source of data for authorization decisions made by UIs and APIs. My blog post on claims describes a pattern you can use to manage claims over time from multiple data sources.

Is OAuth 2.0 redundant/unnecessary if the client is the same as the resource owner?

In section 1.1 of RFC 6749, there are four roles: resource owner, resource server, client, and authorization server.
Does OAuth become redundant or unnecessary if the client and the resource owner are the same entity?
For example, I have a closed API and a front-facing web server. (The front-facing web server would be both the client and the resource owner.) I am trying to decide whether to switch to OAuth 2 authentication instead of using the current username/password authentication method. Is there any added security for moving to OAuth 2 if the API remains closed to third-party applications? (That is, no third-parties will ever have access to the API.)
Thanks!
In the case where the Resource Owner and Client/Resource Server roles coincide OAuth 2.0 may become less relevant from a security point of view, since one of the primary objectives of OAuth not to expose primary credentials of the user to the client becomes moot. That is also the reason why the so-called Resource Owner Password Credentials grant is considered to be a legacy/deprecated flow.
However, it may still make sense to follow the OAuth 2.0 pattern for a number of reasons:
the ability to leverage a standardized protocol through stock libraries and
frameworks without relying on custom code
the fact that in your case the Resource Server is still made strictly OAuth 2.0 compliant, dealing with Clients presenting access tokens, irrespective of what the Client/Resource Owner relationship/implementation is; this would make it easier to allow for 3rd-party client access in a future scenario
the fact that you concentrate verification of user credentials on a single path between Client and Authorization Server so each of your Resource Servers don't need to be bothered by checking user credentials individually, possibly dealing with different authentication mechanisms
and perhaps most importantly, also security-wise: once the user has authenticated through the Client using his primary credentials, the Authorization Server can issue a refresh token as well as an access token; the Client can store and use the refresh token to a new access token when the old one expires; this frees the Client from storing the primary user credentials if it wants to keep accessing the API for a long period of time without requiring explicit user interaction and authentication and makes the resulting system less vulnerable for leakage/loss of user credentials since the user credentials (password) are not stored in the Clients
If you have the following issue then you should use OAuth;
Let's say you a Gmail like web mail provider. Some of your users are using a third party app which logs in into your user's account and auto replies certain emails for you. Or you are Facebook like social network web site where some of your users use a third party app which analyzes your friend networks and prints a 2D graph for you. In this case your users are giving away their usernames and passwords. How would they prevent a certain third party app accessing their account after they gave away their username and password? Simply by changing their password. Now you have another problem; other third party apps won't be able to access the user's account. Then the user have to re-give away his password to other apps he trusts. Now this is problem too because it is not user friendly. OAuth is simply a temporary password that your user gives away to a third party app developer. He can revoke it whenever he wants without changing his own password.
Other than that OAuth is unnecessary. Just use a session cookie if you are not going to have third party app developers. It is a random string stored in user side. And on the server side will have whatever you want. Just look how PHP sessions are used and stored on server side. You can define their lifespan and refresh time automatically from php.ini.

Should a REST API contain an ADMIN section and use the same OAuth 2 authorization as the rest of the API?

I'm planning a web app centered on a REST API and I would like this API to be the only way to access the app, be it from my own web-site or any other tool using the API via OAuth 2 authorization.
Obviously, some critical sections should only be accessible to administrators: user deletion, billing management...
I was wondering what would be the best practice in that case:
Should the API contain that admin section (/admin for example) which is only accessible when admin access is granted by OAuth ?
Is that a security risk and should the administrator section be accessed differently via a different hidden secured access ?
I would keep the parts together and I don't think it's a security risk. I even see two different paths for the implementation:
Use plain OAuth2. The admin section of the API simply requires presence of "admin" scope for attached tokens, while other parts require only a "user" scope. However, you should somehow make sure that only administrator users may have a token with the "admin" scope. You may have to customize your OAuth server for this.
Ignore token scopes. Instead, use a special token validation to get roles of the user that granted the token.
Either way, I see no reason to seperate the admin part from the rest of the API.