user setup in keycloak with organization information - keycloak

I am looking for best recommended approach to create / manage users with organization name and id in Keycloak ( through a html form )
I read following documentation but cannot find a straight forward way to manage users there with organization name and Org id.
https://www.keycloak.org/docs/latest/authorization_services/
The approach that i used was using a custom attributes but i am not sure if that is the recommened approach or not.
Step-1, For every user create a custom attribute "OrgId" with value unique to that organization lets say 1.
Step-2, For the Client, that the user belongs to, define a protocol mapper "OrgId"
Step-3, Create a table for Organziation into our system, add an Organization entry there when first user for that organization is created.
Problem i am trying to solve: We need to keep track of various actions that users belongs to an organization is doing, such as we need to keep track which organization bought what type of products from our system

Related

Keycloak: Optimal Approach for Managing User Heirarchies and Child Groups(Teams)

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.

How should I handle parent and child users in my Postgres db design?

I'm building a platform targeted to kids with an optional parent sign up. Regular users can access the full platform experience while parent users can only access a parent dashboard to create their child's account, manage it, and see activity from their child.
Parent accounts will never become users. If they want to be a regular user they must make a separate user account.
Two ways I can create this:
A single users table with an account_type column. This is what I currently have.
Separate tables, users and parents, as well as an accounts table that has a one-to-one mapping to either (for things like email, password hash, etc.).
#2 seems like the better longterm solution. The pros are that I can evolve the two separately, and the cons are that basic user queries become slightly more complicated.
Any thoughts or recommendations on these two approaches?
Why don't you just use a role based user maangement.
you will have user, role models.
In user model you will have a column roleid having a object-type-relationship[one-to-one] with role model.
Now, in your user model you will give the permission to parent user (role account) to create a child user (role account).
ask me if you need further explanation.

oData, Yii2, and Dynamic Objects

We have a system built on dynamic objects - so there is a metadata table that describes these objects. For example - Organization A can have a Warehouse Object, a Client Object and a Sales Object. Organization B can have a Sales Object and a Clown Object.
Users authenticate to our rest api built on the Yii2 framework. They authenticate using a call to /user/authenticate and then they query for objects using /object/ for list / create and /object// for Read, Update, Delete.
The issue with this is: If a developer is going to integrate into the service, they would need to know all objects that have been defined in their organization including available fields they are able to read/write to. What we would like to do is provide an option to describe our data.
E.g. My initial thought would be to expose something like /object/metadata in which I would respond with a json list of resources that the user is allowed to access e.g. a Warehouse A user would see Warehouse, Client, Sale. Where a Org B user would see Sales, Clown.
I have been asked to take a look at oData as a specification for this but oData seems to define a whole convention of things (url, searching and filtering etc).
Does it make sense to implement part of the oData Spec or use it as a guide and keep our URLs the same?
Is there a part of the oData spec that would lend itself to the describing of a dynamic resource (e.g. if the user uses our system to add a column to the Sales object - the api should reflect that).
Would appreciate any thoughts on how to design / proceed with this requirement.
Thank you!
I created follow solution:
extend dektrium/yii2-rbac, where to assigments add column company
in each module (werhause, invoices,..) created roles objects
roles object has methods: canAssign(), canView(), canRemove() for user administartion
user administration panel collect all roles from all modules (scan as files) and display grouped by modules.
This solution allow to user switching between companies and for users assign different access rights to different companies and control user manager rights assigning rights

How to unable backend Customer Module for several users?

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.

Should I have multiple views/endpoints of a resource in a RESTful service?

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.