How to set a default group on an Identity Provider in Keycloak - oauth

In Keycloak, is there a way to assign users to a default group when those user sign in over an Identity Provider?
Note: This already works with roles. E.g. navigate to Identity Provider → select Provider → Mappers → New → Hardcoded Role → select Role → Save. However, such a Mapper seems to be missing for selecting groups.
Any ideas on how to achieve this?

One would aspect that such Mapper would exists, but unfortunately until the most recent version it does not. However, aside from extending and creating your own mapper, you can do the following workaround:
Navigate to the identity provider configuration;
Select the IDP;
Go to Mappers and click in create;
As Mapper Type select Advanced Claim to Group
Add a Key and Value claims that you know will always be present in all the tokens coming from the IDP, regardless of the user;
For example, 'exp' as a key, and '*' has the value. For this particular example, you would need to enable the 'Regex Claim Values' option;
In the field Group select the group to be automatically added by default to all users coming the external IDP;
Click on save.
If you login via the external IDP with a given user, you should see that the user belongs to the group that you have set. To check that, go to users > select the desire user > Tab Groups.

I don't know for other Keycloak versions, but on version 16.1.x the Hardcoded Group mapper doesn't exist. Nor do the Advanced Claim to Role/Group mappers for certain IDP providers (for Google for example). The "Advanced Claim..." mappers are available for the OIDC type IDP providers though.

Related

Identity Server - Multiple users with different access levels on different accounts

My application is composed of an API layer which is accessable by presenting a Bearer Token, obtained from our Identity Server. Each of our API has a level of scopes that the token must contain in order to be invoked: this means, for example, that if you want to make the API call which "creates a product" you need a write access to products (i.e. the scope "products") while you may just need the scope "products_read" if you only want to retrieve them.
Scopes are bound into the token when you authenticate onto the ID server.
Now, I need this user to be able to perform different operations on different "workspaces". Each workspace administrator can set which permissions each user have. This is, in fact, linked to the scopes that each user will have when operating on that particular workspace.
Right now we have implemented that, if you are trying to access a different workspace, the API layer will check:
if your bearer token is valid (by validating it on the ID server)
if you are authorized to access that workspace
changing associated claims by removing the original "scopes" (set into the token by the ID server) and overwriting with those assigned by the administrator of that workspace
This somehow works, but it stinks because I don't want my application layer (API) to have this kind of responsability and the opportunity to tamper with the token. I want the ID server to handle it and, after the user tries to enter into a different workspace, it generates a new crafted bearer token with correct claims (so the API will just need to trust it).
What's the best approach in doing that? I'm digging into the "custom grant type": may this be the right approach?
Scopes are fixed at design time and the same for all users. I like your use of products and products_read - that is very standard.
When you need dynamic behaviour, implement claims, which depend on who the user is. In your case I would use a workspaces array claim. Since this is a key vaue for authorization, it should be added to access tokens at the time of token issuance. Think in terms of your products scope being composed of claims.
It feels like workspaces and other permissions are part of your business data rather than your identity data. At the time of token issuance, IdentityServer should send identity attributes (eg subject claim) to an API endpoint you provide. which returns business attributes (workspaces). I believe in IdentityServer this is done via a custom profile service.
I'd try to avoid different tokens for different workspaces, since that will be awkward in terms of usability and code complexity. The standard way to do it would be to redirect the user each time.

Jenkins LDAP authentication for specific group members

I need to setup authentication for our Jenkins via LDAP (AD). I was able to setup the authentication on a wide scale but I have to narrow it down to a certain members of a group and my LDAP filtering fails here.
This is the full DN that I want to target:
CN=jenkinsgroup,OU=App1,OU=Applications,OU=CompanyGroup,OU=Company,DC=my,DC=domain,DC=com
In the jenkinsgroup group I have the users stored as member attributes, only they should get access.
Jenkins LDAP plugin offers these fields:
Jenkis configuration
I'm not sure whether I should use a filter in on the User or the Group field, or which objectClass or category should I use for member attribute - I tried user and member as well.
Error message I get:
User lookup: user "username" does not exist.
Does the Manager Dn have permissions to perform user lookup?
Are the user search base and user search filter settings correct?
LDAP Group lookup: could not verify.
Please try with a user that is a member of at least one LDAP group.
Without the filtering, I can authenticate with a user from the group and it also confirms me its membership.
So I'm confused about how the write the proper query.
Thanks in advance!
As EricLavault commented:
(&(sAMAccountName={0})(memberOf=CN=jenkinsgroup,OU=App1,OU=Applications,OU=CompanyGroup,OU=Company,DC=my,DC=domain,DC=com))
I used this as the user search filter and worked.

How to return specific scope according to given user role in Curity

Given :
a oauth client using Authorization code flow used by a website to fetch resources from an API located behind a Reverse Proxy,
some users with differents roles (admin & customer) defined in the roles part of the SCIM 2.0 User schema in Curity
a custom claim 'roles' based on the 'roles[]' field retrieve from the account-manager-claims-provider
two scopes (product_read & product_write)
How can we attached the right scope based on a given role for an unique client in Curity to get :
the product_read scope for all users with 'customer' role
the product_write scope for all users with 'admin' role
Curity docs or videos talk about custom mapper for claims, but it seems there is no example of procedure to dynamically verify which scopes must be attached to a token based on the role of an authenticated user.
I'm looking for an answer dedicated to Curity.io solution and the recommanded best practices to adapte scopes based on a given user role in a web app using RBAC, to secure the calls to the APIs during the user journey.
This type of scenario is usually managed as follows:
Scopes are application level privileges set at design time, and are requested before the user is known
Claims are identifiers with user specific values set at runtime, once the user has been identified
MULTIPLE ROLES APP DESIGN
Personally I would look to model the authorization around the mainstream use case:
Customers can buy things and look at products, and this constitutes the majority of app usage
There is an internal admin operation to update products, which is an exception
This might lead to the following API authorization code:
updateProduct(input: Product) {
if (!this.hasScope('product') || !this.hasRole('admin')) {
throw new ForbiddenError();
}
this.repository.updateProduct(input);
}
I think my personal preference for your use case would be to use the below values:
Scope: product_read
Claim: (role=customer)
You may prefer to call this scope product or product_write. It is true to say that the app has scope to a product but that exact permissions are not known until the user's claims are identified.
APP PER ROLE DESIGN
At one previous company we used to design separate apps for each persona, since the security and UX effort sometimes varied between the two cases:
The main internet app for customers, with scope=product_read
An internal UI for administrators, with scope=product_write
If this made sense for you at some future point, I think my suggested scope would translate nicely.

Using Spring Security authorization with context-specific authorities

We need to add access control to our application, making sure that every command is performed by a user who has the proper authorities for the given domain objects. We are already using Spring Security 4.0 for authentication and intend to use it for authorization as well.
What makes this complex is the way that authorities are granted to a given user. In our problem space, a User can found several Companies and hire other Users, making them Employees. Each User can be an Employee of several Companies. Some authorities can be granted to a User directly (e.g. canResetOtherUserPassword); other authorities can also be granted by a Company to an Employee based on their Role in the Company (e.g. canOpenProject, canRenameProject). When performing Company-independent commands, User-specific authorities must be checked by the service layer. When performing Company-specific commands (e.g. open a project for a company, rename an existing project), Employee-specific authorities must be checked.
Now let's consider these last two commands, which would have the following service signatures:
long openProject(long companyId, String title)
void renameProject(long projectId, String title)
To control access for the 1st method, the authorization component could retrieve the acting User through the thread-local SecurityContext.authentication, retrieve the Company using the companyId parameter, retrieve the Employee corresponding to the current User, then match Employee-specific authorities against the required canOpenProject authority.
To control access for the 2nd method, the authorization component could again retrieve the acting User through the Thread-local SecurityContext.authentication, retrieve the Project using the projectId, retrieve the owner Company through project.ownerCompanyId, retrieve the Employee corresponding to the current User, then match Employee-specific authorities against the required canRenameProject.
Clearly, this can be done using procedural code, as I just described. We would prefer to use a declarative approach similar to the #PreAuthorize interceptor that Spring Security already offers, and obviously to write as little code as possible. We just don't know where to start.
Any ideas?
Thanks in advance!
You can implement UserDetails (org.springframework.security.core.userdetails.UserDetails) or just extend a default implementation of UserDetails, like User (org.springframework.security.core.userdetails.User) ---> CustomUserDetails with additional attributes like company (with getters).
finally : use simply #PreAuthorize("principal.company.companyId == #companyId")
Reference : Spring Security 3.1 chapter 10 (you need to go back to chapter 3 for UserDetails implementation)
It was very useful for me !

How to make Jenkins hide logs, history, etc on front page?

I want to remove all changes, workspace links and logs from Jenkins front page.
I do not want unauthorized people, bots, etc to have access to this kind of information.
How can I do that?
Set up your permissions to not allow unauthorized access
WARNING:
Make sure you have your own user/admin setup will all permission, otherwise you risk locking yourself out. If you do, use information here to reset [thanks Alex]
To configure anonymous users to not see anything:
Go to Manage Jenkins
Click Configure System/Configure Global Security (depending on your Jenkins/Hudson configuration)
Under Access Control -> Security Realm, you should have either Matrix-based security or Project-based Matrix Authorization Strategy. I will assume you've selected the later.
Under User/group to add: type authenticated and click Add
Now, give this group all the permissions that you want them to have.
Next, under User/group to add: type Anonymous and click Add
Make sure that none of the permissions are given to this group
Click Save
This way, anonymous (not-logged in) users will not be able to see anything, but authenticated (logged in) users will be able to see what you selected. You can drill-down into more specific user permissions by adding individual users and granting them certain permissions.
P.S. The user authentication depends on your Security Realm configuration. You can configure to use Active Directory/LDAP, or use Jenkin's own user database. The former means you don't have to create users in Jenkins, just give them permissions. The later means you've got to create Jenkins's users first through Manage Jenkins -> Manage Users

Resources