I scrolled through the documentation of KeyCloak and also set it on my machine to explore.
I also explored fine-grained permissions however I didn't get much detail in documentation around the n-level of nested hierarchies.
Here https://www.keycloak.org/docs/latest/server_admin/ this talks about limiting an admin user to particular client management, however, I want certain users, within the client, to be able to create accounts but with scopes and attributes limited to what's assigned to themselves.
For an example:
For a client(ERP>Transactions) we want to create an Org(our customer) Admin who in return will create teams and team admins. Team admins shall be able to invite their teammates in there.
Now I just want to know if only Keycloak can be used to make sure a user in one Org shouldn't be able to create a user in some other org, in the same way, a team admin shouldn't be able to onboard/invite a user in some other team.
Because if Keycloak in principle can't handle this, our team will start writing custom logic in our application code base for this.
Related
I have a tenant admin account for a SharePoint online tenant. I am tasked with looking at all the sites on the tenant and all the SharePoint groups on each site. Getting a list of sites is easy using PNP libraries (Get-PnPTenantSite). My next step is to loop through each site and get all the security groups associated with each site - also easy using Get-PnPGroup commandlet.
The problem I'm running into is that my tenant admin is not added to some sites - not Site Admin, Not Site Owner, not even Site Reader - and so when my script executes against one of these sites, I'm getting a 403 Forbidden when asking for the groups on the site. Yes, I could avoid this by just adding my tenant admin as an owner on every single site in the tenant, and could probably even do this using a fairly simple powershell script.
However, my question is, why is this necessary? Shouldn't I be able to just run a script with some kind of "tenant admin super-read-permissions" or something that will just temporarily give me all access to everything without having to go through the middle step of adding myself everywhere?
Depending on the needs of your business with SharePoint, it may seem like an unnecessary or extra layer of security. After all, why not allow an administrator to access all the things?
The answer lies in the fact that SharePoint security is designed to allow separation of roles. These roles may not necessarily match exactly how responsibilities are defined in your company.
From Microsoft:
Global Administrators and SharePoint Administrators don't have
automatic access to all sites and each user's OneDrive, but they can
give themselves access to any site or OneDrive.
See https://learn.microsoft.com/en-us/sharepoint/sharepoint-admin-role
Tenant admins have several responsibilities:
Create sites
Delete sites
Manage sharing settings at the organization level
Add and remove site admins
Manage site storage limits
To perform these responsibilities, very little access to the actual sites and their content is required.
Management of access to a site collection and its content is the responsibility of the site collection administrator and site owners.
It sounds like in your company, you wear both hats. You might be creating and deleting sites, and also getting involved in access control or auditing at the site collection level. In these cases, you must use the privilege of the tenant admin (e.g., add and remove site admins) to grant yourself the site collection privileges required to access the information you need.
I recommend not granting yourself these privileges forever. It is helpful to consider that having constant administrative access to all sites is undesirable for a few reasons. For instance:
Search is supposed to be filtered to content that is relevant to the user. If the user is an admin with access to all content, search will not be filtered in a useful way.
While an administrator may certainly grant themselves access to a site, some collaborators would prefer that their content remain private to their team until or unless they require technical support.
All of this addresses the "why" part of your question. As for the technical question, there is currently no "tenant admin super-read-permissions" role that you can use for the data you want to collect.
I have 2 users, one with less than 30 roles and one with 400 roles. When I login with the 30 role user, I can reach the redirect URL without issues. But when I log in with the 400 role user, the request to the redirect URL doesn't complete. If I reduce the number of roles in the 400 role user then it will work. So, is there a way to disable passing roles in the java access token or increase some limit somewhere that's causing the failure?
I would suggest to focus rather on roles reduction/optimization than forcing the transmission (raising limits) over the maximum number of roles inside tokens (or anywhere else).
Some interesting questions (among others) to start with:
Which protected resources am I going to serve?
What am I trying to protect? and what are the associated risks? (build a Threat Model)
How do resources are served by each application? and how are they distributed among my applications?
What kind of resources are they? How can I group them? Which sets are identifiable? or what are the relationships between them? What actions are possible against all sets of resources?
Who are the users of each application? How will they interact with my resources? Which flows are sensitive?
What roles can I define for all my resources?
Which role can apply to each application, resource type or set?
What kind of user groups can I create?
Do I need additional attributes or claims for each set of roles or users/groups?
I firmly believe that if you answer all these questions you will end up having a bunch of roles instead of hundreds. Think security by design and follow principle of least privilege.
Focus on your use case
Now as far as I understand, your blocking point is that you are assuming that each resource is unique, sensitive and requires its own permissions, and consequently a role definition. While it may be true in some cases, in most other cases it does not mean that you have to use the token roles/scopes/claims to secure your assets deep at the resource-level. I'll try to illustrate this sentence by an example.
RBAC and authorizations example for your use case
Let's assume that:
you have millions of sensitive resources to serve
each registered user of your application has access to a (different) set of these resources.
your resources are splitted into, say, 3 categories (e-books, videos, musics).
each resource can be downloaded, uploaded, deleted.
your application will meet unregistered users, registered users, contributors and administrators
registered users will always have read access to resources (not a single action will ever allow a modification)
contributors are particular registered users who can perform special actions including modification ('upload', 'edit')
contributors and administrators may have access to various administrative parts of the application
your application will evolve by serving additional categories of resources in the future and new actions will be available to users later (such as 'flag', 'edit' or 'share link').
Then first things first:
organize your resources accordingly by serving them behind categorized paths such as: .../myapp/res/ebooks, .../myapp/res/videos, .../myapp/res/musics
identify your resources via UUID such that a resource may look like: .../myapp/res/ebooks/duz7327abdhgsd95a
Now imagine that your business risks or at least the greatest risks you wish to avoid are:
unregistered users having gaining access or rights for any part of the application or resource
uncontrolled registration process (robots, spam, no mail verification, fake users, ...)
registered users gaining illegal privileges (unauthorized actions, access to other categories, illegal administrative rights)
discovery of available resources by any mean
You will note that I voluntarily didn't listed:
registered user having illegal access to certain resources. For example: maliciously pointed/provided by an existing user.
This is because it is not a high risk as you may hold contact information about registered users as well as log activity and actions, quota or requests throttling, and you may be able to ban them or start legal action against them. Your registration process is also assumed robust and secure. Nonetheless if its considered a critical risk you can address this with extra mechanisms (cf. suggestions at the end). But never will it result in adding extra roles, such as one per resource, as it does not fit in any security model.
That being said, finally, here are the roles and authorizations scheme you may come with:
SCOPE / AUDIENCE
MY_APP
ROLES
USER
CONTRIBUTOR
ADMINISTRATOR
CLAIMS / ATTRIBUTES
CATEGORIES
ACTIONS
--> POSSIBLE USER GROUPS
USERS
Roles: USER
Claims: CATEGORIES(variable), ACTIONS('download')
CONTRIBUTORS
Roles: USER, CONTRIBUTOR
Claims: CATERGORIES(variable), ACTIONS('download', 'upload', 'edit')
ADMINISTRATORS
Roles: USER, CONTRIBUTOR, ADMINISTRATOR
Claims: CATEGORIES(*), ACTIONS(*)
Following this model, assigning the correct group to each registered user will provide high-grade security by mitigating/controlling the main risks. As claims/attributes are defined in the token(s) (managed and signed by Keycloak) then you can trust this information in your application and serve your resources accordingly and safely. There is also no risk of illegal access or discovery of resources as you are using UUIDs, only registered users having had access once to a resource will know it and registration with appropriate category access will be needed for another user to access it (to only be able to read it basically). Of course you may store in a database the list of resources to which each user has access to, raising the overall security to a very high level.
However, if the latest is not enough you may also implement rolling UUIDs or temporary links for your resources when served to users. To go farther you may also define groups and masks for your categories, resources and actions.
In fine, in this example I made use exclusively of token claims to define roles (common claim), categories and actions (custom claims). In terms of security the authentication and identity will be the first-line security followed by roles then categories, actions and stored list of resources per user (db).
Other alternatives are obviously possible, its just an example. Still, I hope it helps!
To fix this problem you should start from defining client scope mappings for each of you applications (e.g. oidc clients). Main idea of this facility is that even if your user is super duper admin with all existing roles, all of his roles actually don't required for any particular application. For example client foo which defines following roles:
foo_user
foo_viewer
to perform its security logic need to know only whether currently logged user has foo_user or foo_viewer, but it doesn't care about has this user roles bar_user or bar_admin from application bar. So our goal is to make Keycloak return for any client access token with only valuable set of roles for this client. And roles scope mappings is you friend here. You can set for client foo scope like:
foo.foo_user
foo.foo_viewer
bar.bar_admin
and now even if logged user has role "bar.bar_admin" this will not go to access_token since client foo doesn't take this role into account. After applying some scope settings you can test them at 'Clients -> $CLIENT_OIDC_ID -> Client scopes tab -> Evaluate sub tab.
As for you case with 400 roles, i'm quite confident that none of your application requires all of 400 roles, so precise scope configuration for you apllications can drammatically reduce access token size.
But if i'm mistaken and you really have an application that rely on large amount of roles you should look into you runtime settings.
For example if you run keycloak behind reverse proxy like nginx large tokens may not fit in default HTTP parameters buffer size (afaik about 2-4kb) so you have to increase it via appropriate nginx configuration option. Another example is tomcat which has about 16kb as default HTTP header buffer, so if you send request with very large access token in Authorization header Tomcat may not handle this request properly.
I have developed a web application with following architecture:
Frontend : Angular 6
Backend : Java REST APIs with Springboot
I want to add authentication and authorization to it. For that I'm looking for some open source application (e.g. KeyCloak, Gluu etc.). I would like to know in which tool the below scenarios are supported.
There will be predefined set of Activities on UI (e.g. Add, Edit,
Delete etc)
There will be predefined Access Levels (e.g. Read, Write, No Access)
I should be able to create Roles, then assign activities and access levels to those roles and assign those roles to user.
Can you please help me to find out a tool which supports my above scenario?
I tried something for KeyCloak, but i couldn't find a way to add activities, access levels and map roles to it. I think everything there is governed by Role only.
I just realized that I need Activity based authorization and not Role based authorization. Please help me find some tool for that.
I'm not sure what is meant by activity based authorization but i suspect you actually mean permission based authorization, in example: Grant permissions to users to perform certain actions.
Shiro offers you permissions and role based authorization out of the box.
You can create roles, add permissions to these roles and assign them to a user. Supported are implicit and explicit roles, whereas one role can hold any number of permissions. You can even work with wildcards and group the permissions.
For more information you should take a look at the official Shiro entry and especially the web documentation for your project in particular. Shiro offers full support for Spring-Boot applications, you can find a HowTo here.
Shiro fully supports your described scenario.
I'm working with Shopware.
I've added a new attribute "proxy" to the s_core_auth table for each user in order to show the ability to get access to the Customer Module in the backend, so that if a user is not selected as "proxy" he/she won't be able to make changes in that module.
I need help to understand what I need to write in my plugin's code (maybe having only a Subscriber file.)
I'll be very grateful!
Adding a custom column to the s_core_auth table is not a good idea. What you're trying to achieve can be done with user groups and group rights. From the Shopware Documentation:
With User administration you are able to create new users in the backend and control access rights to areas, modules and plugins in accordance with certain group policies that you define per ACL (Access Control List). Within the ACL you have the possibility to control precisely which user is able to perform which activity. Thus, it is possible to assign certain reader rights to an administration group without granting them authorization to edit or delete.
You can find instructions for User administration inside the Documentation.
Let's say I'm creating a RESTful service to handle orders for my warehouse over the web.
I want to allow customers to create accounts
I want a customer admin to be able to create accounts for other users in their office
I want to allow customer users to create orders
I want a site administrator to be able to create and manage all customer accounts
I want a site administrator to be able to create and manage all users
I want a site administrator to be able to create and manage all orders
Given these requirements. My initial thoughts are to design endpoints in this manner.
# to request a new customer account
/customers/request {POST}
# create and view customers - limited to admins
/customers {GET, POST}
# view customer info, update a customer
/customers/{customer_id} {GET, PATCH}
# create and view orders for a customer
/customers/{customer_id}/orders {GET, POST}
# view and update order for a customer
/customers/{customer_id}/orders/{order_id} {GET, PATCH}
I feel pretty confident that those path's make sense and follow the general restful ideas. However, I'm not sure how to handle the users endpoint. The problem is, I want customer admins to be able to create users that can use their customer account to create orders. Where do customer admins POST to to accomplish this? I had a couple of ideas.
Following this answer, I thought about this.
# creation of users always done through this endpoint no matter what the
# authenticated user's role is
/users { GET, POST }
# associate user with customer
/customers/{customer_id}/user_memberships { GET, POST }
The problem with this approach is how does the admin of the customer account get the ID of the user to associate with the customer account. Any GET request on /users would be filtered by retrieving only users who are part of their customer account. However, because the user would be created before the membership, they would never be able to view the user.
I also though about just having two endpoints to create users.
# create a user for a customer account
/customers/{customer_id}/users {GET, POST}
# root users endpoint only accessible to admins
/users {GET, POST}
# return same user
/users/1
/customers/{customer_id}/users/1
It essentially boils down to using the customer url prefix as a means of authorization. It seems a little strange to have two endpoints invalidating the other. What if the root endpoints were only views of the subresource endpoints?
# view all users in system - admin only
/users {GET}
# create & view admin users
/admin/users {GET, POST}
# create internal office users
/locations/{location_id}/users { GET, POST }
# create customer users
/customers/{customer_id}/users { GET, POST }
In this case, we could still cache GET responses on the sub resources as they would not change unless there was a POST or PATCH/DELETE on the specific id of a subresource.
This style also seems to make sense for orders. Admins can view all orders even though they technically belong to a customer.
# admin can view all orders
/orders?customer_id=1234
/orders
I kind of like the idea of the root resource being a view of subresources allowing for easier authorization based on the url.
So, I guess after all of that, my real question is:
Is having multiple endpoints representing the same resource a problem even if one of them is just an aggregate view of the subresources and does not permit the creation of a resource through that endpoint?
You shouldn't mix the design of your API, REST principles, and the need for authorization. You should design your API in a way that makes it:
easy to use
easy to maintain
easy to understand
A RESTful approach to API design tries to address these different concerns. A RESTful approach is about identifying the objects you have, their state, and their possible transition.
And that's where it stops. Now, you wonder about authorization. You want to be able to control what a user can do on given records depending on who the user is (an administrator, a customer,...) and what the targeted resource is (a customer record...).
What you need to do is deploy an authorization framework on top of your REST API in a loosely-coupled way. In other words, you want to externalize authorization. You definitely not want to build authorization straight into your API. Imagine that suddenly you have new authorization rules / constraints: you would have to recode your API. In doing so you'd break all the clients. That would lead to poor user experience.
So, we've identified you need to externalize authorization. Great. What are the different ways to do so? This depends on the language and framework you use.
You can use:
Spring Security in Java
Yii in PHP
CanCan in Ruby
... and many more
You could also implement your own filters, for instance a Servlet filter in Java in front of your REST endpoints.
Lastly, you can turn to a full-blown attribute-based authorization model based on XACML. There are several open-source and vendor alternatives. If you are not familiar with attribute-based access control or XACML, have a look at the following links:
ABAC explained by NIST
XACML
With XACML, you define policies centrally e.g:
Administrators can view all customer accounts
Administrators can modify a customer account he/she is assigned to
Customers can view and edit their own account only
The policies are then evaluated in an authorization service (in XACML that's known as a policy decision point). The authorization service exposes a binary authorization API which your API can call out to: can user Alice view record foo?.
Using externalized authorization based on policies and using XACML, you achieve a loose coupling between your business logic (your business API) and the authorization logic which you can more easily maintain and update.
According to my understanding, for ex. u want that for particular customerId you want that this customer only view its users not will be able to create its user which will only be created by admin, so this can be done using spring security as well and this definitely creates the problem so u have to categorize the customer according to your requirement.