Article summary

Summary

Discusses how to create a AEM web page that uses the Google component reCaptcha to include better security.  

 This community article was Inspired by the great community article written by Venkata Subba Rao Adavi. Thank you to the commuity member of the year (2015), Lokesh BS, for testing this article to ensure it works. 

Digital Marketing Solution(s) Adobe Experience Manager (Adobe CQ)
Audience
Developer (intermediate)
Required Skills
Java, OSGi, Maven
AEM Version(s) AEM 6.x
Video https://youtu.be/dBAQPtaTe0M

Introduction

You can use Google reCAPTCHA to your AEM site to protect your website from automated script attacks while letting real users pass through with ease. The reCAPTCHA library is a free service that protects your website from spam and abuse. By using reCAPTCHA, you can improve the security of your AEM site. For more information, see reCAPTCHA.

The following illustration shows reCAPTHCA included within an AEM site. 

client
An AEM web page using recaptcha

As shown in the previous illustration, when using reCAPTCHA, a user is prompted to enter a code into an AEM page. If the code is valid, a message appears. If the user enters an invalid code, a message appears letting the user know an invalid code was entered.

invalid
An invalid code

Create an application folder structure

Create an Experience Manager application folder structure that contains templates, components, and pages by using CRXDE Lite.  

CQAppSetup

The following describes each application folder:

  • application name: contains all of the resources that an application uses. The resources can be templates, pages, components, and so on. 
  • components: contains components that your application uses. 
  • page: contains page components. A page component is a script such as a JSP file.
    global: contains global components that your application uses.
  • template: contains templates on which you base page components. 
  • src: contains source code that comprises an OSGi component (this development article does not create an OSGi bundle using this folder). 
  • install: contains a compiled OSGi bundles container.

To create an application folder structure:

  1. To view the CQ welcome page, enter the URL http://[host name]:[port] into a web browser. For example, http://localhost:4502.
  2. Go to CRXDE Lite at http://localhost:4502/crx/de/index.jsp.
  3. Right-click the apps folder (or the parent folder), select Create, Create Folder.
  4. Enter the folder name into the Create Folder dialog box. Enter recaptcha
  5. Repeat steps 1-4 for each folder specified in the previous illustration. 
  6. Click the Save All button.

 

Note:

You have to click the Save All button when working in CRXDELite for the changes to be made.

Create a template

You can create a template by using CRXDE Lite. A CQ template enables you to define a consistent style for the pages in your application. A template comprises of nodes that specify the page structure. For more information about templates, see Templates.

To create a template, perform these tasks:

1. Go to Select CRXDE Lite at http://localhost:4502/crx/de/index.jsp.
2. Right-click the template folder (within your application), select Create, Create
Template.
3. Enter the following information into the Create Template dialog box:

  • Label: The name of the template to create. Enter capTemplate
  • Title: The title that is assigned to the template.
  • Description: The description that is assigned to the template.
  • Resource Type: The component's path that is assigned to the template and copied to implementing pages. Enter recaptcha/components/page/capTemplate.
  • Ranking: The order (ascending) in which this template will appear in relation to other templates. Setting this value to 1 ensures that the template appears first in the list.

4. Add a path to Allowed Paths. Click on the plus sign and enter the following value: /content(/.*)?.
5. Click Next for Allowed Parents.
6. Select OK on Allowed Children.
 

Create a Page Rendering Component

Components are re-usable modules that implement specific application logic to render the content of your web site. You can think of a component as a collection of scripts (for example, JSPs, Java servlets, and so on) that completely realize a specific function. In order to realize this functionality, it is your responsibility as a CQ developer to create scripts that perform specific functionality. For more information about components, see Components.

By default, a component has at least one default script, identical to the name of the component. To create a render component, perform these tasks:

1. Go to Select CRXDE Lite at http://localhost:4502/crx/de/index.jsp.
2. Right-click /apps/recaptcha/components/page, then select Create, Create Component.
3. Enter the following information into the Create Component dialog box:

  • Label: The name of the component to create. Enter capTemplate
  • Title: The title that is assigned to the component.
  • Description: The description that is assigned to the template.
  • Super Type: foundation/components/page (in AEM 6, you specify this value for page components. In previous versions of AEM, this was not required.)

4. Select Next for Advanced Component Settings and Allowed Parents.
5. Select OK on Allowed Children.
6. Open the capTemplateJCR.jsp located at: /apps/recaptcha/components/page/capTemplate/capTemplate.jsp.
7. Enter the following JSP code.

<html>
<head>
<title>Hello World !!!</title>
</head>
<body>
<h1>Hello reCAPTCHA!!!</h1>
<h2>This page will use reCAPTHA</h2>
</body>
</html>

Add the reCapthca JAR file to the AEM service container

Download the recaptcha4j-0.0.7.jar from Maven at the following URL:

https://mvnrepository.com/artifact/net.tanesha.recaptcha4j/recaptcha4j/0.0.7

You need to wrap this JAR file into an OSGi bundle and deploy it to the AEM service container. Perform these tasks:

1. Start Eclipse (the Indigo version works the best). The steps below have been tested on Eclipse Java EE IDE for Web Developers version Indigo Service Release 1.

2. Select File, New, Other.

3. Under the Plug-in Development folder, choose Plug-in from Existing JAR Archives. Name your project recapBundle.

4. In the JAR selection dialog, click the Add external button, and browse to the recaptcha4j-0.0.7.jar file that you downloaded.

5. Click Next.

6. In the Plug-in Project properties dialog, ensure that you check the checkbox for Analyze library contents and add dependencies.

7. Make sure that the Target Platform is the standard OSGi framework.

8. Ensure the checkboxes for Unzip the JAR archives into the project and Update references to the JAR files are both checked.

9. Click Next, and then Finish.

10. Click the Runtime tab.

11. Make sure that the Exported Packages list is populated.

12. Make sure these packages have been added under the Export-Package header in MANIFEST.MF. Remove the version information in the MANIFEST.MF file. Version numbers can cause conflicts when you upload the OSGi bundle.

13. Also make sure that the Import-Package header in MANIFEST.MF is also populated, as shown here (notice that Export-Package is net.tanesha.recaptcha).

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Recap
Bundle-SymbolicName: recap
Bundle-Version: 1.0.0
Export-Package: net.tanesha.recaptcha,
net.tanesha.recaptcha.http
Bundle-RequiredExecutionEnvironment: JavaSE-1.7

14. Save the project.

15. Build the OSGi bundle by right-clicking the project in the left pane, choose Export, Plug-in Development, Deployable plug-ins and fragments, and click Next.

16. Select a location for the export (C:\TEMP) and click Finish. (Ignore any error messages).

17. In C:\TEMP\plugins, you should now find the OSGi bundle.

18. Login to Apache Felix Web Console at http://server:port/system/console/bundles (default admin user = admin with password= admin).

19. Sort the bundle list by Id and note the Id of the last bundle.

20. Click the Install/Update button.

21. Check the Start Bundle checkbox.

22. Browse to the bundle JAR file you just built. (C:\TEMP\plugins).

23. Click Install.

24. Click the Refresh Packages button.

25. Check the bundle with the highest Id.

26. Your new bundle should now be listed with the status Active.

27. If the status is not Active, check the error.log for exceptions. If you get “org.osgi.framework.BundleException: Unresolved constraint” errors, check the MANIFEST.MF for strict version requirements which might follow: javax.xml.namespace; version=”3.1.0”

28. If the version requirement causes problems, remove it so that the entry looks like this: javax.xml.namespace.

29. If the entry is not required, remove it entirely.

30. Rebuild the bundle.

31. Delete the previous bundle and deploy the new one.

You will see the OSGi bundle fragment in an Active state, as shown in the following illustration.

OSGI
An OSGi bundle in a running state

Get Public and Private Keys to use Google reCaptcha

You need to get both a public and private key value from the reCAPTCHA admin site at:

https://www.google.com/recaptcha/admin#list

Enter the domain of your site in the first field, as shown below.

regKeys
Admin site

After you successfully register your domain, you will receive both a pubic and prviate key value that you need to use in your AEM component script. The following illustration shows these key values.

keys
Public and private reCAPTCHA keys

In the previous illustration, notice that there are two key values. You need both of these values. As well, notice the script tags. You need to place these script tags in your AEM component script (this is shown later in this article).

Note:

If you are testing AEM on localhost, you need to register localhost as well in order for reCAPTCHA to work.

Add reCaptcha logic to the capTemplate JSP

Modify the capTemplate.JSP to add logic required to use the Google reCaptcha component in an AEM page component. Add the following code to the capTemplate.jsp located at /apps/recaptcha/components/page/capTemplate.

<%@include file="/libs/foundation/global.jsp"%>
<%@ page import="net.tanesha.recaptcha.ReCaptcha" %>
<%@ page import="net.tanesha.recaptcha.*" %>
<script src='https://www.google.com/recaptcha/api.js'></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>

<%
    //Getting remote ip addres to validate catpcha 
    String ipAddress = request.getHeader("X-FORWARDED-FOR");  
    if (ipAddress == null) {  
   ipAddress = request.getRemoteAddr();  
   } 

 %>
    <input type="hidden" value="<%=ipAddress%>" id="remoteIPAdderess" >
    <input type="hidden" value="<%=currentNode.getPath()%>" id="curNodePath" >
    <% ReCaptcha reCaptcha = ReCaptchaFactory.newReCaptcha("<Public Key>", "<Private Key>",false); %>
    
    <h1 id="page-title" class="title">Google Captch Integration in CQ</h1>
    <form accept-charset="UTF-8" id="testCaptcha" method="post" action="" class="contact-press-form ajax-form">
        <div id="gooleCaptcha">
            <input type="hidden" value="form-U5ArplaaF5MKYCMnyZkQDZfvXEy7bO7JLc5e6VCKses"  name="form_build_id"> 
            <input type="hidden" value="apollocontactpress_contact_form" name="form_id">
    
            <fieldset class="captcha form-wrapper">
                <legend>
                    <span class="fieldset-legend">CAPTCHA</span>
                </legend>
                <div class="fieldset-wrapper form-item form-item-captcha">
                    <%=reCaptcha.createRecaptchaHtml(null, "clean", null) %>
                    <div class="error-message"></div>
                </div>
            </fieldset>
            <input type="button" id="test" class='testCaptcha' value="test">
        </div>
        <div class="g-recaptcha" data-sitekey="6LeSxQcUAAAAADn_Jr46GP-JnieZ0c58BElK8xwn"></div>
    </form>

<script>

$(function() { 
  
  $('#gooleCaptcha').on('click','.testCaptcha',function(){
       alert("redy captch integration");
       var cpatchaFlag = false;
        var remoteIP=$('#remoteIPAdderess').val();
        var currentNodePath = $("#curNodePath").val();         
        var captchaField = $('#recaptcha_response_field');
        var capResponse=$('#recaptcha_response_field').val();
        var capChallange=$('#recaptcha_challenge_field').val();                 
        var captchValUrl=currentNodePath+'.validatecaptcha.html';
        if($.trim(capResponse).length === 0){
   alert("response is empty");
  }else{  
            var isValidCaptcha="";
            $.ajax({                          
                url: captchValUrl,
                async: false,
                data: {'remoteAddr':remoteIP,'recaptcha_response_field' : capResponse,'recaptcha_challenge_field':capChallange},
                success: function (response, status, xml) {
                    isValidCaptcha=response;
                }
            });
            
            if($.trim(isValidCaptcha) === 'true'){ 
                alert("valid captcha");
                $('#recaptcha_response_field').css({border : '1px solid black !important'});
            }else{
                alert("invalid captcha");
                $('#recaptcha_response_field').css({border : '1px solid red !important'});
            }
            
        }
  });  
});
    </script>

On line 17, notice there is a placeholder for Public and Private key values:

<% ReCaptcha reCaptcha = ReCaptchaFactory.newReCaptcha("<Public Key>", "<Private Key>", false); %>

Replace these placeholders with the key values that you retrieved when you registered your domain.  

Validate Captcha

To validate the Captcha component, create a validatecaptcha.jsp at this location:

/apps/recaptcha/components/page/capTemplate

Add this JSP code to the file. (You can add code to this JSP to meet your business requirements.)

<%@include file="/libs/foundation/global.jsp"%>
<%@ page import="net.tanesha.recaptcha.ReCaptcha" %>
<%@ page import="net.tanesha.recaptcha.*" %>
<%
 ReCaptchaImpl reCaptcha = new ReCaptchaImpl();
 reCaptcha.setPrivateKey("<Private Key>");
 String remoteAddr =  request.getParameter("remoteAddr");
 String challenge = request.getParameter("recaptcha_challenge_field");
 String uresponse = request.getParameter("recaptcha_response_field");
 ReCaptchaResponse reCaptchaResponse = reCaptcha.checkAnswer(remoteAddr, challenge, uresponse);
 
 if (reCaptchaResponse.isValid()) {
    out.print("true");
    log.info("valid capticha");
 } else {
    out.print("false");
    log.info("invalid capticha");
 }
 
%>

Note:

On line 6, enter your private key value as the parameter for the setPrivateKey method.  

Create a page that displays data retrieved from the KeyService

The final task that you perform in order to see a web page that uses the reCaptcha component is to create an AEM page that is based on the capTemplate (the template created earlier in this development article).

client
A reCaptcha component shown in an AEM web page

To create a web page that displays a reCaptcha component, perform these tasks:

  1. To view the CQ Websites page, enter the URL http://localhost:4502/siteadmin#/content.
  2. Select New, New Page.
  3. Specify the title of the page in the Title field.
  4. Specify the name of the page in the Name field.
  5. Select capTemplate from the template list that appears. This value represents the template that is created in this development article. If you do not see it, then repeat the steps in this development article. For example, if you made a typing mistake when entering in path information when creating the template, the template will not show up in the New Page dialog box.
  6. Open the new page that you created by double-clicking it in the right pane. The new page opens in a web browser. You should see a page displaying data similar to the previous illustration.

See also

Congratulations, you have just created a basic custom AEM Service by using Maven Adobe Archetype project. Please refer to the AEM community page for more articles that discuss how to build AEM services/applications.

This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License  Twitter™ and Facebook posts are not covered under the terms of Creative Commons.

Legal Notices   |   Online Privacy Policy