Ad Code

Wednesday, October 4, 2017

Sling Service Authentication in AEM 6.3


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
1.PNG
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
2.PNG
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.
system user.PNG
Fig -  JCR System User Validator Configuration
If you unchecked the configuration, you can create service mappings with non system users, but it is not recommended in the production environment.

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
user list.PNG
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.
servicemapper.PNG
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.
conf.PNG
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
config whitelist1.PNG
Fig - Apache Sling Login Admin Whitelist Configuration

  1. 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.
  2. 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
config2.PNG
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.

2 comments:

  1. Hi Shivani,

    Very 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


    ReplyDelete
  2. When i am going through resource resolver details in net, i observed same approach to get resource using resource resovler factory.

    Could you please let us know,Service authentication and getting resource form resource resolver factory are same?

    ReplyDelete