JCR sessions and CQ5

The JCR 2.0 specifications says about sessions:

A user connects to a repository by passing a set of credentials and the name of the workspace that the user wishes to access. The repository returns a session which binds the user to the requested persistent workspace with a level of authorization determined by that user’s credentials. A session is always bound to exactly one persistent workspace, though a single persistent workspace may be bound to multiple sessions.

In the implementation of Jackrabbit/CRX it means that the session enforce authorization; if a user is not authorized to see nodes, the session will not expose them to the user. It’s just as they are not there. Workspace handling is in the case of CQ5 not really relevant, as only the “crx.default” workspace is used.

But what does this mean for your work with CQ5?

  • So first of all, sessions are an integral concept of security within CQ5. A normal user session is different from an admin session. In a user session normally less nodes than in an admin session are visible. You cannot just switch the user context within a session, but you create a new one.
  • In an admin session you are not restricted at all, you can do everything.
  • In the context of requests to templates and components, you will work with an authenticated session (or anonymous sessions in the standard publish case). Sling authenticates the request and provides you an appropriately authenticated session, and closes this specific session when the request processing is done. Do not close this session!
  • In a request scope you normally should not need to create a new session. You should leverage the session associated with the request.
  • Not closing a single session isn’t a problem, but not closing many session will cause a serious memory leak.
  • Sessions are cheap. You can create as many of them as you need. So it’s perfectly ok to open a session to change a few properties and then close that session again. Try to have sessions as short-lived as possible.
  • The only exception from this rule are sessions, in which you have registered a JCR observation listener. But use these sessions only for reading. If you need to write to the repository in an observation listener, create a new session for these write operations.
  • In most cases Unix daemons work in the context of a specialized user to limit the impact of a security breach through this daemon. You should act alike and use specialized user sessions if you work with JCR sessions. For 99% of all usecases you should not use an admin session!
  • If you want to run a session with a less privileged user than the admin, you should use the impersonation feature of JCR. Do not hardcode any user password in your code. This code fragment shows how you can use impersonation to create a session with a different user than admin, but without hardcoding the password of that user:
private static final RUNAS_USER="technical_user";
@Reference
SlingRepository repo;
Session adminSession = null;
Session userSession = null;
try {
  Session adminSession = repo.loginAdministrative(null);
  userSession = adminSession.impersonate(new SimpleCredentials(RUNAS_USER,"".toCharArray()));
  adminSession.logout();
  adminSession = null;
  doSomethingWith(userSession);
} catch (RepositoryException e) {
  // report exception
} finally {
  if (adminSession != null) {
    adminSession.logout();
  }
  if (userSession != null) {
    userSession.logout();
  }
}

Update March 19th 2013: My colleague Alex Klimetschek recommended me to add this statement: “Admin sessions sound so useful. But they are dangerous!”
Update April 9th 2013: SimpleCredentials take in the constructor a char array as password, not a String. Thanks Anand.

2 thoughts on “JCR sessions and CQ5

  1. Thanks for the nice post!
    I tried but new SimpleCredentials(RUNAS_USER,””) is not accepted as the API says like SimpleCredentials(java.lang.String userID, char[] password) .

    Please clarify whether the password is the real user password that is stored in crx repository or we can escape this. Basically I don’t want to hardcode the password.

    Thanks!

    1. Hi Anand,

      Thanks for your comment.

      If you use impersonation, you don’t need to provide any password. Just impersation must be allowed, and from admin to any other user it is possible by default.

      Jörg

Comments are closed.