Autenticação e Autorização
Em 90% das aplicações, é utilizado algum tipo de autenticação e autorização. O NEO disponibiliza um filtro que é responsável por validar o usuário logado, checar se aquele usuário tem permissão a um determinado recurso no sistema, e também autenticá-lo.
Para que a autenticação funcione são necessários os seguintes componentes:
Configuração do web.xml
Primeiramente é necessário configurar o web.xml, e dizer a ele para interceptar as requisições, e a partir dela validar a permissão do usuário.
Conforme explicado no capítulo 2, Primeira aplicão, é necessário ter ao menos um módulo configurado.

Adicione o seguinte código ao seu web.xml:
[JSP]
	<!-- Autenticação / Autorização -->
    <filter>
		<filter-name>authenticationControlFilter</filter-name>
		<filter-class>br.com.linkcom.neo.authorization.AuthenticationControlFilter</filter-class>
	</filter>
	
	<filter-mapping>
		<filter-name>authenticationControlFilter</filter-name>
		<url-pattern>/modulo/*</url-pattern>
	</filter-mapping>
Caso você ainda não tenha definido o filtro do Neo, adicione-o antes do filtro de autorização descrito acima, caso contrário você receberá um erro de que a requisição não está em um contexto do Neo. Veja abaixo um exemplo de definição do filtro do Neo:
[JSP]
	<filter>
        <filter-name>neoFilter</filter-name>
        <filter-class>br.com.linkcom.neo.core.web.NeoFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>neoFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    

Suponhamos que em sua aplicação estivesse configurado mais de um módulo, portanto ficaria assim:
[JSP]
	<!-- Autenticação / Autorização -->
    <filter>
		<filter-name>authenticationControlFilter</filter-name>
		<filter-class>br.com.linkcom.neo.authorization.AuthenticationControlFilter</filter-class>
	</filter>
	
	<filter-mapping>
		<filter-name>authenticationControlFilter</filter-name>
		<url-pattern>/modulo/*</url-pattern>
	</filter-mapping>
	
	<filter-mapping>
		<filter-name>authenticationControlFilter</filter-name>
		<url-pattern>/modulo2/*</url-pattern>
	</filter-mapping>
O filtro deve estar declarado no web.xml antes dos servlets que mapeiam os módulos.
Configuração do applicationConfig.xml
Também é necessário configurar a maneira que o NEO se comporta na autenticação/autorização. Para isso será utilizado o Spring, para injetar valores na classe DefaultConfig.

No seu arquivo applicationConfig.xml, adicione o seguinte trecho de código:
[JSP]
	<bean name="config"	class="br.com.linkcom.neo.core.config.DefaultConfig" autowire="autodetect">
		<property name="authenticationConfig">
            <ref bean="authenticationConfig" />
        </property>
	</bean>
	
	<bean id="authenticationConfig" class="br.com.linkcom.neo.core.config.AuthenticationConfig">
        <property name="loginPage" value="/jsp/login.jsp"/>
        <property name="indexPage" value="/modulo/index"/>
        <property name="useStaticModuleAccess" value="false"/>
    </bean>
Desenvolvimento da tela de login
Em seguida é necessário termos uma tela de login, que possui a função básica de submeter os dados para que o filtro possa autenticar o usuário, e registrá-lo na aplicação. A url que receberá os dados é /contexto/seumodulo/neo_security_manager.

No diretório Web-Root/jsp coloque o arquivo descrito abaixo com o nome login.jsp:
[JSP]
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<HTML>
  <HEAD>
    <TITLE>NEO FRAMEWORK</TITLE>
  </HEAD>
  <BODY leftmargin="0" topmargin="0" rightmargin="0"
    style="padding: 0px; margin: 0px;">
    <form name="loginForm" action="${ctx}/modulo/neo_security_manager"
      method="post">
      <table width="100%" border="0" cellspacing="0" cellpadding="0">
        <tr>
          <td width="47%" height="80">

          </td>
          <td width="51%">
            <table width="100%" border="0" cellspacing="0" cellpadding="0">
              <tr>
                <td colspan="2">
                  <c:if test="${!empty login_error}">
                    <div id="error">
                      Login / senha inválidos.
                    </div>
                  </c:if>
                </td>
              </tr>
              <tr>
                <td>
                  <span class="style8"> Login</span>
                </td>
                <td>
                  <input type="text" name="username" id="username" />
                </td>
              </tr>
              <tr>
                <td>
                  Senha
                </td>
                <td>
                  <input type="password" name="password" size="14" />
                </td>
              </tr>
              <tr>
                <td align="right" colspan="2">
                  <input type="submit" value="Entrar" />
                </td>
              </tr>
            </table>
          </td>
        </tr>
      </table>
    </form>
  </BODY>
</HTML>
Estrutura do banco de dados.
Crie no seu banco de dados a seguinte estrutura:
CREATE TABLE "usuario" (
  "id" INTEGER NOT NULL, 
  "nome" VARCHAR(80) NOT NULL, 
  "login" VARCHAR(50) NOT NULL, 
  "password" VARCHAR(50) NOT NULL,  
  CONSTRAINT "usuario_pkey" PRIMARY KEY("id")
) ;
CREATE TABLE "papel" (
  "id" INTEGER NOT NULL, 
  "description" VARCHAR(80) NOT NULL, 
  "name" VARCHAR(50), 
  "admin" BOOLEAN,
  CONSTRAINT "papel_pkey" PRIMARY KEY("id")
) ;
CREATE TABLE "permissao" (
  "id" INTEGER NOT NULL, 
  "permissionString" VARCHAR(80) NOT NULL, 
  "path" VARCHAR(100) NOT NULL, 
  "role_id" INTEGER NOT NULL, 
  CONSTRAINT "permissao_pkey" PRIMARY KEY("id"), 
  CONSTRAINT "fk_permissao_papel" FOREIGN KEY ("id")
    REFERENCES "papel"("id")
    ON DELETE NO ACTION
    ON UPDATE NO ACTION
    NOT DEFERRABLE
);
CREATE TABLE "usuariopapel" (
  "id" INTEGER NOT NULL, 
  "usuario_id" INTEGER NOT NULL, 
  "papel_id" INTEGER NOT NULL, 
  CONSTRAINT "usuariopapel_pkey" PRIMARY KEY("id"), 
  CONSTRAINT "usuariopapel_fk" FOREIGN KEY ("usuario_id")
    REFERENCES "public"."usuario"("id")
    ON DELETE CASCADE
    ON UPDATE NO ACTION
    NOT DEFERRABLE, 
  CONSTRAINT "usuariopapel_fk1" FOREIGN KEY ("papel_id")
    REFERENCES "public"."papel"("id")
    ON DELETE NO ACTION
    ON UPDATE NO ACTION
    NOT DEFERRABLE
) ;
Esta ddl foi gerada no PostGreSQL. Caso utilize outro SGBD serão necessárias adaptações.
Estrutura dos beans.
No pacote que é localizado as suas entidades do hibernate, adicione as seguintes classes:
Usuario.java
package entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

import br.com.linkcom.neo.authorization.User;
import br.com.linkcom.neo.bean.annotation.DescriptionProperty;
import br.com.linkcom.neo.types.Password;

/**
 * Representa um usuário no sistema
 */
@Entity
public class Usuario implements User {
	
	Integer id;
	String nome;
	String login;
	String password;
	
	@Id
	@GeneratedValue
	public Integer getId() {
		return id;
	}
	//API
	public String getLogin() {
		return login;
	}
	
	@DescriptionProperty
	public String getNome() {
		return nome;
	}
	
	//API
	@Password
	public String getPassword() {
		return password;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public void setLogin(String login) {
		this.login = login;
	}
	public void setNome(String nome) {
		this.nome = nome;
	}
	public void setPassword(String password) {
		this.password = password;
	}

}
Papel.java
package entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

import br.com.linkcom.neo.authorization.Role;
import br.com.linkcom.neo.bean.annotation.DescriptionProperty;

/**
 * Representa um papel no sistema, um nível de permissão. Ex.: Administrador,
 * Usuário, Financeiro
 */
@Entity
public class Papel implements Role {

	Integer id;
	String description;
	String name;
	Boolean admin;

	@Id
	@GeneratedValue
	public Integer getId() {
		return id;
	}

	// API
	@Override
	@DescriptionProperty
	public String getDescription() {
		return description;
	}

	// API
	@Override
	public String getName() {
		return name;
	}

	// API
	@Override
	public Boolean isAdmin() {
		return admin;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public void setAdmin(Boolean admin) {
		this.admin = admin;
	}

}
UsuarioPapel.java
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;

/**
 * Faz o relacionamento entre Usuário e Papel
 * Relacionamento muitos para muitos entre usuario e papel
 */
@Entity
public class UsuarioPapel {

	Integer id;
	Usuario usuario;
	Papel papel;
	
	@Id
	@GeneratedValue
	public Integer getId() {
		return id;
	}
	
	@ManyToOne(fetch=FetchType.LAZY)
	public Papel getPapel() {
		return papel;
	}
	
	@ManyToOne(fetch=FetchType.LAZY)
	public Usuario getUsuario() {
		return usuario;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public void setPapel(Papel papel) {
		this.papel = papel;
	}
	public void setUsuario(Usuario usuario) {
		this.usuario = usuario;
	}
}
Permissao.java
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

import br.com.linkcom.neo.authorization.impl.AbstractPermission;

/**
 * Representa a permissão para determinado papel em determinada tela
 */
@Entity
public class Permissao extends AbstractPermission {
	
	Integer id;
	Papel role;
	String permissionString;
	String path;
	
	@Id
	@GeneratedValue
	public Integer getId() {
		return id;
	}
	public String getPath() {
		return path;
	}
	
	//API
	public String getPermissionString() {
		return permissionString;
	}
	
	//API
	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name="role_id")
	public Papel getRole() {
		return role;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public void setPath(String path) {
		this.path = path;
	}
	public void setPermissionString(String permissionString) {
		this.permissionString = permissionString;
	}
	public void setRole(Papel role) {
		this.role = role;
	}
}
Configuração do AuthorizationDAO.
O NEO dispõe de uma interface, a AuthorizationDAO, que possui os métodos que serão usados tanto para a autorização quanto autenticação do usuário.
No pacote dos DAO's adicione a seguinte classe:
NeoAuthorizationDAO.java
package dao;
import java.util.List;
import java.util.Map;

import org.springframework.orm.hibernate3.HibernateTemplate;

import entity.Papel;
import entity.Permissao;
import entity.Usuario;
import entity.UsuarioPapel;

import br.com.linkcom.neo.authorization.AuthorizationDAO;
import br.com.linkcom.neo.authorization.Permission;
import br.com.linkcom.neo.authorization.Role;
import br.com.linkcom.neo.authorization.User;
import br.com.linkcom.neo.persistence.QueryBuilder;

/**
 * DAO de autorização, detectado automaticamente pelo NEO.
 * Fornece informações sobre autorização para o framework 
 */
public class NeoAuthorizationDAO implements AuthorizationDAO {
    
    private HibernateTemplate hibernateTemplate;
    
    public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
        this.hibernateTemplate = hibernateTemplate;
    }
    
    //API
    /**
     * Retorna a lista de todos os papeis do sistema
     */
    public Role[] findAllRoles() {
        List<Papel> roles = new QueryBuilder<Papel>(hibernateTemplate)
                            .from(Papel.class)
                            .list();
        return roles.toArray(new Role[roles.size()]);
    }

    //API
    /**
     * Acha a permissão para determinado nível em determinada tela
     * @param role papel que desejamos a permissão
     * @param controlName path que representa a tela desejada
     */
    public Permission findPermission(Role role, String controlName) {
        return new QueryBuilder<Permissao>(hibernateTemplate)
                    .from(Permissao.class)
                    .where("permissao.role = ?", role)
                    .where("permissao.path = ?", controlName)
                    .unique();
    }

    //API
    /**
     * Acha o usuário pelo login
     */
    public User findUserByLogin(String login) {
        return new QueryBuilder<Usuario>(hibernateTemplate)
                    .from(Usuario.class)
                    .where("usuario.login = ?", login)
                    .unique();
    }

    //API
    /**
     * Acha os papeis (níveis) de determinado usuário
     */
    public Role[] findUserRoles(User user) {
        List<UsuarioPapel> list = new QueryBuilder<UsuarioPapel>(hibernateTemplate)
                            .select("papel")
                            .from(UsuarioPapel.class)
                            .leftOuterJoin("usuarioPapel.papel papel")
                            .leftOuterJoin("usuarioPapel.usuario usuario")
                            .where("usuario = ?", user)
                            .list();
        return list.toArray(new Role[list.size()]);
    }
    
    //API
    /**
     * Salva ou atualiza uma permissão no banco de dados.
     */
    public Permission savePermission(String controlName, Role role, Map<String, String> permissionMap) {
        Permissao permissao = (Permissao)findPermission(role, controlName);
        if(permissao == null){
            permissao = new Permissao();
            permissao.setPath(controlName);
            permissao.setRole((Papel) role);
        }
        permissao.setPermissionMap(permissionMap);
        hibernateTemplate.saveOrUpdate(permissao);
        return permissao;
    }

}
Configuração do controller da página principal.
Também é necessário configurar a página principal da nossa aplicação. Para isso crie o seguinte controller:
import org.springframework.web.servlet.ModelAndView;

import br.com.linkcom.neo.controller.Controller;
import br.com.linkcom.neo.controller.DefaultAction;
import br.com.linkcom.neo.controller.MultiActionController;
import br.com.linkcom.neo.core.web.WebRequestContext;


@Controller(path="/modulo/index")
public class IndexController extends MultiActionController {

	@DefaultAction
	public ModelAndView doPage(WebRequestContext request){
		return new ModelAndView("index");
	}
}
Em seguinda um arquivo chamado index.jsp na pasta /WEB-ROOT/WEB-INF/jsp/modulo/
<b>Página principal da minha aplicação.</b>
Documentação extra.
Caso precise de recursos extras para autenticação, abra as seguintes classes: