I am wondering about one aspect of Identity Server that I hope to use in my projects.
The scenario is relatively simple:
I have an API and a couple of clients
I want to protect that API using Identity Server and OIDC
On one client, I was looking at the concept of having optional authentication.
Some features would require certain claims i.e Admin
The Rest should allow anonymous users access, but should only allow requests from the registered clients
This should also be reflected on the API
The caveat here is I would like still restrict the API to only be accessed by the registered clients in Identity Server only
Is this scenario possible in Identity Server?
I understand I would set up the Admin Policy on the API but do I also have to set up a CORS feature as well or does Identity Server do this out fo the box using the Allowed scopes and Resources Configuration?
Apologies if the explanation is poor I will try and add a diagram soon
Yes, if you wish to restrict API access to authenticated requests only, one way is via scope validation by setting up a global authorization policy (see https://github.com/IdentityServer/IdentityServer4.AccessTokenValidation).
Your admin endpoints would check for an additional claim. There are several ways to do this, one way is policy based authorization (https://learn.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-2.2).
You will need to configure the CORS middleware for your API (see https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-2.2). If you need CORs access to the Identity Server endpoints, then you'll need to configure Identity Server (see http://docs.identityserver.io/en/latest/topics/cors.html).
Related
I see that in most of the keycloak tutorials it is suggested to create two client in keycloak i.e. frontend, backend. But I don't understand the need for this since I can validated the JWT token provided by frontend using public key even without creating separate client.
So my question is, is the approach of not creating the backend app the wrong approach? Also when & why should we create a backend client in keycloak.
Ref - https://medium.com/devops-dudes/secure-front-end-react-js-and-back-end-node-js-express-rest-api-with-keycloak-daf159f0a94e
I see most of the tutorial of keycloak suggest to create two client in
keycloak i.e. frontend, backend. But I don't understand the need of
this as I can validated JWT token provided by frontend using public
key even without creating separate client.
Typically, such tutorials are created to showcase the authentication and authorization capabilities of Keycloak.
The authentication part is showcased by the user authenticating via the browser (using the frontend client), whereas the authorization part is showcased by the application sending an access token to the Keycloak server where the claims on the access token (e.g., roles) can then be used to infer if the user has the permissions to perform the desire action (i.e., authorization).
So my question is, is approach of not creating backend app is not
right approach?
Depends on your specific use case. Alternatively to the approach that I have previously mentioned, one could have had a single client (i.e, the frontend client), and after the user has successfully authenticated, the application would pass the access token to the backend. The backend could then perform the authorization by directly checking, for instance, the roles in the access token, instead of relying on the Keycloak server to do so. There are pros and cons to both approaches.
Also when & why should we create backend client in keycloak.
A typical example would be if the backend would be a separated micro-service that triggers some maintenance task for example. Assuming that task is not related at all to the user authentication process, it would make more sense to then have a separate client (in this case a confidential one) that would rely on the client credentials flow which is typically used for machine-to-machine use-cases.
We're using Keycloak server for authenticating against several IDPS (google, active directory, etc). We have a spring gateway microservice which plays role of a client and several other microservices which play role of resource servers.
When user authenticates via keycloak, we want to associate the authenticated user with some custom fields (like context, roles, user details) from our custom database (NOT Keycloak DB) and send those fields to other microservices as well, so that we do not need to load the fields from DB in every microservice.
How would you do that? Making a GlobalFilter in the Gateway which would add those fields to request headers and setting those headers somehow to the principal object in resource servers? Or using cache (redis) to store the fields on gateway and load them in resource servers? Or do you have some other solution? For example extending access token, overiding UserDetailsService, etc..
What's important to note is, that we don't want to extends Keycloak Database, since we want to have the whole role management in our custom database. Reason for that is that keycloak schema is not very flexible. We want to use keycloak only as a dummy authentication server.
The preferred option for security related values is for Keycloak to reach out to your APIs or custom data sources at the time of token issuance, then include your domain specific claims in JWT access tokens. In keycloak I believe this is done via a protocol mapper, as in this answer.
This design pattern is discussed in the Claims Best Practices article. It is recommended to not send secure values such as roles in custom headers etc, since they are potentially easier to change by a hostile party. Instead each API should receive the JWT and validate it, in a zero trust manner, then use the received claims for authorization.
For non secure values, such as a session_id or correlation_id used for logging, simple HTTP headers work well.
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.
I have two different client apps written in javascript connecting to two different web api. I am trying to implement identity server 3.
Is it possible to have identity server behind my web api owin
authentication api end point. In other words, is it possible to
route /token endpoint from owin in web api to call /authenticate
endpoint in identity server?
Is it possible to audit log to db in identity server including
failed request along with user's ip and browser agent. Also is it
possible to log user's ip even if i am calling from web api as my
web api is being called by a user using browser?
In my case should i keep two different user base for two different
projects or move all my users to identityserver. If i move all the
user info to identityserver, how am i going to handle all the joins
with other tables in different applications or should i keep a copy
of user with minimum info such as id, email and name?
It makes little sense to first call a web api and deal with authentication during that call.
Your client apps should first redirect the browser to IdentityServer where user would log in and be redirected back to your client app along with either access token (implicit flow) or authorization code (AuthorizationCode flow), depending on the client app having a back-end or not. Then, your client app would make requests to the webapi, passing the access token in the Authorization header.
As for different user bases, one approach might be to implement specific IUserService for each user base and either send a hint about which one to use in the acr_values or tie it to specific clients registered in IdentityService. Again, depending on the requirements.
Is it possible to have identity server behind my web api owin authentication api end point. In other words, is it possible to route /token endpoint from owin in web api to call /authenticate endpoint in identity server?
Yes and no - you cannot reroute those requests, but you can host identityserver in the same application as a web api. In Startup.cs, map a folder to identityserver.
It's not a good idea to do this, first of all, which api of the two will host idsrv? What if that api goes down and takes idsrv with, then the other api does not work anymore.
-> host idsrv separately, make both apis and both javascript apps clients in idsrv, login to idsrv from the javascript apps (=SSO) and use bearer tokens for the api
Is it possible to audit log to db in identity server including failed request along with user's ip and browser agent. Also is it possible to log user's ip even if i am calling from web api as my web api is being called by a user using browser?
Yes, this should be possible, check the logging implementation for idsrv, at the least you should be able to plug in a provider that writes to a database.
In my case should i keep two different user base for two different projects or move all my users to identityserver. If i move all the user info to identityserver, how am i going to handle all the joins with other tables in different applications or should i keep a copy of user with minimum info such as id, email and name?
Idsrv does not need to have all the user info, just an email-address is enough, you can use that as link to the user data in your api databases if you use that as unique identifier.
I am creating a REST inspired API for a Learning Management System. It will expose data such as users, classes, grades, courses etc. I have defined all the resources I want to expose, given them each an endpoint URL, and defined the JSON resource structures that are returned.
I now want to understand how to secure the API using Oauth2 (I don't want to use Oauth1). Am I correct in the assumption that my API will play the part of both the Authorization Server & the Resource Server? Also, what grant type / flow should I be researching?
A lot of the tutorials seem to focus on using Oauth2 to login using facebook credentials etc - but I just want to use it to secure my API and allow my users access to my API (either through a client, or directly). The access permissions for the API should follow the individual users access permissions that are already handled within our system.
Sorry for the scatter-gun questions - I just don't understand oauth2 enough to know where to direct my research. Any help would be greatly appreciated, and any pointers to simple tutorials for the correct use case would be great too.
FYI - The system is built on a LAMP stack using Drupal 6 (old, I know).
Well your assumption is correct the authorization server and the resource server can be on the same server or in the same API.
So how the OAuth2 basically works you have some kind of client(Server, Browser) Authorization API will authorize with Access Token to use your resource API which is then sent in the the Authorization HTTP header on every resource request.
So what I success is that when the user logs in, you identify the user and generate the Access Token immediately to the client. Now you can put some data inside the Access Token e.g. userId, permissions etc. Now when the Access Token hits your resource endpoint you can identify the user and check the permissions. Also you can just make the Access Token dumb so it doesn't contain any data then when you validate it from Authorization API(on Access Token creation you have to store info about the user to Authorization DB), you can get the info you need on the response e.g. userId, permissions etc.
What grant type flow to use, this is basically up to question what kind of clients are using your Authorization API and how secure you want the Authorization to be. E.g. implicit grant is for browser based clients which can handle redirections and e.g. Client Credentials grant is for (server-to-server) communication.
Reference here
To start with, you can use existing providers like WSO2 API Manager for supporting your system. It is well documented and has many REST APIs for this.