We have a scenario where we are polling users from Active directory to keycloak and this works perfectly fine and any recently changed user automatically gets added in keycloak .But here I have to load same users from Keycloak to my SpringBoot application DB on certain interval say 1 hour . So the high level data flow is like below
Active Directory -> KeyCloak ->Spring Boot Service Poll->Application DB
Need to find a best way to process only users who have recently been modified in keycloak so that I shall have less number of records to update in Application DB.
Keycloak keycloakInstance=// pass Keycloak URL to KeycloakBuilder
Userresource userResource=// using keycloakInstance pass realmName and getUsers
List uersListFfromkeyCLoak// Here need only users who have changed in last one hour
You can implement a Keycloak plugin based on the EventListenerSpi. In your custom EventListenerProvider you can react to any change of user objects. You may write the change events to a message queue and read from that queue with your spring boot application.
For more information and a code snippet have look at my answer on that quite similar question.
Related
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.
I try to achieve the following behavior with Spring Boot:
When a user wants to log in to my site he can choose from multiple OAuth2 serves (for example Google, Facebook, GitHub, etc...).
He selects an option (for example google) and logs in with google OAth2.
Then my site takes the e-mail address from OAuth2 and loads the user from a database to use as Principal.
So I basically want the Principal to always be the same (read from database) and do not depend on which OAuth2 server the user uses to log in.
To achieve the behavior, you're looking for, I would suggest you take a look at PrincipalExtractor, here's a blog post about it.
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.
I have implemented a Spring Boot application with AngularJS frontend. Have also setup users along with their permissions. Right now I am able to login with any of these users and is working well with Spring security. I would like to turn this traditional login flow into a Facebook/Google OAuth login flow, where in I want the users to use their Facebook/Google account to log in and they will be mapped to their internal users automatically. This will help me in getting rid of maintaining passwords of these users.
I found many articles talking about setting up OAuth with Spring Boot and how can Facebook/Google login be integrated with a Spring Boot application. But I am having difficulty in finding an article which talks about linking a Facebook/Google user with internal users.
How should I go about this?
Look for a user with the associated facebook/google userID.
If that user does not exist you request an email address and try to match it with an existing legacy account.
If you do not get a email adress for any reason (not acceping the authorization request for example) you could show a popup box asking for the email adress explaining why you need it.
You then locate the legacy user and merge it adding the facebook/google ID to look it up in the future.
If no user is found with the email adress you either refuse the user or create a new account.
you should be able to do all of this by implementing your own AuthenticationProvider
Before you can fetch a user’s data from Facebook, you must specify your application’s ID and secret by setting the spring.social.facebook.appId and spring.social.facebook.appSecret properties. You can set these via any means supported by Spring Boot, including setting them in an application.properties file:
spring.social.facebook.appId=233668646673605
spring.social.facebook.appSecret=33b17e044ee6a4fa383f46ec6e28ea1d
For reference you can follow this article: https://spring.io/guides/gs/accessing-facebook/
I am currently having a problem in implementing concurrent user session in spring mvc. My requirement is that "I have a web application which uses spring MVC, and I have my own login form and I have not implemented spring security yet(which means I have not configured any role based user restriction in my web application). I want only one user with same username to be logged in from a machine. I have surfed all over the net , but couldn't find any useful links nor example project(without role based).
My Requirement:
One user per session
No role based restriction
Have my own login form and once the user logs in , user object(which contains username an password) is stored in session object
If user tries to login for second time , previous user session should be terminated and new user(second user) should be allowed to home page.
Can some one please provide me a solution, links or example project for my requirement ? Many thanks in advance :)
Why not just go ahead and use Spring Security? It will take care of deactivating sessions for you. You can use your own login form and not restrict any of your endpoints based on roles.
You can configure the max number of sessions like so: