Access Content Repository via getServiceResourceResolver() in AEM6/Sling7
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
[java]
@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();
}
}
}[/java]
ReadOpService :
[java]
@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();
}
}
}
[/java]
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 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 :
[java]<%@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); %>
[/java]
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
will u pls explain for slingrepository.loginadminstrative also
Image attached is too small
Good article, but you should mention that ONLY system users can be used to do service login.