Article summary

Summary

Discusses how to build an AEM web site that reqires a user to login to view the content of the web site. Part of following along with this development article involves downloading and building the sample AEM authentication project. 

In addition to reading this article, it is recommended that you also watch the following Ask the AEM Community Experts: Building Secure AEM web sites.  

Digital Marketing Solution(s) Adobe Experience Manager (Adobe CQ)
Audience
Developer (intermediate)
Required Skills
Java, JQuery, AJAX, CSS, Maven, JSON, HTML
Tested On Adobe Experience Manager 6

Download

Introduction

You can create secure Adobe Experience Manager web sites that require users to login in order to view a site's content. AEM supports form-based authentication that requires a web site visitor to enter a user name and password, as shown in the following illustration.

Login

AEM form-based authentication displays a login form (as shown in the previous illustration). When the user fills in the login form and submits the data, AEM stores the successful authentication in a Cookie or an HTTP Session. If the authentication is unsuccessful, then an error message is displayed. 

By default, the URL of a form submission has to end with /j_security_check. That is, a login Form Action can POST to <anything>/j_security_check. For example:

<form action="${homePage.path}/j_security_check

The user name and password names must be j_username and j_password. For example:

<div class="form-group">
<label for="j_username">Username</label> <input type="text"
name="j_username">
</div>
<div class="form-group">
<label for="j_password">Password</label> <input type="password"
name="j_password">
</div>

You can also use two optional parameters:

  • resource – the path to redirect to on a successful login
  • j_validate – used for Ajax logins

When a user logins into AEM, the AEM authentication handler is invoked. You can see the AEM authenticatiion handler using this URL: 

http://localhost:4502/system/console/slingauth

If the user credentials are succecssful, the user is able to view the site's contents.

 

CustomAuthentication3

The following illustration shows how the Sling authentication process works within AEM. 

flow

Note:

For more information about Sling's authentication process, see Authentication.   

Download and build the AEM secure project

Download and build the example AEM secure project that is located from the following GitHub repository:

https://github.com/Adobe-Marketing-Cloud/aem-ask-the-experts-login

Fork the repository to make a copy of it. Download the forked version by using GitHub clone command:

git clone git://<URL TO THE FORKED REPOSITORY>

This command downloads the forked repository to your local Github folder. Now you can use Maven to build and deploy the example AEM secure project to AEM. 

Note:

For more information about setting up Maven, see: Maven in 5 Minutes.

Navigate to your local folder to where the secure AEM project is located. Build and deploy the project by using the following Maven command from the project's root:

mvn -PautoInstallPackage clean install

This command places the project in the apps folder in your local version of AEM, as shown in the following illustration.

Project

Note:

The sample secure AEM application uses the BackBone JavaScript framework. For information, see BackBone

Understanding the sample AEM secure project

At this point, you do not have to do anything but understand the files that make up the sample AEM secure application so you can build your own secure AEM site. The AEM secure sample application is located at /apps/ate-login

The nav.jsp defines the navigation section of the page where the login link is located, as shown in this illustration. 

Nav

When the login link is clicked, the AEM login form appears that lets a web user log into an AEM site, as shown in this illustration.  

Login

The nav.jsp file is located at:

/apps/ate-login/components/page/page/nav.jsp

The following code represents this JSP file. 

<%@page import="com.day.cq.wcm.api.PageFilter,
                java.util.Iterator"%>
<%@include file="/libs/foundation/global.jsp"%>
<%@taglib prefix="personalization" uri="http://www.day.com/taglibs/cq/personalization/1.0" %>
<%
// obtain the site's home page, assume that this is the first level page under /content
Page homePage = currentPage.getAbsoluteParent(1);
Iterator<Page> navPages = homePage.listChildren(new PageFilter());
pageContext.setAttribute("homePage", homePage);
pageContext.setAttribute("navPages", navPages);
%>


<div id="loginModal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="loginModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                <h4 class="modal-title" id="loginModalLabel">AEM Login</h4>
            </div>
            <div class="modal-body">
                <div style="display: none;" id="loginModalRequired" class="alert alert-danger" role="alert">Both username and password are required.</div>
                <div style="display: none;" id="loginModalInvalid" class="alert alert-danger" role="alert">Username and password do not match</div>
                <div style="display: none;" id="loginModalUnknown" class="alert alert-danger" role="alert">Unknown error</div>
                <form id="loginModalForm" method="post" action="${homePage.path}/j_security_check">
                    <div class="form-group">
                        <label for="j_username">Username</label> <input type="text" name="j_username">
                    </div>
                    <div class="form-group">
                        <label for="j_password">Password</label> <input type="password" name="j_password">
                    </div>
                    <input type="hidden" name="resource" value="${currentPage.path}.html"/>
                    <button type="submit">Login</button>
                </form>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn" data-dismiss="modal">Cancel</button>
            </div>
        </div>
    </div>
</div>

<nav class="navbar navbar-inverse navbar-fixed-top">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed"
                data-toggle="collapse" data-target="#navbar"
                aria-expanded="false" aria-controls="navbar">
                <span class="sr-only">Toggle navigation</span> <span
                    class="icon-bar"></span> <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="${homePage.path}.html">ATE Login Session</a>
        </div>
        <div id="navbar" class="collapse navbar-collapse">
            <ul class="nav navbar-nav">
                <li class="${currentPage == homePage ? 'active' : ''}"><a href="${homePage.path}.html">Home</a></li>
                <c:forEach var="navPage" items="${navPages}">
                    <li class="${currentPage == navPage ? 'active' : ''}"><a href="${navPage.path}.html">${navPage.pageTitle ? navPage.pageTitle : navPage.title}</a></li>
                </c:forEach>
            </ul>
            <ul class="nav navbar-nav navbar-right">
                <li class="cq-cc-profile-not-anonymous">
                    <a href="#">
                        <personalization:contextProfileProperty propertyName="givenName" prefix="Hi " suffix="!" store="profile"/>
                    </a>
                </li>
                <li>
                    <a class="cq-cc-profile-anonymous" href="#" data-target="#loginModal" data-toggle="modal">The Login</a>
                    <a class="cq-cc-profile-not-anonymous logout-link" href="/system/sling/logout?resource=${homePage.path}.html">Logout</a>
                </li>
            </ul>
        </div>
    </div>

In this code example, notice that a homePage variable is defined using the return value of the currentPage.getAbsoluteParent(1) method. Now that the homePage variable is defined, it is used in the AEM form-based authentication process. That is, the homePage variable is used in the HTTP Post operation:

<form id="loginModalForm" method="post" action="${homePage.path}/j_security_check">

Also notice that the j_username and j_password are defined as well. 

<div class="form-group">
<label for="j_username">AEM Username</label> <input type="text" name="j_username">
</div>
<div class="form-group">
<label for="j_password">AEM Password</label> <input type="password" name="j_password">
</div>

As mentioned at the start of this development artilce, these values are required when using form-based authentication in AEM. 

The following HTML defines the login link.

<li>
<a class="cq-cc-profile-anonymous" href="#" data-target="#loginModal" data-toggle="modal">The Login</a>
<a class="cq-cc-profile-not-anonymous logout-link" href="/system/sling/logout?resource=${homePage.path}.html">Logout</a>
</li>

When the user clicks the login link, the login form appears. 

Note:

The remaining files are just typical files that you use when creating an AEM application. For example, the body.jsp has statements such as <cq:include script="nav.jsp"/>. If you are unfamiliar with setting up an AEM site, see How to Create a Fully Featured Internet Website

Create a CQ web page that displays the client web page

Create a site that contains a page that is based on the ATE Security - Generic Page (the template that is part of the AEM project you built in this article). When the user clicks the login link and enters valid AEM credentials (for example, admin/admin) the user is logged in and the logout link appears. 

Logout

Create a CQ web page that lets an AEM user login:

  1. Go to the CQ welcome page at http://[host name]:[port]; for example, 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 ATE Security - Generic Page 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. That is, download and build the project.
  6. Open the new page that you created by double-clicking it in the right pane. The new page opens in a web browser.
  7. Add some content to the page. For example, add text and some images. 
  8. Once done adding content to the page, preview the page and click the login link.   

See also

Congratulations, you have just built the sample AEM secure project that shows how to build an AEM application that uses form-based authentication. In additon to understanding the concepts shown in this artilce, it's important to understand the Sling Authentication process. See the link earlier in this development article that references Sling Authentication information.

Please refer to the AEM community page for other 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