neo4j / neo4j-ogm

Java Object-Graph Mapping Library for Neo4j
https://neo4j.com/docs/ogm-manual/
Apache License 2.0
327 stars 162 forks source link

How to use ImpersonatedUser in neo4j ogm session #999

Open joyantac33 opened 9 months ago

joyantac33 commented 9 months ago

We can use ImpersonatedUser at the time of using neo4j java driver like below:

Session session = neo4jDriver.session(SessionConfig.builder().withDatabase(neo4jDB).withImpersonatedUser(userName).build());

But how can we use ImpersonatedUser at the time of neo4j ogm session in java:

Session session = sessionFactory.openSession();

Expectation is to load or run cypherQuery through neo4j ogm session with impersonatedUser in java.

meistermeier commented 9 months ago

You can provide a UserSelectionProvider on the SessionFactory configuration like this:

new Configuration.Builder().userSelectionProvider(() -> {
            return UserSelection.impersonate("someone");
        }).build().
joyantac33 commented 9 months ago

Thank you for your response, it was helpful. Is there any way to change the impersonate("someone") in configuration dynamically in SessionFactory before opening session as username is dynamic and also want to avoid creating SessionFactory every time user is requesting something from the application.

meistermeier commented 9 months ago

I don't know the context, your application is running is, but normally you provide this configuration just once. The dynamic part would be within the lambda. For example, if you use Spring, you could create a bean for the UserSelection that then depends on the logged in user or similar.

joyantac33 commented 9 months ago

Environment : Spring Boot + Apache Camel + Neo4j OGM Use case : Web application with API endpoints as well as integration flows. Service class is backed by a DAO layer with OGM Entities. Application is accessed by multiple users. Users will be impersonated based on the roles defined. As you have mentioned, since we are using Spring, we can create a bean for UserSelection. What will be the scope of the bean. In session scope it will be shared. We cannot make it request scope due to two reasons :

  1. We are creating the driver instance and session factory as bean inside class annotated with @Configuration
  2. Camel route cannot set value in a request scope bean as it is not in web request context scope Please provide us a better solution to handle the problem. Right now we had to create our own bolt driver implementation to solve the problem. Bolt driver class within OGM module is very rigid. Not providing options for extension. Looking forward for your answer. Thanks in advance.
joyantac33 commented 8 months ago

It will be a great help if you can revert back with any solution for above scenario.

meistermeier commented 8 months ago

I have no experience with Apache Camel. I think with this background that the solution for your problem is to create two UserSelectionProvider beans, one for the requests and one for the singleton. I created a small example that should show what my idea is: Also it is working. It is always the same SessionFactory just with different UserSelectionProviders in place.

https://github.com/meistermeier/neo4j-issues-examples/tree/master/ogm-impersonation

From the logs

org.neo4j.ogm.session.SessionFactory@161d95c6
DEFAULT_USER
com.example.ogmimpersonation.MyUserSelectionProvider@11b8f718
org.neo4j.ogm.session.SessionFactory@161d95c6
ROLE_USER
com.example.ogmimpersonation.MyUserSelectionProvider@7c6b0965
org.neo4j.ogm.session.SessionFactory@161d95c6
ROLE_READER
meistermeier commented 6 months ago

Did this work?

joyantac33 commented 4 months ago

Thank you so much for your solution. Unfortunately, within camel environment, it didn't solve our purpose.

michael-simons commented 1 month ago

Hey @joyantac33 you should write the UserSelectionProvider in such a way that it is aware of the camel environment and grab the username from there. That should actually do it, so that if you open a new OGM session, it will take the user appropriate.