Setting permissions in Keycloak - permissions

I want to create role-based access control system using Keycloak's authorizaion system.
I'm using OAuth 2.0 in microservice architecture and faced the following problem: I have records with unique IDs (they are rooted to other entities) and what I want to achieve is that only certain users or a group of users can see (modify) entries with these IDs.
And I would like to be able to explicitly bind users (or groups) to these IDs (and it is possible to receive them in JWT for example).
How could this problem be solved using Keycloak and what best practices to do this?
Perhaps I misunderstood something and this problem can be solved in another way?
Thanks in advance!

There are 2 ways to handle this:
1. Using Client roles:
i) ie. create some set of pre-defined roles (viewer, admin, editor, etc).
ii) Now whenever your IDs are generated, then generate one client in keycloak and assign any of above roles.
iii) in JWT, it will be visible in path :
"resource_access" --> <CLIENT_IDs> --> "roles": [your defined roles]
Then, in service layer can autorised using granted Authority or by roles-group.
2. Using Realm roles:
i) in JWT: this will be fetched from path: "realm_access"-> "roles":[your defined roles].
If you have only 2 roles (eg: admin and viewer), then 2nd option would be preferred.
Let me know if this helps. :)

Related

Blazor Authentication via existing database table

I want to build a Blazor server application that has user authentication. The only experience I have with Blazor was a simple app for work that used AD authentication and made various api calls to get the data necessary.
I have an existing sql table containing: userId, username, permissionLevel
Basically I want to be able to make a new table with the username and a hashed password that when matched will return an object containing userid, username, and permissionlevel that will be used for authentication in the Blazor server app.
Is this possible and are there any resources pointing me in the right direction for this? I have searched but have not come up with anything I am looking for. I am looking for examples of how to display certain options based on PermissionLevel.
Blazor Server supports Policy based authorization (https://learn.microsoft.com/en-us/aspnet/core/blazor/security/?view=aspnetcore-6.0#authorize-attribute) - Example:
#page "/"
#attribute [Authorize(Policy = "PermissionLevel.5")]
<p>You can only see this if you satisfy the 'PermissionLevel.5' policy.</p>
You can register all policies (PermissionLevels) in Startup.cs, example:
services.AddAuthorization(options =>
{
options.AddPolicy("PermissionLevel.5",
policy => policy.RequireClaim("Permission", "PermissionLevel.5"));
});
Unlike with Role based authorization, only a single policy can be applied inside any Authorize attribute, or AuthorizeView component. You can however evaluate multiple requirements for a single policy (such as if PermissionLevel must be '5' or higher) by customising your own AuthorizationHandler (see MS Docs for some good examples: https://learn.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-6.0#use-a-handler-for-multiple-requirements - You can also refer to my last link below for a detailed example using Role Claims, by #pacificoder).
If you use ASP.NET Identity (such as with a Blazor Project's Individual User Accounts), the AspNetUserClaims table is created for you (see https://learn.microsoft.com/en-us/aspnet/core/security/authentication/customize-identity-model?view=aspnetcore-6.0#entity-types), which contains all the user-claim pairs. Claims can be assigned to users during runtime by using UserManager.AddClaimAsync().
This would be sufficient if you do not have many claims - However the more permissions and roles a user has, the larger the access token becomes (and you could get an "Access token must not be longer than 4K" error - I started getting this after adding 5+ claims to a role, but not sure how easy it is to exceed 4K with user claims only...).
If you consider using Policy-based authorization, I would recommend taking a look at this answer by #pacificoder: https://stackoverflow.com/a/49539930/13678817 - Although this relates to Role based policies, the same approach can be used for user based policies, and I also liked the way Enums are used to create and add all the permissions/policies.

Vault OIDC with google, how to restrict roles to specific groups

I installed a vault and configured OIDC with gsuite, that was already an adventure in itself as the documentation is limited and even wrong at more than one place.
Finally I have a working authentication with my google accounts and I began to create roles, and there I saw a huge issue. How do you restrict google users from using a role. Let's say I create a gsuite-admin role that has access to all of vault administration, any user entering the role before login can assume it.
I tried to use the different claims but those seems to be only for vault created groups or other things.
Does anyone has a solution for that?
Thank you in advance.
EDIT:
The configuration I'm using whith group claims:
{
“allowed_redirect_uris”: “https://URL/ui/vault/auth/oidc/oidc/callback,http://localhost:8250/oidc/callback”,
“user_claim”: “sub”,
“policies”: “vault_admin”,
“ttl”: “24h”,
“groups_claim”: “devops”,
“oidc_scopes”: “profile”,
“bound_claims”: {
“group”: [“devops”]
}
}
That configuration only provides a lock of the role that can't be used anymore by anyone. From what I could see the JWT doesn't have any informations and that is why we used the config with the fetchgroup option in the oidc configuration.
I found a solution for this problem. Firstly, we need to ensure that a user is part of a G Suite group. Then mapping the G Suite group with Vault group (that has a policy assigned) ensures that the user is bound to the Vault policy.
This article contains some example steps and might be helpful.

Permission linking between LDAP users groups and Django permissions (custom if possible)

Hello again every one,
I have a question: I successfully implemented django-auth-ldap, the LDAP users can request successfully my DRF API. But nows, for my projetc needs, I have to define permissions depending of the group.
Indeed, I will have like 12 groups in my app. Depending of the group, I will authorize or not the user to request a given route, BUT even if I defined the global var AUTH_LDAP_MIRROR_GROUPS = True, and saw in my database the are linked to a group (see capture):
Users in database
Groups from LDAP inserted in db thx to django-auth_ldap settings
User linked to the groups defined
But now, I have some other problems: I do not know how to implement permissions depending of the group the user belong. In fact, if a user belong to the group ServerAdministrator, I want to allow him to access to every route accessible, but I dont know where to see this in the received request in my view?
As I understood, I should implement custom permissions I should write programmatically in a User object (which should inherit from django AbstractUser)
If yes, How does it work? Should I empty my whole Database and then let django-auth-ldap insert users and it also will create the given permissions defined inside the database?
Maybe it is not clear, do not hesitate to ask questions if I can be more precise.
Kind regards.
Benjamin

How limit user's access to a certain resource?

Suppose that I have a web application. Consider it like a Black-Box for now. I want to use a backend system to limit what a user can view/do on the app.
i.e. Sample users can only do three functions, Premium users can do 10 functions and see more pictures.
What is the best way to do it?
I'm trying to using WSO2 Identity Server, but it doesn't offer this functionality. So I've thought that maybe I can integrate it with the WSO2 API Manager and make an API that limits users' access to a certain resource. But really I cannot find if it's possible do it. Anyone know it?
Please refer to : https://docs.wso2.com/display/IS530/Access+Control+Concepts
1) WSO2IS can act as a coarse grained access manager. Your application will act as a fine grained access mnager.
It means that roles can be defined in WSO2IS, managed and assigned to user. From there Roles assigned to one user can be provided as clains with the identity token generated by WSO2IS and sent to the application.
The application, on the other side, will manage roles to permissions links.
Access control is then done at each request by the application, based on the roles presented in the Identity Token by the user and the Permissions grid based on roles in the application.
2) The access control at the application is a business logic you must implement (or at least configure if it a COTS). It is possible to outsource this logic to WSO2IS as policies on attribute (with Workflows).
Please look at : https://docs.wso2.com/display/IS530/XACML+Architecture
Jeff

how to configure multiple users to access multiple ressources with different rights?

I'm working on a project where I've multiple ressources and multiple users, what I need to do is to associate different access rignts to every user depending on the ressource he wants to access to
The problem is that a simple LDAP server can't implement this kind of situation,
An idea is to use multiple LDAP servers, one for each ressource, then how could I manage them all?
Or is there another authentication process I can use in this case?
Spring Security has a special ACL module to handle such situations. The basic idea is that each domain object / ressource may have separate access control list. You need to fill this list with appropriate permissions and add corresponding checks in your code. You can have parent -> child relations between the objects to reduce number of permissions. Check it out.
If you have logic behind the access to the resources, you may want to use a rules authorization language such as XACML.
If the assignment of resources to users is arbitrary then the use of ACLs with Spring Security's ACL module is good enough.
The problem is that a simple LDAP server can't implement this kind of situation
Mine does. You use LDAP to define the roles associated with each user, then you use web.xml to associate the resources with the roles that are required to access them, then you configure/write your login module such that it looks up the roles of each user when you login. Container-managed security can do all that.