Use Case:
1) You want to create a custom login module in CQ / AEM
2) You already have a custom login module in CQ5.4 and integrate it with CQ5.5
Prerequisite: Please check http://dev.day.com/content/kb/home/cq5/CQ5Troubleshooting/cq55prerelease-installandconfigchanges.html
Solution:
CQ 5.6 and less
Any custom login module should be added in CQ5.6 and less as a JAAS module. That mean CQ should have access to module during load time.
Here is set of steps you might have to do to create custom login module
1) Create a OSGI bundle with class that extend Jackrabbit AbstarctLoginModule (Example http://wemcode.wemblog.com/custom-login-module)
2) Create bundle as frangment bundle attached it to com.day.crx.sling.server
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Import-Package>!com.day.crx.core.token,!org.apache.jackrabbit.*,*</Import-Package>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Export-Package>....... Package you want to export .... </Export-Package>
<Fragment-Host>com.day.crx.sling.server</Fragment-Host>
<Bundle-Name>${project.name}</Bundle-Name>
<Bundle-Description>${project.description}</Bundle-Description>
<Bundle-Version>${project.version}</Bundle-Version>
<Include-Resource>lib=${basedir}/lib</Include-Resource>
<Bundle-ClassPath>
.,
lib/<Your custom jar file>.jar,
</Bundle-ClassPath>
</instructions>
</configuration>
</plugin>
3) Deploy and start your bundle as start level 15. You can do following things for that
curl -u admin:admin -T <Your custom module bundle>.jar http://<host>:<port>/apps/<Your path>/install/15/<Your login module>.jar
Or
<profiles>
<profile>
<id>install-packages</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.sling</groupId>
<artifactId>maven-sling-plugin</artifactId>
<executions>
<execution>
<id>install-package</id>
<goals>
<goal>install</goal>
</goals>
<configuration>
<slingUrl>${crx.url}/system/console/install</slingUrl>
<user>${crx.user}</user>
<password>${crx.password}</password>
<bundleStartLevel>15</bundleStartLevel>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
4) Change repository.xml
Open the file crx-quickstart/repository/repository.xml (on the server's filesystem) and remove the <LoginModule>...</LoginModule> element.
Find the <SecurityManager> element and add the WorkspaceAccessManager as shown below:
<SecurityManager class="com.day.crx.core.CRXSecurityManager">
<WorkspaceAccessManager class="org.apache.jackrabbit.core.security.simple.SimpleWorkspaceAccessManager"/>
<UserManager class="com.day.crx.core.CRXUserManagerImpl">
<param name="usersPath" value="/home/users"/>
<param name="groupsPath" value="/home/groups"/>
<param name="defaultDepth" value="1"/>
</UserManager>
</SecurityManager>
5) Create custom jaas config
Now create the file crx-quickstart/conf/jaas.conf. In this file you would have something like this:
com.day.crx {
<Your login Module class name> sufficient
com.day.crx.core.CRXLoginModule sufficient;
};
6) Change start up script
Update your crx-quickstart/bin/start script with this jvm parameter (Replace /path/to/your/jaas.conf with the real path to the jaas.conf file):
-Djava.security.auth.login.config=/path/to/your/jaas.conf
1) You want to create a custom login module in CQ / AEM
2) You already have a custom login module in CQ5.4 and integrate it with CQ5.5
Prerequisite: Please check http://dev.day.com/content/kb/home/cq5/CQ5Troubleshooting/cq55prerelease-installandconfigchanges.html
Solution:
CQ 5.6 and less
Any custom login module should be added in CQ5.6 and less as a JAAS module. That mean CQ should have access to module during load time.
Here is set of steps you might have to do to create custom login module
1) Create a OSGI bundle with class that extend Jackrabbit AbstarctLoginModule (Example http://wemcode.wemblog.com/custom-login-module)
2) Create bundle as frangment bundle attached it to com.day.crx.sling.server
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Import-Package>!com.day.crx.core.token,!org.apache.jackrabbit.*,*</Import-Package>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Export-Package>....... Package you want to export .... </Export-Package>
<Fragment-Host>com.day.crx.sling.server</Fragment-Host>
<Bundle-Name>${project.name}</Bundle-Name>
<Bundle-Description>${project.description}</Bundle-Description>
<Bundle-Version>${project.version}</Bundle-Version>
<Include-Resource>lib=${basedir}/lib</Include-Resource>
<Bundle-ClassPath>
.,
lib/<Your custom jar file>.jar,
</Bundle-ClassPath>
</instructions>
</configuration>
</plugin>
3) Deploy and start your bundle as start level 15. You can do following things for that
curl -u admin:admin -T <Your custom module bundle>.jar http://<host>:<port>/apps/<Your path>/install/15/<Your login module>.jar
Or
<profiles>
<profile>
<id>install-packages</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.sling</groupId>
<artifactId>maven-sling-plugin</artifactId>
<executions>
<execution>
<id>install-package</id>
<goals>
<goal>install</goal>
</goals>
<configuration>
<slingUrl>${crx.url}/system/console/install</slingUrl>
<user>${crx.user}</user>
<password>${crx.password}</password>
<bundleStartLevel>15</bundleStartLevel>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
4) Change repository.xml
Open the file crx-quickstart/repository/repository.xml (on the server's filesystem) and remove the <LoginModule>...</LoginModule> element.
Find the <SecurityManager> element and add the WorkspaceAccessManager as shown below:
<SecurityManager class="com.day.crx.core.CRXSecurityManager">
<WorkspaceAccessManager class="org.apache.jackrabbit.core.security.simple.SimpleWorkspaceAccessManager"/>
<UserManager class="com.day.crx.core.CRXUserManagerImpl">
<param name="usersPath" value="/home/users"/>
<param name="groupsPath" value="/home/groups"/>
<param name="defaultDepth" value="1"/>
</UserManager>
</SecurityManager>
5) Create custom jaas config
Now create the file crx-quickstart/conf/jaas.conf. In this file you would have something like this:
com.day.crx {
<Your login Module class name> sufficient
com.day.crx.core.CRXLoginModule sufficient;
};
6) Change start up script
Update your crx-quickstart/bin/start script with this jvm parameter (Replace /path/to/your/jaas.conf with the real path to the jaas.conf file):
-Djava.security.auth.login.config=/path/to/your/jaas.conf
7) Restart your CQ
Note: if you already have Non osgi version of your custom login module, You can use http://www.wemblog.com/2012/04/how-to-integrate-3rd-party-jar-file-in.html to convert to OSGI bundle. Make sure that you follow step 2.
To debug custom login module, you can follow steps mention in http://www.wemblog.com/2011/09/how-to-set-up-debug-mode-for.html
Note that LDAP login module com.day.crx.security.ldap.LDAPLoginModule in CQ is good example of custom Login Module.
AEM / CQ 6
From CQ6 onward, Login module can now be configured as pluggable login module in OSGI. To implement Login Module in CQ6 onward you can
Option 1:
implement org.apache.sling.jcr.jackrabbit.server.security.LoginModulePlugin Here is example of Pluggable Login Module with Authentication handler http://svn.apache.org/repos/asf/sling/trunk/bundles/auth/form/src/main/java/org/apache/sling/auth/form/impl/
More info: https://sling.apache.org/documentation/the-sling-engine/authentication/authentication-authenticationhandler/form-based-authenticationhandler.html
Option 2:
You can also use OAK external Login Module https://github.com/apache/jackrabbit-oak/tree/trunk/oak-auth-external To create custom login module (Which you register and service) as well. Example of that would be LDAP Login Module in AEM6 https://github.com/apache/jackrabbit-oak/tree/trunk/oak-auth-ldap
Here is one more example of how to use this in AEM 6 onward: https://helpx.adobe.com/experience-manager/using/oak-login.html
You do not have to restart your instance after creating custom login module in AEM 6.
To debug custom login module, you can follow steps mention in http://www.wemblog.com/2011/09/how-to-set-up-debug-mode-for.html
Note that LDAP login module com.day.crx.security.ldap.LDAPLoginModule in CQ is good example of custom Login Module.
AEM / CQ 6
From CQ6 onward, Login module can now be configured as pluggable login module in OSGI. To implement Login Module in CQ6 onward you can
Option 1:
implement org.apache.sling.jcr.jackrabbit.server.security.LoginModulePlugin Here is example of Pluggable Login Module with Authentication handler http://svn.apache.org/repos/asf/sling/trunk/bundles/auth/form/src/main/java/org/apache/sling/auth/form/impl/
More info: https://sling.apache.org/documentation/the-sling-engine/authentication/authentication-authenticationhandler/form-based-authenticationhandler.html
Option 2:
You can also use OAK external Login Module https://github.com/apache/jackrabbit-oak/tree/trunk/oak-auth-external To create custom login module (Which you register and service) as well. Example of that would be LDAP Login Module in AEM6 https://github.com/apache/jackrabbit-oak/tree/trunk/oak-auth-ldap
Here is one more example of how to use this in AEM 6 onward: https://helpx.adobe.com/experience-manager/using/oak-login.html
You do not have to restart your instance after creating custom login module in AEM 6.
Hi,
ReplyDeleteDoes this work for CQ5.4 too? Or do you know how to write a custom login module for CQ5.4?
Kind regards, Christoph
I doubt (As in CQ5.4 CRX starts up before launchpad and hence OSGI). In CQ5.4 you have to put non OSGI version of jar file under crx libs directory in file system.
DeleteI'm confused of Sling AuthenticationHandler Interface with Custom Login Module. Are they the same thing, or are they completely different for what they are meant to solve?
ReplyDeleteCharles,
DeleteThere are two things,
1) Login Module (Example LDAP Login Module in CQ, Used for user synching and Password verification)
2) Authentication Handler (Example SlingAuthentication handler, FormBasedAuthenticationHandler etc in CQ)
Sling Authentication handler is one of the example of custom Authentication Handler that CQ uses. Here is source code for that http://svn.apache.org/repos/asf/sling/trunk/bundles/auth/core/src/main/java/org/apache/sling/auth/core/
So suppose you have third party system to get user/group data then,
1) you will use Login Module to sync data from third party system
2) and custom authentication handler to authenticate against your third party system
Hope it make sense
Yogesh
Thanks Yogesh. To further understand your points, what should I read to know more about how exactly a Login Module works and how to develop one? and how adding a Login Module to CQ means in terms of its interaction with Authentication Handler. I think I'm lack of the overall basic picture thus having difficulty understanding.
DeleteSay I'd like to have a 3rd party (instead of CQ logon page) to authentication users (authors, writers, etc.). On success, redirect the authenticated user back to CQ with the user id and from there the CQ will continue to authorize the user according to the ACL in CRX. How would I achieve that?
Charles,
DeleteYou can have your custom login module to interact with third party system to sync user / Group, For that follow above process and override AbstractLoginModule methods to have custom user / group sync.
I will create a post for creating custom authentication handler soon.
Yogesh
See http://www.wemblog.com/2013/03/how-to-create-custom-authentication.html
DeleteYogesh
Hi Yogesh,
ReplyDeleteCan you also provide a sample for LDAP configuration with CQ in your style? you make it really easy to understand things?
Runal,
DeleteSample "Login Module" conf will look like this
com.day.crx {
com.day.crx.core.CRXLoginModule sufficient
disableNTLMAuth="true"
tokenExpiration="43200000";
required
autocreate.user.emailAddress="profile/email"
autocreate.user.firstName="profile/givenName"
autocreate.user.lastName="profile/familyName"
autocreate.user.companyName="profile/companyName"
autocreate.user.ID="profile/myid"
autocreate.user.locale="preferences/toolboxLanguage"
autocreate.user.customerID="profile/organizationId"
cacheMaxSize="10000"
cache.expiration="86400"
cache.maxsize="6000";
};
This is nice article. It seems we can configure multiple LoginModule but how do we configure which module to use for different authentication handler.
ReplyDeleteHello,
DeleteYou need to bind your login module to appropriate authentication handler for this. That happen in activate method of authentication handler.
Here is example,
@Activate
protected void activate(ComponentContext componentContext) {
context = componentContext;
Dictionary props = context.getProperties();
facebookIdAttribute = OsgiUtil.toString(props.get(PROP_FACEBOOK_ID_USER_ATTR), DEFAULT_FACEBOOK_ID_USER_ATTR);
this.loginModule = null;
try {
this.loginModule = FaceBookLoginModule.register(this, componentContext.getBundleContext());
} catch (Throwable t) {
log.info("Cannot register FaceBookLoginModulePlugin. This is expected if Sling LoginModulePlugin services are not supported");
log.debug("dump", t);
}
}
My requirement is, user will enter userid in CQ based form and this userid will be validated by 3rd party system using REST call from CQ. Now once user is validated in 3rd party system then user should be able to login to CQ. We do not store user information in CQ.
ReplyDeleteSo, for the purpose of implementation I was thinking about a custom login module or a custom authentication handler, but I am confused on which one to implement.
Best regards,
Sam
Hello Sam,
DeleteThis is common use case. In this case you will authenticate against third party system using protocol they are using and then skip sync using login module. Here is relevant example http://www.wemblog.com/2013/03/how-to-create-custom-authentication.html pay attention to authSucceded method.
Yogesh
Hi,
ReplyDeleteLooking to configure Login Module in AEM6. http://svn.apache.org/repos/asf/sling/trunk/bundles/auth/openid/src/main/java/org/apache/sling/auth/openid/impl/ is not working. Can you please provide an alternative.
Here is example http://www.wemblog.com/2012/04/how-to-use-ldap-with-cq55.html check AEM 6 section. Note that LDAP is one of OOTB login module. If you have custom login module then you have to create first and then register it using above method.
DeleteYogesh
Hi Yogesh,
ReplyDeletethanks a lot for your article!
Is it also possible to authenticate external Users and dont sync them with the Repository, e.g. prevent Synchronization?
Hello,
DeleteYes, In that case you would just use authentication handler as mentioned in http://www.wemblog.com/2013/03/how-to-create-custom-authentication.html
Yogesh
Hello Yogesh,
Deletemany thanks for your reply!
Is this also the solution to accept Users from 3rd Party, e.g having stored them an own node of JCR-Repository?
The LoginModulePlugin is not supported by AEM. Do you have another solution?