Introduce new service level authentication to replace
Created: 4. April 2013
|Table of Contents|
Since the early days of Sling we had methods to get an administrative JCR Session and later an administrative ResourceResolver. These methods were intended to provide services with access to the repository with less restrictions than regular users and to also allow those services to access the Resource tree (and JCR Repository) without hard-coding a password in the code or even having the password as some plain text in configuration.
Over the years, it turned out that these
loginAdministrative methods have been abused.
The goal of this proposal is to come up with new API to replace the
One example of a service, which currently uses administrative privileges but which would benefit from a carefully crafted service user is the Tenant Manager
- Don't use administrative JCR Sessions or ResourceResolvers all over
- Allow services access to JCR Sessions and ResourceResolvers without requiring to hard-code or configure passwords
- Allow services to use "service users" which have been specially configured for service level access (as is usually done on unixish systems)
- Allow administrators to configure the assignment of service users to services
New loginService methods
Two new methods are introduced to replace
ResourceResolver getServiceResourceResolver(Map<String, Object> authenticationInfo) throws LoginException;
Session loginService(String serviceInfo, String workspace) throws LoginException, RepositoryException;
The bundle identifying the actual service is not part of the new API. The bundle is taken from the call stack by leveraging the OSGi Service Factory mechanism: Each bundle using the
SlingRepository service actually gets an instance bound to the using bundle. That bundle is used to identify the service.
serviceInfo parameter or
sling.service.info property of the
authenticationInfo map may be used to provide additional information on the service. See the New ServiceUserMapper Service section below for information on additional service information.
Communicating Service Information to ResourceProviderFactories
ResourceProviderFactory interface is not extended for the new service login. Rather the required information – using bundle and additional service information – is passed to the
getResourceProvider method as part of the
ResourceResolverFactory.USER– name of the service user (never
ResourceProviderFactory.SERVICE_BUNDLE– the service
ResourceResolverFactory.SERVICE_INFO– additional service information (optional; may be
In case the
ResourceProviderFactory makes use of another service to provide the
ResourceProvider the provided service bundle should be used to acquire the service to allow the service to support service logins using the
ServiceUserMapper service. An example of such an implementation would be the JCR based
ResourceProviderFactory which gets the
SlingRepository service using the service bundle.
New ServiceUserMapper Service
A service is introduced which allows to map a service to a user name. A service is identified by a service name related to the OSGi Bundle implementing the service and an additional service information string. For example a bundle implementing mail support may represent the MailServer service while the actual mail sender may identify itself with the sender information and some mail queue handler may identify itself with the queue information. This allows separate users to be used for sending messages and handling the message queue or using the same user for both services, depending on the requirements and needs of the system administrator.
ServiceUserMapper service has two methods:
String getServiceName(Bundle bundle, String serviceInfo);– Returns the value of the service identification string to use for the bundle providing the service. In the above example of the message sender service, when call with the mail server bundle and
serviceInfo="sender"the returned value might be
String getUserForService(Bundle bundle, String serviceInfo);– Returns the name of the user to be used for the given service.
ServiceUserMapper service is intended to be used by implementations of the new
loginService methods to allow mapping services to user names and to provide for a central point of configuring the mapping.
The following methods are deprecated:
The implementations we have in Sling's bundle will remain implemented but there will be a configuration switch to disable support for these methods: If the method is disabled, a
LoginException is always thrown from these methods. The JavaDoc of the methods is augmented with this information.
A prototype implementation of this concept is available in the deprecate_login_administrative whiteboard.