Access Content Repository via getServiceResourceResolver() in AEM6/Sling7

22 / Dec / 2014 by Vivek Dhiman 3 comments

JCR Sessions and Sling Based Authentication are always the important in code where someone need to get an access of the Content Repository. But this same way to get an access over content repository was remains controversial due to its administrative privileges . So with the new AEM6 version below methods have been deprecated to get an access of admin sessions which can cause the security vulnerabilities :

1) ResourceResolverFactory.getAdministrativeResourceResolver
2) ResourceProviderFactory.getAdministrativeResourceProvider
3) SlingRepository.loginAdministrative

Latest release of Sling provide an alternative to access the repository without using admin session via Service Based Authentication. In Service Based authentication each service will bind to specific set of users which will have different access privileges. These users also refer as the service users. Below is the implementation steps of service based authentication .

Step 1 : Create two users with different access privileges, gives one to read and other to read/write.
Step 2 : Create two services which try to write some property inside node :

WriteOpService

@Service
@Component(immediate = true)
public class WriteOpServiceImpl implements WriteOpService{
    private final Logger logger = LoggerFactory.getLogger(WriteOpServiceImpl.class);
    @Reference
    private ResourceResolverFactory resolverFactory;
    @Override
    public void writePropToNode(String resourcePath) {
        Map<String, Object> serviceParams = new HashMap<String, Object>();
        serviceParams.put(ResourceResolverFactory.SUBSERVICE, "writeService");
        ResourceResolver resolver = null;
        try {
            resolver = resolverFactory.getServiceResourceResolver(serviceParams);
            logger.info(resolver.getUserID());
            Resource res = resolver.getResource(resourcePath+"/jcr:content");
            logger.info("Path is ::: "+res.getPath());
            ModifiableValueMap modMap = res.adaptTo(ModifiableValueMap.class);
            if(modMap != null){
                modMap.put("propname", "propValue");
                resolver.commit();
                logger.info("Successfully saved");
            }
        } catch (Exception e) {
            logger.error("Exceptions is ::: ",e);
        }finally{
            if(resolver != null){
                resolver.close();
            }
        }
    }

ReadOpService :

@Service
@Component(immediate = true)
public class ReadOpServiceImpl implements ReadOpService {

    private final Logger logger = LoggerFactory.getLogger(ReadOpServiceImpl.class);

    @Reference
    private ResourceResolverFactory resolverFactory;

    @Override
    public void readPropFromNode(String resourcePatb) {
        Map<String, Object> serviceParams = new HashMap<String, Object>();
        serviceParams.put(ResourceResolverFactory.SUBSERVICE, "readService");
        ResourceResolver resolver = null;
        try {
            resolver = resolverFactory.getServiceResourceResolver(serviceParams);
            logger.info(resolver.getUserID());
            Resource res = resolver.getResource(resourcePatb+"/jcr:content");
            logger.info("Path is ::: "+res.getPath());
            ModifiableValueMap modMap = res.adaptTo(ModifiableValueMap.class);
            if(modMap != null){
                modMap.put("propname", "propValue");
                resolver.commit();
                logger.info("Successfully saved");
            }
        } catch (Exception e) {
            logger.error("Exceptions is ::: ",e);
        }finally{
            if(resolver != null){
                resolver.close();
            }
        }
    }

Step 3 : Configure the Apache Sling Service User Mapper service via Felix Console as below:

console

Syntax will be  : [bundle-symbolic-name]:[subServiceName]=[Service-User] 

Step 4 : Create some authering stuff, in such a way we will pass the page path then on submit, property propname with value propValue will be set to the page.
Step 5 : Below is the sample associated component script :

<%@include file="/libs/foundation/global.jsp"%>
<%@page session="false" %>
<% String prop = properties.get("pagePath","");
com.aem.services.WriteOpService writeOpService = sling.getService(com.aem.services.WriteOpService.class);
com.aem.services.ReadOpService readOpService = sling.getService(com.aem.services.ReadOpService.class);
//readOpService.readPropFromNode(prop);
writeOpService.writePropToNode(prop); %>

If we look both the services they are performing the write operation but in the success will depends on via which user you logged in & which operation you call, as different services are associated with different service users. Refer the below link for further information :
https://cwiki.apache.org/confluence/display/SLING/Service+Authentication

Vivek Dhiman

FOUND THIS USEFUL? SHARE IT

comments (3)

Leave a comment -