Wednesday, July 16, 2014

LDAP integration with AEM6 (OSGi Config way)

In AEM 6, LDAP support comes with a new implementation that requires a different type of configuration than with previous versions.

All LDAP configurations are now available as OSGi configurations. They can be configured via the Web Management console at:

http://serveraddress:4502/system/console/configMgr

The required config classes are listed below.
  1. org.apache.jackrabbit.oak.security.authentication.ldap.impl.LdapIdentityProvider
  2. org.apache.jackrabbit.oak.spi.security.authentication.external.impl.DefaultSyncHandler
  3. org.apache.jackrabbit.oak.spi.security.authentication.external.impl.ExternalLoginModuleFactory. 
The configs can be updated manually via OSGi console or via deployment. We can use the follow steps & config files to add/update an LDAP provider.


Create OSGi config file of type  "sling:OsgiConfig" & name it to 
"org.apache.jackrabbit.oak.security.authentication.ldap.impl.LdapIdentityProvider.xml". 

See here for reference.
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="sling:OsgiConfig"
bind.dn = "cn=Directory Manager" bind.password = "******" group.baseDN = "ou=groups,dc=example,dc=com"
group.memberAttribute = "uniquemember" group.nameAttribute = "cn" group.objectclass = "[groupOfUniqueNames]"
host.name = "localhost" host.port = "389" host.ssl = "false" host.tls = "false" provider.name = "ldap"
user.baseDN = "ou=users,dc=example,dc=com" user.idAttribute = "uid" user.objectclass = "[inetorgPerson]" />



Similarly create two more config files & name them as below.

org.apache.jackrabbit.oak.spi.security.authentication.external.impl.DefaultSyncHandler.xml

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="sling:OsgiConfig"
user.autoMembership = "[contributor]" user.expirationTime = "1h" user.membershipExpTime = "1h"
user.membershipNestingDepth = "0" user.propertyMapping = "[rep:fullname=cn]" />


org.apache.jackrabbit.oak.spi.security.authentication.external.impl.ExternalLoginModuleFactory.xml

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="sling:OsgiConfig"
idp.name = "ldap" jaas.controlFlag = "SUFFICIENT" jaas.ranking = "50" jaas.realmName = "ldap" sync.handlerName = "default" />


Now with this config files in place, do a config/content deployment & upon successful deployment your AEM instance is configured with the provided LDAP server.

Tested with OpenDS 2.2 & AEM 6

Please Note: You may need to restart your AEM instance once the configs are applied.

Tuesday, July 8, 2014

Inject OSGi services in Sling models (Pojos) - Sling model way

Create the injection point in the sling model class with @Source annotation & assign "osgi-services" as a value to the source annotation. 
@Model(adaptables = Resource.class)
public class Banners {
@Inject @Source("osgi-services") GreetService greetService;
view raw Banners.java hosted with ❤ by GitHub


By this we can inject the below OSGi service in the Sling Model class.

@Service(value = GreetService.class)
@Component( metatype = true, immediate = true )
public class GreetServiceImpl implements GreetService {
@Override
public String greet(String greeter) {
return String.format( "Hallo %s, Wel Come to Sling Model", greeter );
}
}

JCR content mapping with Sling Model

follow the easy steps to use sling model for JCR content mapping.

  1. Add sling model bundle dependency information in pom.xml
    <dependency>
    <groupId>org.apache.sling</groupId>
    <artifactId>org.apache.sling.models.api</artifactId>
    <version>1.0.0</version>
    </dependency>
    view raw pom.xml hosted with ❤ by GitHub
     
  2. Add Sling-Model-Packages declaration in the instruction 
    <plugin>
    <groupId>org.apache.felix</groupId>
    <artifactId>maven-bundle-plugin</artifactId>
    <extensions>true</extensions>
    <configuration>
    <instructions>
    <Sling-Model-Packages>
    edu.saral.models
    </Sling-Model-Packages>
    <Bundle-SymbolicName>edu.saral.slingmodel-bundle</Bundle-SymbolicName>
    </instructions>
    </configuration>
    </plugin>
    view raw declaration.xml hosted with ❤ by GitHub
  3. Annotate pojo class with @Model annotation and use @Inject against the fields (with getters)
    package edu.saral.models;
    import org.apache.sling.api.resource.Resource;
    import org.apache.sling.models.annotations.Model;
    import javax.inject.Inject;
    /**
    * Created by behera on 07-07-2014.
    */
    @Model( adaptables = Resource.class )
    public class Person {
    @Inject private String firstName;
    @Inject private String lastName;
    @Inject private String email;
    @Inject private String mobile;
    view raw Person.java hosted with ❤ by GitHub
     
  4. Now adapt this pojo with resource.adaptTo() 
    person = getResource().adaptTo( Person.class );
    LOGGER.info( "person {} ", person );
    view raw PersonBean.java hosted with ❤ by GitHub
  5. This Will map the below content structure easily without the bulgy or cluttered code.  
    <?xml version="1.0" encoding="UTF-8"?>
    <jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
    jcr:primaryType="cq:Dialog"
    helpPath="en/cq/current/wcm/default_components.html#Title"
    title="Person"
    xtype="panel">
    <items jcr:primaryType="cq:WidgetCollection">
    <title
    jcr:primaryType="cq:Widget"
    fieldLabel="First Name"
    name="./firstName"
    xtype="textfield"/>
    <link
    jcr:primaryType="cq:Widget"
    fieldLabel="Last Name"
    name="./lastName"
    xtype="textfield"/>
    <email
    jcr:primaryType="cq:Widget"
    fieldLabel="Email"
    name="./email"
    xtype="textfield"/>
    <mobile
    jcr:primaryType="cq:Widget"
    fieldLabel="Mobile"
    name="./mobile"
    xtype="numberfield"/>
    </items>
    </jcr:root>
    view raw dialog.xml hosted with ❤ by GitHub