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.
Related
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
After having read books and watched videos on OAuth, OIDC, PKCE, JWT, etc. I still have no idea on how to use all of these for my app (a secured REST API).
My use case is fairly simple. I want my users to be able to login with Google, Amazon, Okta or whatever and the only info I want from them is the email address they used to login, nothing else. After their first login, their email will be added to a database and in a separate process I will grant them some permissions (what resources they can access).
So let's imagine a standard authorization code flow and let's fast forward to the access token part. The redirect URI has been called, we are in my client (somewhere is my backend/API) where I retrieve an access token. At this point the user has been successfully authenticated.
But what now ?
I don't care about Google anymore (do I still need the access token ?), but I still want to check if the user can use my API for each request and is able to access the API resources depending on his permissions.
How do I keep the user authenticated (for like 2h only) and check his permissions ? A session Cookie, a Token or something else with an expiration time ?
Do I need my own authorization server to check if the user has access to the resource he is requesting ?
Considering my requirements, do I need PKCE if the API is accessed from an SPA or a mobile app ? Wouldn't the authorization code flow be enough - the SPA or mobile app retrieve an authorization code, then call the callback endpoint from the API ?
And the more important question is, do I ask the right questions or am I completely off track and it's not how it's supposed to work ?
In terms of your questions:
Your API needs an access token on every request
A stateless session is managed by sending the access token on every request
It is recommended to use your own Authorization Server that manages redirecting to social providers - this will simplify your UIs and APIs which only need to handle one type of token - also this means you are in control of the tokens your apps use
Yes - use PKCE for public clients - the Authorization Server and UI security libraries will handle this for you
Your use case is not simple at all on a technical level and requires a lot of understanding. A good starting point is to understand these aspects:
Role of UI and what a coded solution looks like
Role of Authorization Server and its configuration
Role of API and what a coded solution looks like
Open Id Connect messages used
These links of mine may be useful for browsing:
Initial code sample and tutorial
Message Workflow including PKCE
Given an access token, both the UI and API can potentially get the email via step 12 in the second link to lookup user info.
I am working on a prototype for a site re-architecture using ASP.NET 5 and I am debating using IdentityServer4 for my Authentication and Authorization. I have reviewed a lot of samples and articles about setting up IdentityServer3 and 4 and I am trying to wrap my head around if it can handle my client’s requirements in a proper way. Here are my requirements.
I have 3 sites that need authorization. Site 1 (abc.com) will require windows authentication and will be a combination of mvc and webapi calls using roles (or roles converted to claims) for authorization. Site 2 (def.com) is a trusted site that wants a login widget with a username/password/rememberme text box on their site that when submitted will authenticate the user and redirect them to site 3 (xyz.com). Site 3 will also have its own login page and will be a combination of mvc and webapi calls using claims. Site 2 and 3 will not be using windows authentication and the client does not want them redirecting to the identity server login screen, but rather having their own login screen and calling the identity server from code with the credentials to login.
Here are my questions regarding this scenario and IdentityServer4.
Can Idsvr4 handle one client using windows authentication and
another using username/password authentication?
If so, is there a
reason to have windows auth in idsvr4 or should it just use standard
windows auth within the webapp?
Can idsvr4 be setup to have the client collect the username/password/rememberme values and pass them through code to
get the proper jwt tokens for both mvc and webapi?
If so, can it
log them into both the mvc and webapi applications on another site?
If so, is this circumventing the real purpose of identityserver4
and therefor is a bad idea?
If it can handle this scenario and is a good idea, how would I setup the client, scopes and code to handle the login through code and redirect?
Examples are great and very welcome, but I am not even sure what verbiage to use to search for this scenario so even pointing me in the right direction would be of great help.
Not sure if this question is still active. But yes, i believe you can do all that.
1) You can setup which ldp is available for each client by setting IdentityProviderRestrictions on the client (docs)
1.1) - Not sure what you mean, i believe one of the points of having idsrv is to sentralize you authentication, and it makes it easier for future websites to integrate with the same service.
2) When logging in using a client (application), you also specify which apiResource the client has access to - and the application needs to add this to the requested scopes when signing in. So if your client is the mvc application, you just add the ApiResource in the AllowedScopes - and set the request_type to id_token code - this would then give the user a access_token that is passed with each request to the backend api. (docs)
2.1) - This would basically log the user in on both sites - using an access token that says that the user is authorized to use the backend api.
2.2) - In my opinion this flow is one of the things that makes idsrv great - and they even mention this as a great feature of idsrv themself. You just need 1 trip to the authserver to gain access to all systems.
as for pt. 3 - Take an extra look at the docs, try to setup a blank project following the quickstarts.
For logging in from your own login page, you need to use the grant type Resource Owner password - Altough they dont recommend doing this for security issues (transmitting passwords over the wire) - it is supported.
I am currently being tasked with writing an RESTful API that we are going to release to our clients. I plan to use Web API 2 with OWIN middleware. The applications that will be accessing this can range anywhere from a Console app with no additional user authentication to full blow web applications that will involve user login and authentication.
One other requirement is that we need not only provide user authentication to control what data we will return, we also need to authenticate that the application accessing our API is allowed by our organization. So this requires us to not only validate the application invoking our API's but also the many users logging in via that application.
The goal is to use a bearer token technology like OAuth 2. I am not very familiar with OAuth 2 but after looking it over I don't see a way to facilitate a two part authentication like this. Ideally we would like to issue a clientId and a clientPassword and they would pass this in along with the userid and userpassword and we would then pass a token back.
Is this something that anyone has tackled before using OAuth2 or is this a job for a custom auth solution?
What you describe sounds like fairly standard Oauth2.0 scenarios so you shouldn't need anything custom.
For the web apps you could use the Resource Owners Password Credentials Grant. Which is a standard flow.
This allows your Oauth client to pass in its client Id and client secret along with a user's Id and password to your Auth Server which can then validate both the user and the client before issuing a token in response.
But I would recommend using the Authorization Code Grant which is probably the best option for web applications and it involves both the client and the user being effectively authenticated.
For you console apps, or any apps which are not user specific, you can use the Client Credentials Grant. This allows the app to authenticate and to get a token without a user.
If you need your API to be aware of the client application, the only flow you can't really use is the Implicit Grant which doesn't authenticate the client.
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.