Create and Use Service User using ACL Scripts | AEMaaCs

In this article we will learn how to create and use Service Users in your AEM code to provide controlled, programmatic access to the AEM repository.

As we all know we used to create the system users using the /crx/explorer and used to provide the required permissions from /useradmin dashboard. But now as we are moving towards AEMaaCs and the recommended way is to push the system users and it’s permissions through code. So let’s see how we can achieve that.

So let’s go ahead and update the OSGI config which comes OOTB as part of recent archetypes i.e, org.apache.sling.jcr.repoinit.RepositoryInitializer-myproject-statistics.config which can be found in you project structure at /ui.config/src/main/content/jcr_root/apps/myproject/osgiconfig.


1. Service User – permission to single path

scripts=["
    create service user myprojectUserService
 
 
    set ACL on /content/dam/myproject
         allow jcr:all for myprojectUserService
    end
"]

2. Service User – permission to multiple paths

scripts=["
    create service user myprojectUserService
 
 
    set ACL on /content/dam/myproject,/conf/myproject
         allow jcr:all for myprojectUserService
    end
"]

We can give different permissions as per our requirement, here I have given jcr:all for the above paths but if you want to give only read/write permissions you can do something like below:

3. Service User – permission to single path with only read permission

scripts=["
    create service user myprojectUserService
 
 
    set ACL on /content/dam/myproject
         allow jcr:read for myprojectUserService
    end
"]

4. Service User – permission to multiple paths with only write permission

scripts=["
    create service user myprojectUserService
 
 
    set ACL on /content/dam/myproject
         allow jcr:write for myprojectUserService
    end
"]

The recommended way is to create the service user under system/cq:services/<my-project> when using the principle ACL. You do it my using the following script:

scripts=["
    create service user myprojectUserService with forced path system/cq:services/my-project

    
    set principal ACL for myprojectUserService
        allow jcr:read on /content/dam/myproject
    end
"]

So once we are done creating the service user we will map it to a subServiceName which will be used in our java code to get the proper resolver to access the AEM content.

We can create our OSGI config i.e, org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended-myproject.cfg.json

{
  "user.mapping": [
    "myproject.core:myprojectUserService=[myprojectUserService]"
  ]
}

So once we are done creating the above configurations we can utilise the above service user to get our resource resolver which will help us access the AEM content.

final Map<String, Object> authInfo = Collections.singletonMap(
                ResourceResolverFactory.SUBSERVICE,
                "myprojectUserService");

    
        try (ResourceResolver serviceResolver = resourceResolverFactory.getServiceResourceResolver(authInfo)) {
            // Do some work with the service user's resource resolver and underlying resources.
        } catch (LoginException e) {
            log.error("Login Exception when obtaining a User for the Bundle Service: {} ", e);
        }


Thank you for reading.
Happy Coding!

Author:

I am Nikhil Kumar, AEM developer. Working on AEM since the start of my career. Created this blog to share my AEM knowledge and give back to the AEM Community. You can reach out to me on any query.

Leave a comment