April 10, 2020
Estimated Post Reading Time ~

Access Content Repository via getServiceResourceResolver() in AEM6/Sling7

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

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

The latest release of Sling provides an alternative to access the repository without using admin session via Service-Based Authentication. In Service-Based authentication, each service will bind to a specific set of users which will have different access privileges. These users also refer to 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 others to read/write.
Step 2: Create two services which try to write some property inside the 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:

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

Step 4: Create some authoring stuff, in such a way we will pass the page path than 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 depend 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


By aem4beginner

No comments:

Post a Comment

If you have any doubts or questions, please let us know.