Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.
SOLVED

How to pass the current user's credentials to ResourceResolverFactory.getResourceResolver?

Avatar

Level 7

I want to define an abstract service that subclasses can extend. In the abstract service I want to define a getResourceResolver() method that gets a resource resolver authenticated with the current user.

How can I pass the current user's credentials to ResourceResolverFactory.getResourceResolver considering that I don't have access to the request object in the service?

Also currently I am acquiring a Session like this:

protected ResourceResolver getResourceResolver() { try { return resolverFactory.getAdministrativeResourceResolver(null); } catch (LoginException le) { log.error("Could not get administrative resource resolver", le); throw new RuntimeException(le); } } protected Session getSession() { return getResourceResolver().adaptTo(Session.class); }

However this sometimes leads to the following exception:

RepositoryException: This session has been closed. See the chained exception for a trace of where the session was closed. at org.apache.jackrabbit.core.session.SessionState.checkAlive(SessionState.java:150) at org.apache.jackrabbit.core.session.SessionState.perform(SessionState.java:200) at org.apache.jackrabbit.core.ItemImpl.perform(ItemImpl.java:91) at org.apache.jackrabbit.core.ItemImpl.remove(ItemImpl.java:322)

How can I reopen the session when it is closed?

protected Session getSession() { Session session = getResourceResolver().adaptTo(Session.class); if (!session.isLive()) { // ??? } }

Thanks.

1 Accepted Solution

Avatar

Correct answer by
Employee Advisor

Hi,

when you want to execute some activities in the context of the current user, you should use the resourceresolver of the request. Because when you have a "user" information, it should be easy to pass the resourceResolver as well.

To your questions:

1) That depends. If "jcr:lastModifiedBy" is not updated or created, the original username remains (or there is no name at all).

2) Not at all.

(Well, if you don't require a resourceResolver, but only a JCR session, you could use the session.impersonate() method.)

Jörg

View solution in original post

4 Replies

Avatar

Employee

Hi,

Instead of creating a service why not create an adapter factory?  You could adapt the resource resolver from the request to your class(es) and then you would have access to the actual user's session and you would not need to acquire an additional session.

See [0] for how to build an adapter factory, the docs are here [1]

Will

[0] http://www.wemblog.com/2013/07/how-to-use-adapters-in-adobe-cq-aem.html

[1] https://sling.apache.org/documentation/the-sling-engine/adapters.html

Avatar

Former Community Member

To answer your question, according to me

  1. It will be marked as admin as you are updating JCR with admin account.
  2. Use sling request.getResourceResolver, then you can adapt the resolver into JCR session. This will use the current user account.If you are using pre authenticated session. Other wise you are directly login using user account like this.
    SimpleCredentials credential = new SimpleCredentials("your_username", "your_password".toCharArray()); session = repository.login(credential, "crx.default");  

     

Avatar

Level 7

Hi Will,

Thanks for your reply but I am afraid that doesn't answer my question. Maybe my question is not clear enough. Let me rephrase.

There are some articles (for example Getting Resources and Properties in Sling) about how one can access resources, etc. in Sling. However, for example in the given article, access to JCR is done through an administrative resource resolver.

Now I have two questions about this:

  1. If a request sent by a non-admin user leads to a write operation via an administrative resource resolver, would that resource be marked as updated by that given user or by the administrator user?
  2. In a service method/class that is not passed the current request, how can I get the current user's resource resolver, rather than the administrative resource resolver?

Thanks.

Avatar

Correct answer by
Employee Advisor

Hi,

when you want to execute some activities in the context of the current user, you should use the resourceresolver of the request. Because when you have a "user" information, it should be easy to pass the resourceResolver as well.

To your questions:

1) That depends. If "jcr:lastModifiedBy" is not updated or created, the original username remains (or there is no name at all).

2) Not at all.

(Well, if you don't require a resourceResolver, but only a JCR session, you could use the session.impersonate() method.)

Jörg