Is support for Groups required by the SCIM protocol, and how do you handle it if your application doesn't have the concept of groups? - okta

I'm planning the work necessary to add SCIM support to an application.
I've read the documentation for Okta and OneLogin, as well as the RFCs, but it isn't clear to me if we have to implement the Groups resource. The application doesn't have a concept of groups at all at the moment, and we have no immediate plans to add them.
Do we have to implement the Groups resource? If not, is it be sufficient to just not return Groups from the /ResourceTypes end-point, and exclude groups from the User schema, and the identity provider should then do the right thing?

To not list it on the /ResourceTypes sounds about right. The provisioning service itself might also be configurable to exclude groups independently.
Keep in mind that Resource discovery is considered optional. So to be on the save side, implement a dummy /Groups endpoint that returns 404:
HTTP/1.1 404 Not Found
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"],
"detail":"Resource Type Groups not found",
"status": "404"
}
However, sometimes the groups endpoint is used to represent the role assignments within an application. So if you want to have those being manageable at the central identity provider you might want to consider mapping groups to roles for your application.

Related

Implementing RBAC using okta

Currently our spring boot app uses okta for login. There is a need to implement RBAC for the application so I was trying to see if I can leverage okta itself for mapping users to specific roles.
I would like to implement the standard RBAC model in which I would map multiple permissions under a role and the roles are associated to users. Basically it involves 3 levels permissions > roles > users.
But in okta I don't see the standard way for mapping roles and permissions. RBAC is achieved by creating groups and associating groups to the users, which is two levels. And groups needs to be added as a custom claim.
How do I achieve the standard RBAC mapping(permissions > roles > users) in okta or it's something that needs to handled outside the IDP provider.
Thanks in advance.
Possible Solution:
You can make the scopes (scp in access token) be your permissions. Below are the steps:
In your Authorization Server, create your custom scopes(permissions) and set them as default scopes (this is necessary).
For example create 2 default scopes:
books.read (default=true)
books.write (default=true)
Go to access policies in your Authorization Server create one if none is defined.
Create access policy rules in the access policies page, the rules will be your mapping between groups and scopes.
Test that in Token Preview tab, the trick here is to leave scopes field empty so that the Authorization server can return the default scopes that are set for the user, as explained by Okta:
A default scope will be returned in an access token when the client omits the scope parameter in a token request, provided this scope is allowed as part of the access policy rule.
Now in your application when requesting an authorization code make sure that scope query param is empty.
Depending on the library you are using you may face some issues if by default they are expecting an id_token to be always returned but you will probably be able to customize it. For example: https://github.com/okta/okta-auth-js/issues/827
Solution Limitations:
As mentioned in steps 4 and 5 we are omitting the scope query parameter, this mean that only our custom scopes assigned for the user or his groups will be returned, since the base scopes that are predefined by Okta such as profile, openid, email ... will not be returned. Which also means that we are skipping OIDC which needs the openid scope, so id_token will not be returned and only an access_token will. So this solution assumes that you don't need any of the base scopes predefined by Okta.
In case you need any of the base scopes
As described in the limitations, the solution assumes that you don't need any of the base scopes predefined by Okta. But in case you do then below is a solution that works in that case but not that nice.
When requesting an authorization code in the oauth flow, you need to send the request twice
first one: omit scope query param, so the default scopes are returned.
second one: append the returned scopes returned from the first request to the list of base scopes you wanted such as openid, profile, 'email`. So you would send something like (encoded already)
?scope=books.read%20books.write%20openid%20profile%20email
Disclaimer:
The above solution may not be recommended, but it works. If anyone can find any security issues with the above solution please leave it in the comments.
When you get into the details of roles and permissions, the data tends to be domain specific and to change often. I would advise against trying to manage it in the Authorization Server.
One design pattern that will give you full control over claims is to form a custom AuthenticationPrincipal that includes roles or permissions from your application database(s).
If interested in this pattern, see these resources of mine:
Custom Claims Blog Post
Java Custom Claims Code
How to run Java Code Sample

Spring security user based permission? (not role based)

Assume I have a database composed of user and projects. A user has a one to many relationship with projects. The user can do operations using rest endpoints.
The problem is:
how can I verify that this user owns this resource?
I don't want a malicious user to change an id then suddenly he views another person's project details/images/etc. Think of it like a social media (my app is not a social media but trying to illustrate the issue): where you can view only your images but not another person's images despite having the same "status".
Most spring-security blogs online is using a role based approach. I have no idea what to even search for in this case (tried multiple search queries to no avail).
One option is to run some sort of multijoin query on every resource request/operation till I reach that resource id and check it's owning user to check if it is the logged in user. However, I am not sure if this way is efficient since there are multiple tables in a chain in the real app (could have a lot of joins if I go this way manually; example: user -> project -> tasklist-> ... -> Note; deleting a note would trigger a large chain) or how to make the "authorizer" use it.
what are my options?
In case it matters:
I am using spring-boot + hibernate/JPA + spring-security
Spring Security has the following concepts:
Authentication:
Proving the an actor is who it vouches to be. Authentication is done using credentials, where credentials can take any number of forms - username/password, token, hardware key, etc.
You can set up Spring Security with a set of acceptable authentication providers.
Authorization:
Given an authenticated user, deciding if that user has access to a given resource. Where the resource can be:
An HTTP endpoint.
An Java Method.
A property of an object.
What you want to do here is provide a custom authorization scheme.
You can read about Spring Security's authorization architecture here, including how to set up custom authorization. Once you're ready you might ask specific questions as you go.

Can multi-tenancy in Keycloak be done within a single realm?

First, I'm well aware of the multi-realm approach to multi-tenancy in Keycloak. I've taken over a legacy project where nobody thought of multi-tenancy. Now, two years later, suddenly, the customer needs this feature. Actually, the microservices are prepared for this scenario out-of-the-box.
The customer develops a mobile app that authenticates users via API on our keycloak instance with an account number (as username) and a password. Now, he'd like to add an tenant id to the login information.
The customer wants to avoid using several endpoints as a multi-realm solution would demand.
One first idea was to just concatenate tenant-id and account-id on registration. But that's a smelly approach.
So, my thought was that there may be a way to configure Keycloak in a way that I add a custom tenantid field together with username that acts just like a composite primary key in the database world.
Is such a configuration possible? Is there another way to achieve multi-tenancy behaviour using a single realm?
I can't say for sure, but after some research, I found this:
This website lists all of this together with more information:
https://lists.jboss.org/pipermail/keycloak-user/2017-June/010854.html
Check it out, it may help with your data organization in key-cloak.
Late to the party. But maybe for others who are interested. You could try the keycloak extension keycloak-orgs. I am currently building a test stack with it and I am pleased.
A tenant in keycloak-orgs is an organization. You can map organizations and their roles to token claims with a built-in mapper.
"organizations": {
"5aeb9aeb-97a3-4deb-af9f-516615b59a2d" : {
"name": "foo",
"roles": [ "admin", "viewer" ]
}
}
The extension comes w/ an admin interface. From there you can create organizations and assign users to it. There is also a well-documented REST API on the Phase Two homepage (the company who open-sourced the project).
The maintainers provide a keycloak docker image that has the relevant keycloak extensions installed.
If you want a single realm and singe client that serves many tenants, you can just use custom user attribute and e.g. add key(s) "tenant=MyTenant" and then add a client scope and a mapper to include user attributes that has key=tenant
Then the token will carry the user's tenant(s) and you can use that to filter data, add to newly created data etc.
It's only like 4 steps in Keycloak:
Add User attributes using a key-convention.
Add a Client scope that will represent tenants.
Add a mapper to extract the User attributes.
Add Client scope to the Client in use.
Wrote about it here: https://danielwertheim.se/keycloak-and-multi-tenancy-using-single-realm/

Assigning users to specific resource entities in microservice architecture

Description
Assigning users to a partial list of resource entities to limit access (or visibility) is pretty common (e.g. assigning devices to a user).
Currently we have implemented authorization at the REST API level based on resource (/devices) along with http verbs (GET, POST, etc.) to control read, write access. But, this only allows users to manage either all devices or nothing.
Solution #1
device-service itself maintains user-device associations, and does filtering based on the userId extracted from the auth token on the fly.
Cons: This will introduce dependency between device and account services. Also, we will have to repeat this implemenation for other types of entities in their own services.
Solution #2
Implement user-device associations at the API Gateway level. This way, services simply need to provide filtering by userId which becomes optional to them. There is also no need to extract userId from the auth token.
Cons: This solution burdens the API gateway with association checking.
Is there a better or standard approach to dealing with this kind of resource entity level access control in microservices?

Separate access in one app with keycloak

I have the following setup - the Spring SAAS REST service, which allows different companies to manage different events. And there is a rest client (a mobile app) also, shipped separately for each company.
I want to use keycloak for security stuff, and I have a question of how to separate one company from another.
I need companyA to not be able to access companyB event, and also need different roles within the company - some can create events, some can only read it.
First I thought each company will have own realm created in keycloak, but I learned that realm actually specified in the spring boot REST service parameters like
keycloak.realm=demo-realm
Which means it is only one realm per REST application. And I don't want to configure REST service instance per client. I only want one REST rule them all.
Am I trying to use something which really doesn't fit my use case?
Will it be right way to have a keycloack Group configured for each company, and make a logic in such a way that users of one group won't have access to what is created by other group. But then it actually feels wrong, since as I understand group are supposed to be used in a different way - to have admin group and user group, etc, segregating users "vertically" by "privileges", and not "horizontally".
Can you please suggest a right approach for this problem?
I would implement a custom protocol mapper which loads extra user permissions for your application and stores them in a token. This way, you use a single realm and if there are more companies in the future it scales well. Here you've got an example of how to implement it.
Basically, the otherClaims field of the access token is a JSON field that allows a map of properties to be set. You could add a field here such as:
userAccessibleCompanyIds: [1,3,4]
How to load the company ids for the concrete user? You can access your application database from the mapper or get them using the REST API.
Then in your application you need to have a control of what the user accesses. What I do is decode the token and see if the user request suits. If not, return a 403 response.

Resources