Hi,
This topic has a lot of blogs over internet, but in a distributed way. In this blog, I tried to go in deep and tried to cover each and every point in detail. So let’s start from the problem statement:
Problem: To access the data storage in the Resource Tree and/or the JCR Repository. authentication is required to properly setup access control and guard sensitive data from unauthorized access.
On the other hand, there are some background tasks to access resources. Such tasks cannot be configured with user names and passwords.
The solution presented has serves the following goals:
- Prevent over-use and abuse of administrative ResourceResolvers and/ro JCR Sessions
- Allow services access to ResourceResolvers and/or JCR Sessions 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.
Concept: : The format of service configuration is:
service-name:[sub-service-name]=system-user
|
Service-name: The service-name is the symbolic name of the bundle providing the service.
Sub-Service-Name:A Service may be comprised of multiple parts, so each part of the service may be further identified by a Subservice Name. This field is optional.
System-User :This will be the name of system user having access to get the resource.
Deprecate loginAdministrative
The following methods are deprecated:
- SlingRepository.loginAdministrative
- ResourceResolverFactory.getAdministrativeResourceResolver
- ResourceProviderFactory.getAdministrativeResourceProvider (This API has been deprecated in AEM 6.3)
To replace loginAdministrative , we need Service Authentication.There are two configurations to configure service Authentication:
1. Apache Sling Service User Mapper Service
Fig - User Mapper Service Configuration |
There are two options in this configurations:
- Service mappings: The service mappings configuration can be used here.
You can configure it like this:
Bundle-Symbolic-Name: Sub-Service[Optional] = System-User-Name
- Default User: If there is no service mapping corresponding to a bundle, then the bundle will pick default User and use it as it’s service authentication user.So if you don't want to provide any service mappings, you can use the option of default user.But it is not specific to the bundle.
2. Apache Sling Service User Mapper Amendment
Fig - Service User Mapper Amendment Configuration |
- This configuration is used when you want to have an individual configuration for a particular project.
- If there are more than one configurations correspond to a particular bundle, based on the ranking, service can be picked.(The highest the number will be having highest ranking).
New loginService methods
Now the new methods are introduced to replace loginAdministrative methods:
- ResourceResolver getServiceResourceResolver(Map<String, Object> authenticationInfo) throws LoginException;
- Session loginService(String serviceInfo, String workspace) throws LoginException, RepositoryException;
Note: Each bundle using the ResourceResolverFactory or SlingRepository service actually gets an instance bound to the using bundle. That bundle is used to identify the service.
Can Non System Users can be used for Service Mappings?
So the answer is surprising, but it’s a yes. There is an OSGi Configuration available in felix console:
Apache Sling JCR System User Validator.
Fig - JCR System User Validator Configuration |
Report of Configured System Users for Service Mappings
You can see all the users with configured service mappings in the felix console.
- Go to felix console.
- Go to Status ->Sling Service User Mappings
Fig - Report of configured system users for service mapping |
The package “ org.apache.sling.serviceusermapping” provides three interfaces which are very useful in terms of Service Authentication.
1. ServiceUserMapped: The ServiceUserMapped is a marker service that can be used to ensure that there is an already registered mapping for a certain service/subService.
Understand ServiceUserMapped with example
Use Case: There can be a use case when you don’t want to make your bundle active until no service mappings are available . In such kind of situations ServiceUserMapped Interface is used.
How it works: You use it with @Reference annotation in any component and if it doesn’t find any service user mappings with the bundle it won’t let the component activate.
Example:
@Reference(target = "(subServiceName=test)")
ServiceUserMapped serviceUserMapped;
|
2. ServiceuserMapper: The ServiceUserMapper service can be used to map a service provided by a bundle to the ID of a user account used to access the ResourceResolver used by the service to access its data.
Fig - getServiceUserID method syntax of ServiceUserMapper class |
Note:This 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.
ServiceUserMapper Interface has a method getServiceUserID() that returns the system user name for that particular bundle service mappings, if available.
public class Test extends SlingSafeMethodsServlet {
@Reference
ServiceUserMapper serviceUserMapper;
@Override
protected void doGet(final SlingHttpServletRequest req,
final SlingHttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().print(serviceUserMapper.getServiceUserID(FrameworkUtil.getBundle(this.getClass()),null));
resp.getWriter().print(serviceUserMapper.getServiceUserID(FrameworkUtil.getBundle(this.getClass()), "subService"));
}
}
|
3. ServiceuserValidator: The ServiceUserValidator allows to implement validation of configured service user mappings.
Fig - Method of checking user is valid o |
This interface is used to validate the combination of system user with the bundle’s service mappings.
public class Test extends SlingSafeMethodsServlet {
@Reference
ServiceUserValidator serviceUserValidator;
@Override
protected void doGet(final SlingHttpServletRequest req,
final SlingHttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().print(serviceUserValidator.isValid("cug-service",FrameworkUtil.getBundle(this.getClass()).getSymbolicName(),"subService"));
}}
|
Demonstration video on Sling Service Authentication concept:
WhiteListing Bundle for Administrative Login
Problem Statement: AEM has deprecated its Administrative Login but not removed completely. There are some bundles still available, who are using old Administrative login. So a whitelisting mechanism was introduced with SLING-5153 (JCR Base 2.4.2). If there a need to use Administrative Login , you can whitelist your bundle and use it either it is not recommended.
If you use adminResourceResolver, the log file shows below error:
03.10.2017 23:43:26.858 *ERROR* [0:0:0:0:0:0:0:1 [1507054406856] GET /bin/slingModels HTTP/1.1] com.adobe.granite.repository.impl.SlingRepositoryImpl Bundle com.sling.models.Sling-Models.core is NOT whitelisted to use SlingRepository.loginAdministrative
|
The other scenario can be that there is some older bundle you are using , so you can whitelist this bundle for Administrative Login to continue your work.
How to whiteList a bundle?
1. Apache Sling Login Admin Whitelist
Fig - Apache Sling Login Admin Whitelist Configuration |
- Bypass the whitelist: If this configuration is true, by default all the bundles will be allowed to use adminResourceResolver.It is good option, when you are in a mid of work and don't want to choose the bundles, which are having adminResourceResolver.But it is not recommended in a production at all.
- All the other options are clear with the name only. Just need to add bundle symbolic name in a regex or simple format.
2.Apache Sling Login Admin Whitelist Configuration Fragment
Fig - Bundle Whitelisting Configuration |
If you want to use project level configurations for bundle whitelisting, you can use this:
Name: Name of the bundle (Any Name) which you are adding in whitelist.
Whitelisted BSNs : The symbolic name of the bundle to be whitelisted.
Demonstration video on White listing of Bundle Concept:
If you have any query or suggestion then kindly comment or mail us at sgaem.blog02@gmail.com
Hope it will help you guys !!
Thanks and Happy Learning.
Hi Shivani,
ReplyDeleteVery informative.
As you have clearly highlighted that if there are more than one configurations correspond to a particular bundle, based on the ranking, service can be picked.(The highest the number will be having highest ranking).
What would be criteria to select service , if both are having same ranking? Is the sequence of entry at Apache Sling Service User Mapper Amendment?
Thanks,
Debal
When i am going through resource resolver details in net, i observed same approach to get resource using resource resovler factory.
ReplyDeleteCould you please let us know,Service authentication and getting resource form resource resolver factory are same?