Initially, the available login IDs are admin, secofr, and john,
and the passwords are the same as the login ID.
A page can be made secure, ie. accessible only by HTTPS, by annotating the page's class with @Secure .
You will also have to enable HTTPS on your web server, which may require some configuration.
References: Securing your application with HTTPS, How to enable SSL on JBoss.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- We need a doctype to allow us to use special characters like &nbsp; 
     We use a "strict" DTD to make IE follow the alignment rules. -->

<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd">

<body class="container">

    <div id="page">

        <div class="row" id="instructions">
            Initially, the available login IDs are admin, secofr, and john, <br /> and the passwords are the same as the login
            ID.
        </div>

        <div class="row">
            <div class="col-sm-6 col-sm-offset-3">

                <t:form t:id="login" class="form-signin">

                    <div class="row">
                        <div class="col-sm-10 col-sm-offset-1">

                            <h2 class="form-signin-heading">Log In</h2>

                            <div class="form-group">
                                <t:textfield t:id="loginId" class="input-medium" maxLength="15" t:validate="required, maxLength=15"
                                    placeholder="Login ID" />
                            </div>

                            <div class="form-group">
                                <t:passwordfield t:id="password" class="input-medium" maxLength="15" t:validate="required, maxLength=15"
                                    placeholder="Password" />
                            </div>

                            <div class="form-group">
                                <t:submit value="Login" class="btn btn-lg btn-primary" />
                                <t:eventlink event="GoHome" style="margin-left: 12px;">Home</t:eventlink>
                            </div>

                            <t:errors globalOnly="true" />
                        </div>
                    </div>

                </t:form>
            </div>
        </div>

        <div class="row" id="secure">
            A page can be made secure, ie. accessible only by HTTPS, by annotating the page's class with
            <code>@Secure</code>
            .<br /> You will also have to enable HTTPS on your web server, which may require some configuration.<br />
            References: <a href="http://tapestry.apache.org/https.html">Securing your application with HTTPS</a>, <a
                href="http://roneiv.wordpress.com/2008/01/03/jboss-tutorial-how-to-enable-ssl-https-on-jboss-as-well-as-other-nice-to-know-configurations/">How
                to enable SSL on JBoss</a>.
        </div>
        
        <div class="row" id="links">
            <t:pagelink page="examples/state/displaysessioncontents">Display Session Contents</t:pagelink>
        </div>
        
    </div>

    <t:tabgroup>
        <t:sourcecodetab src="/web/src/main/java/jumpstart/web/pages/theapp/LogIn.tml" />
        <t:sourcecodetab src="/web/src/main/java/jumpstart/web/pages/theapp/LogIn.java" />
        <t:sourcecodetab src="/web/src/main/java/jumpstart/web/commons/IIntermediatePage.java" />
        <t:sourcecodetab src="/web/src/main/resources/META-INF/assets/css/theapp/login.css" />
        <t:sourcecodetab src="/web/src/main/java/jumpstart/web/state/theapp/Visit.java" />
        <t:sourcecodetab src="/web/src/main/java/jumpstart/web/base/theapp/SimpleBasePage.java" />
    </t:tabgroup>
    
</body>
</html>


package jumpstart.web.pages.theapp;

import javax.ejb.EJB;

import jumpstart.business.commons.exception.BusinessException;
import jumpstart.business.domain.security.User;
import jumpstart.business.domain.security.iface.ISecurityFinderServiceLocal;
import jumpstart.util.ExceptionUtil;
import jumpstart.web.base.theapp.SimpleBasePage;
import jumpstart.web.commons.IIntermediatePage;
import jumpstart.web.pages.Index;
import jumpstart.web.state.theapp.Visit;

import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.Link;
import org.apache.tapestry5.annotations.Import;
import org.apache.tapestry5.annotations.InjectComponent;
import org.apache.tapestry5.annotations.InjectPage;
import org.apache.tapestry5.annotations.Persist;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.corelib.components.Form;
import org.apache.tapestry5.corelib.components.TextField;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.slf4j.Logger;

// To make this page accessible only by HTTPS, annotate it with @Secure and ensure your web server can deliver HTTPS.
// See http://tapestry.apache.org/secure.html .
// @Secure
@Import(stylesheet = "css/theapp/login.css")
public class LogIn extends SimpleBasePage implements IIntermediatePage {

    // The activation context

    @Property
    private String loginId;

    // Screen fields

    @Property
    private String password;

    // Generally useful bits and pieces

    @Persist
    private Link nextPageLink;

    @InjectComponent("login")
    private Form form;

    @InjectComponent("loginId")
    private TextField loginIdField;

    @Inject
    private Logger logger;

    @Inject
    private ComponentResources componentResources;

    @EJB
    private ISecurityFinderServiceLocal securityFinderService;

    @InjectPage
    private UserView userViewPage;

    // The code

    @Override
    public void setNextPageLink(Link nextPageLink) {
        this.nextPageLink = nextPageLink;
    }

    void onActivate(String loginId) {
        this.loginId = loginId;
    }

    String onPassivate() {
        return loginId;
    }

    void onValidateFromLogin() {

        if (form.getHasErrors()) {
            // We get here only if a server-side validator detected an error.
            return;
        }

        try {
            // Authenticate the user

            User user = securityFinderService.authenticateUser(loginId, password);

            // Store the user in the Visit

            setVisit(new Visit(user));
            logger.info(user.getLoginId() + " has logged in.");
        }
        catch (BusinessException e) {
            form.recordError(loginIdField, e.getLocalizedMessage());
        }
        catch (Exception e) {
            logger.error("Could not log in.  Stack trace follows...");
            logger.error(ExceptionUtil.printStackTrace(e));
            form.recordError(getMessages().get("login_problem"));
        }
    }

    Object onSuccess() {

        if (nextPageLink == null) {
            // return Welcome.class;
            userViewPage.set(getVisit().getMyUserId());
            return userViewPage;
        }
        else {
            componentResources.discardPersistentFieldChanges();
            return nextPageLink;
        }

    }

    Object onGoHome() {
        componentResources.discardPersistentFieldChanges();
        return Index.class;
    }

}


package jumpstart.web.commons;

import org.apache.tapestry5.Link;

public interface IIntermediatePage {
    
    void setNextPageLink(Link nextPageLink);

}


body {
                Zpadding-top: 40px;
                Zpadding-bottom: 40px;
                Zbackground-color: #f5f5f5;
}

#page {
                margin: 0 auto;
                padding: 20px;
                background-color: #ffffff;
                filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f4f4f4',
                                endColorstr='#ffffff'); /* for IE */
                background: -webkit-gradient(linear, left top, left bottom, from(#eaeaea),
                                to(#ffffff)); /* for webkit browsers */
                background: -moz-linear-gradient(top, #f2f2f2, #ffffff);
                /* for firefox 3.6+ */;
}

#instructions {
                padding: 40px 0 40px;
                text-align: center;
                color: #666;
}

.form-signin {
                max-width: 300px;
                padding: 19px 29px 29px;
                margin: 0 auto;
                background-color: #fff;
                border: 1px solid #e5e5e5;
                -webkit-border-radius: 5px;
                -moz-border-radius: 5px;
                border-radius: 5px;
                -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
                -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
                box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
}

.form-signin .form-signin-heading,.form-signin .checkbox {
                margin-bottom: 10px;
}

.form-signin input[type="text"],.form-signin input[type="password"] {
                font-size: 16px;
                height: auto;
                margin-bottom: 6px;
                padding: 7px 9px;
}

#secure {
                padding: 40px 0 40px;
                text-align: center;
                color: #666;
}

#links {
                padding: 0px 0 40px;
                text-align: center;
                color: #666;
}


package jumpstart.web.state.theapp;

import java.io.Serializable;

import jumpstart.business.domain.security.User;
import jumpstart.business.domain.security.User.PageStyle;

@SuppressWarnings("serial")
public class Visit implements Serializable {

    private Long myUserId = null;
    private String myLoginId = null;
    private PageStyle pageStyle = null;
    private String dateInputPattern = null;
    private String dateViewPattern = null;
    private String dateListPattern = null;
    
    public Visit(User user) {
        myUserId = user.getId();
        cacheUsefulStuff(user);
    }

    public void noteChanges(User user) {
        if (user == null) {
            throw new IllegalArgumentException();
        }
        else if (user.getId().equals(myUserId)) {
            cacheUsefulStuff(user);
        }
    }

    private void cacheUsefulStuff(User user) {
        myLoginId = user.getLoginId();
        pageStyle = user.getPageStyle();
        dateInputPattern = user.getDateInputPattern();
        dateViewPattern = user.getDateViewPattern();
        dateListPattern = user.getDateListPattern();
    }

    public Long getMyUserId() {
        return myUserId;
    }

    public String getMyLoginId() {
        return myLoginId;
    }

    public PageStyle getPageStyle() {
        return pageStyle;
    }

    public String getDateInputPattern() {
        return dateInputPattern;
    }

    public String getDateViewPattern() {
        return dateViewPattern;
    }

    public String getDateListPattern() {
        return dateListPattern;
    }

}


package jumpstart.web.base.theapp;

import java.text.DateFormat;
import java.text.SimpleDateFormat;

import jumpstart.business.commons.exception.BusinessException;
import jumpstart.business.commons.exception.CannotDeleteIsReferencedException;
import jumpstart.business.commons.exception.DuplicateAlternateKeyException;
import jumpstart.business.commons.exception.DuplicatePrimaryKeyException;
import jumpstart.business.commons.exception.OptimisticLockException;
import jumpstart.business.commons.interpreter.BusinessServiceExceptionInterpreter;
import jumpstart.business.domain.security.User;
import jumpstart.web.state.theapp.Visit;

import org.apache.tapestry5.annotations.SessionState;
import org.apache.tapestry5.ioc.Messages;
import org.apache.tapestry5.ioc.annotations.Inject;

public class SimpleBasePage {

    // @SessionState is explained in http://tapestry.apache.org/session-storage.html
    @SessionState
    private Visit visit;
    private boolean visitExists;

    private BusinessServiceExceptionInterpreter businessServiceExceptionInterpreter = new BusinessServiceExceptionInterpreter();

    @Inject
    private Messages messages;

    protected Messages getMessages() {
        return messages;
    }

    public Visit getVisit() {
        return visit;
    }

    protected void setVisit(Visit visit) {
        this.visit = visit;
    }
    
    public boolean isVisitExists() {
        return visitExists;
    }

    public String getDateInputPattern() {
        return visitExists ? visit.getDateInputPattern() : User.defaultDateInputPattern;
    }

    public String getDateViewPattern() {
        return visitExists ? visit.getDateViewPattern() : User.defaultDateViewPattern;
    }

    public String getDateListPattern() {
        return visitExists ? visit.getDateListPattern() : User.defaultDateListPattern;
    }
    
    public DateFormat getDateInputFormat() {
        // If you want to make this static or move it into Visit, first read
        // http://thread.gmane.org/gmane.comp.java.tapestry.user/20925
        return new SimpleDateFormat(visit.getDateInputPattern());
    }

    public DateFormat getDateViewFormat() {
        // If you want to make this static or move it into Visit, first read
        // http://thread.gmane.org/gmane.comp.java.tapestry.user/20925
        return new SimpleDateFormat(visit.getDateViewPattern());
    }

    public DateFormat getDateListFormat() {
        // If you want to make this static or move it into Visit, first read
        // http://thread.gmane.org/gmane.comp.java.tapestry.user/20925
        return new SimpleDateFormat(visit.getDateListPattern());
    }

    protected String interpretBusinessServicesExceptionForCreate(Exception e) {
        String message = "";
        BusinessException x = businessServiceExceptionInterpreter.interpret(e);

        if (x instanceof DuplicatePrimaryKeyException) {
            message = getMessages().get("create_failed_duplicate_primary_key");
        }
        else if (x instanceof DuplicateAlternateKeyException) {
            DuplicateAlternateKeyException d = (DuplicateAlternateKeyException) x;
            message = getMessages().format("create_failed_duplicate_alternate_key", d.getTechnicalMessageText());
        }
        else {
            message = x.getMessage();
        }
        return message;
    }
    
    protected BusinessException interpretBusinessServicesException(Exception e) {
        return businessServiceExceptionInterpreter.interpret(e);
    }

    protected String interpretBusinessServicesExceptionForAdd(Exception e) {
        String message = "";
        BusinessException x = businessServiceExceptionInterpreter.interpret(e);

        if (x instanceof OptimisticLockException) {
            message = getMessages().get("add_failed_optimistic_lock");
        }
        else if (x instanceof DuplicatePrimaryKeyException) {
            message = getMessages().get("add_failed_duplicate_primary_key");
        }
        else if (x instanceof DuplicateAlternateKeyException) {
            DuplicateAlternateKeyException d = (DuplicateAlternateKeyException) x;
            message = getMessages().format("add_failed_duplicate_alternate_key", d.getTechnicalMessageText());
        }
        else {
            message = x.getMessage();
        }
        return message;
    }

    protected String interpretBusinessServicesExceptionForChange(Exception e) {
        String message = "";
        BusinessException x = businessServiceExceptionInterpreter.interpret(e);

        if (x instanceof OptimisticLockException) {
            message = getMessages().get("change_failed_optimistic_lock");
        }
        else if (x instanceof DuplicateAlternateKeyException) {
            DuplicateAlternateKeyException d = (DuplicateAlternateKeyException) x;
            message = getMessages().format("change_failed_duplicate_alternate_key", d.getTechnicalMessageText());
        }
        else {
            message = x.getMessage();
        }
        return message;
    }

    protected String interpretBusinessServicesExceptionForRemove(Exception e) {
        String message = "";
        BusinessException x = businessServiceExceptionInterpreter.interpret(e);

        if (x instanceof OptimisticLockException) {
            message = getMessages().get("remove_failed_optimistic_lock");
        }
        else if (x instanceof CannotDeleteIsReferencedException) {
            CannotDeleteIsReferencedException c = (CannotDeleteIsReferencedException) x;
            message = getMessages().format("remove_failed_is_referenced",
                    new Object[] { c.getReferencedByEntityName() });
        }
        else {
            message = x.getMessage();
        }
        return message;
    }

    protected String interpretBusinessServicesExceptionForDelete(Exception e) {
        String message = "";
        BusinessException x = businessServiceExceptionInterpreter.interpret(e);

        if (x instanceof OptimisticLockException) {
            message = getMessages().get("delete_failed_optimistic_lock");
        }
        else if (x instanceof CannotDeleteIsReferencedException) {
            CannotDeleteIsReferencedException c = (CannotDeleteIsReferencedException) x;
            message = getMessages().format("delete_failed_is_referenced",
                    new Object[] { c.getReferencedByEntityName() });
        }
        else {
            message = x.getMessage();
        }
        return message;
    }

}