Esse post demonstra a integração do Spring 3, Spring Security 3 e Hibernate 3 numa aplicação web.
O exemplo utiliza JSF 2.0 e Primefaces.
A estrutura de pacotes é a seguinte:
* config -> a classe de conexão (datasource)
* model -> as entidades Usuario e Perfil
* services -> a classe service customizada para autenticar o usuário usando o hibernate
* web -> o managed bean acessado pela tela de login (LoginMB), um PhaseListener utilizado para capturar exceções de autenticação e uma classe utilitária para JSF.
web.xml
Aqui configuramos o filtro “org.springframework.web.filter.DelegatingFilterProxy” e definimos os arquivos lidos na inicialização (“spring-config.xml” e “spring-security.xml”).
As demais configurações são relativas ao JSF e Primefaces.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>spring + security + hibernate</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-config.xml
/WEB-INF/spring-security.xml
</param-value>
</context-param>
<context-param>
<param-name>primefaces.SKIN</param-name>
<param-value>none</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Resource Servlet</servlet-name>
<servlet-class>org.primefaces.resource.ResourceServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Resource Servlet</servlet-name>
<url-pattern>/primefaces_resource/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
faces-config.xml
Aqui configuramos o “EL Resolver” e registramos um PhaseListener responsável pelos erros de autenticação do usuário.
<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="2.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
<lifecycle>
<phase-listener>br.com.exemploseguranca.web.seguranca.LoginErrorPhaseListener</phase-listener>
</lifecycle>
</faces-config>
spring-config.xml
Aqui configuramos o suporte à anotações e as propriedades da sessionFactory do Hibernate.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:sec="http://www.springframework.org/schema/security" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <!-- habilita a configuração por annotations --> <context:annotation-config /> <!-- define os pacotes/subpacotes onde serão procurados beans do spring --> <context:component-scan base-package="br.com.exemploseguranca" /> <!-- Propriedades do hibernate --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="annotatedClasses"> <list> <value>br.com.exemploseguranca.model.Usuario</value> <value>br.com.exemploseguranca.model.Perfil</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> </props> </property> </bean> </beans>
spring-security.xml
Nesse arquivo definimos as regras de segurança da aplicação.
O diretório “/paginas/” é protegido e somente usuários autenticados conseguem acessá-lo.
Depois de autenticado, temos acesso às informações de autorização do usuário.
Nesse exemplo temos 2 perfis(roles) de usuário:
* Administrador (ROLE_ADM) -> possui acesso à todos os diretórios da aplicação.
* Usuário (ROLE_USER) -> possui acesso limitado ao diretório “/paginas/usuario/**”.
O acesso ao diretório “/paginas/usuario/**” é permitido aos usuários dos 2 perfis.
O fluxo é o seguinte:
O usuário acessa a aplicação e é direcionado para a página “/login.jsf”.
Após realizar o login ele é direcionado para “/paginas/inicio.jsf”, onde encontra links para as páginas internas (“/paginas/admin/admin.jsf” e “/paginas/usuario/usuario.jsf”).
A página “inicio.jsf” é liberada para qualquer usuário autenticado.
Caso ocorra algum erro na autenticação(dados incorretos), é apresentada uma mensagem de erro na própria página “/login.jsf”.
Caso um usuário não autorizado(ROLE_USER) tente acessar o diretório “/paginas/admin/**”, será direcionado para a página “/acessonegado.jsf”
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:sec="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.3.xsd"> <sec:http auto-config="true" access-denied-page="/acessonegado.jsf"> <sec:intercept-url pattern="/login*" access="IS_AUTHENTICATED_ANONYMOUSLY" /> <sec:intercept-url pattern="/paginas/inicio*" access="ROLE_USER, ROLE_ADM" /> <sec:intercept-url pattern="/paginas/usuario/**" access="ROLE_USER, ROLE_ADM" /> <sec:intercept-url pattern="/paginas/admin/**" access="ROLE_ADM" /> <sec:form-login login-page="/login.jsf" login-processing-url="/j_spring_security_check" default-target-url="/paginas/inicio.jsf" authentication-failure-url="/login.jsf" /> <sec:logout logout-success-url="/login.jsf" /> </sec:http> <sec:authentication-manager> <sec:authentication-provider user-service-ref="hibernateUserDetailsService" ref="daoAuthenticationProvider" /> </sec:authentication-manager> <bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider"> <property name="userDetailsService" ref="hibernateUserDetailsService" /> </bean> <bean id="loggerListener" class="org.springframework.security.access.event.LoggerListener" /> </beans>
HibernateUserDetailsService.java
A autenticação é feita pela interface UserDetailsService.
Para utilizar o hibernate, criamos uma implementação de UserDetailsService e sobrescrevemos o método loadUserByUsername();
package br.com.exemploseguranca.services;
import java.util.List;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import br.com.exemploseguranca.model.Usuario;
@Service("hibernateUserDetailsService")
public class HibernateUserDetailsService extends HibernateDaoSupport implements UserDetailsService {
@Autowired
public HibernateUserDetailsService(SessionFactory sessionFactory) {
setSessionFactory(sessionFactory);
}
@SuppressWarnings("unchecked")
@Override
public UserDetails loadUserByUsername(String login) {
DetachedCriteria criteria = DetachedCriteria.forClass(Usuario.class, "usuario");
criteria.add(Restrictions.eq("usuario.login", login));
List resultado = getHibernateTemplate().findByCriteria(criteria);
if(resultado != null && resultado.size() == 0) {
throw new UsernameNotFoundException("Usuário não encontrado!");
}
return (Usuario)resultado.get(0);
}
}
LoginMB.java
Managed Bean que recebe a requisição da página “login.jsf”
package br.com.exemploseguranca.web.controle;
import javax.faces.context.FacesContext;
import javax.servlet.RequestDispatcher;
import org.springframework.stereotype.Controller;
import br.com.exemploseguranca.web.util.FacesUtil;
@Controller("loginMB")
public class LoginMB {
public LoginMB() {
}
public String logar() {
try {
RequestDispatcher dispatcher = FacesUtil.getServletRequest().getRequestDispatcher("/j_spring_security_check");
dispatcher.forward(FacesUtil.getServletRequest(), FacesUtil.getServletResponse());
FacesContext.getCurrentInstance().responseComplete();
} catch (Exception ex) {
FacesUtil.exibirMensagemErro(ex.getMessage());
return null;
}
return null;
}
}
LoginErrorPhaseListener.java
PhaseListener utilizado para capturar exceções de autenticação. Utiliza a classe utilitária FacesUtil para enviar mensagens de erro.
package br.com.exemploseguranca.web.seguranca;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.web.WebAttributes;
import br.com.exemploseguranca.web.util.FacesUtil;
@SuppressWarnings({"serial"})
public class LoginErrorPhaseListener implements PhaseListener {
@Override
public void afterPhase(PhaseEvent arg0) {
}
@SuppressWarnings({ "unchecked" })
@Override
public void beforePhase(PhaseEvent arg0) {
Exception dadosIncorretosException = (Exception) FacesUtil.getSessionMap().get(WebAttributes.AUTHENTICATION_EXCEPTION);
if(dadosIncorretosException instanceof BadCredentialsException) {
FacesUtil.getSessionMap().put(WebAttributes.AUTHENTICATION_EXCEPTION, null);
FacesUtil.exibirMensagemErro("Dados incorretos!");
}
}
@Override
public PhaseId getPhaseId() {
return PhaseId.RENDER_RESPONSE;
}
}
FacesUtil.java
Classe utilitária para desenvolvimento JSF.
package br.com.exemploseguranca.web.util;
import java.util.Map;
import javax.faces.application.FacesMessage;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Classe utilitária para desenvolvimento JSF
*/
public class FacesUtil {
public static String getRequestParameter(String name) {
return (String)FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get(name);
}
public static void exibirMensagemSucesso(String mensagem) {
exibirMensagem(FacesMessage.SEVERITY_INFO, mensagem);
}
public static void exibirMensagemAlerta(String mensagem) {
exibirMensagem(FacesMessage.SEVERITY_WARN, mensagem);
}
public static void exibirMensagemErro(String mensagem) {
exibirMensagem(FacesMessage.SEVERITY_ERROR, mensagem);
}
private static void exibirMensagem(FacesMessage.Severity severity, String mensagem) {
FacesMessage facesMessage = new FacesMessage(severity, "", mensagem);
FacesContext.getCurrentInstance().addMessage(null, facesMessage);
}
public static ExternalContext getExternalContext() {
return FacesContext.getCurrentInstance().getExternalContext();
}
public static Map getSessionMap() {
return FacesContext.getCurrentInstance().getExternalContext().getSessionMap();
}
public static ServletContext getServletContext() {
return (ServletContext)FacesContext.getCurrentInstance().getExternalContext().getContext();
}
public static HttpServletRequest getServletRequest() {
return (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
}
public static HttpServletResponse getServletResponse() {
return (HttpServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
}
}
Usuario.java
A entidade Usuario implementa a interface UserDetails e deve ter o método getAuthorities().
Foi criada uma tabela de associação (usuario_perfil) para armazenar o perfil de acesso(autorização) dos usuários.
package net.finottisistemas.modelo;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;
@Entity
@Table(name = "usuario")
public class Usuario implements java.io.Serializable, UserDetails {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id_usuario")
private Long id;
@Column(name = "login")
private String login;
@Column(name = "senha")
private String senha;
private boolean ativo = true;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "usuario_perfil", joinColumns = @JoinColumn(name = "id_usuario"), inverseJoinColumns = @JoinColumn(name = "id_perfil"))
private List<Perfil> perfis = new ArrayList<Perfil>();
@Transient
public Collection<GrantedAuthority> getAuthorities() {
List<GrantedAuthority> lista = new ArrayList<GrantedAuthority>();
for(Perfil perfil : getPerfis()) {
lista.add(new GrantedAuthorityImpl(perfil.getAuthority()));
}
return lista;
}
@Transient
public String getPassword() {
return this.senha;
}
@Transient
public String getUsername() {
return this.login;
}
@Transient
public boolean isAccountNonExpired() {
return true;
}
@Transient
public boolean isAccountNonLocked() {
return true;
}
@Transient
public boolean isCredentialsNonExpired() {
return true;
}
@Transient
public boolean isEnabled() {
return this.ativo;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public boolean isAtivo() {
return ativo;
}
public void setAtivo(boolean ativo) {
this.ativo = ativo;
}
public List<Perfil> getPerfis() {
return perfis;
}
public void setPerfis(List<Perfil> perfis) {
this.perfis = perfis;
}
}
Perfil.java
A entidade Perfil implementa a interface GrantedAuthority.
package net.finottisistemas.modelo;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
import org.springframework.security.core.GrantedAuthority;
@Entity
@Table(name = "perfil")
public class Perfil implements java.io.Serializable, GrantedAuthority {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id_perfil")
private Long id;
@Column(name = "descricao")
private String descricao;
@ManyToMany(fetch=FetchType.EAGER)
@JoinTable(name = "usuario_perfil", joinColumns = @JoinColumn(name = "id_perfil"), inverseJoinColumns = @JoinColumn(name = "id_usuario"))
private List<Usuario> usuarios = new ArrayList<Usuario>();
@Transient
public String getAuthority() {
return this.descricao;
}
@Transient
public int compareTo(Object o) {
return this.compareTo(o);
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getDescricao() {
return descricao;
}
public void setDescricao(String descricao) {
this.descricao = descricao;
}
public List<Usuario> getUsuarios() {
return usuarios;
}
public void setUsuarios(List<Usuario> usuarios) {
this.usuarios = usuarios;
}
}
Conexao.java
Propriedades da conexão com o banco de dados (datasource)
package br.com.exemploseguranca.config;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.stereotype.Component;
@Component("dataSource")
public class Conexao extends DriverManagerDataSource {
public Conexao(){
this.setDriverClassName("com.mysql.jdbc.Driver");
this.setUrl("jdbc:mysql://localhost/seguranca");
this.setUsername("root");
this.setPassword("root");
}
}
login.xhtml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:p="http://primefaces.prime.com.tr/ui"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>
Spring + Security + Hibernate
</title>
<link type="text/css" rel="stylesheet" href="#{facesContext.externalContext.requestContextPath}/css/redmond/skin.css" />
</h:head>
<h:body>
<h:form prependId="false">
<p:dialog header="Área restrita"
modal="true"
closable="false"
position="center"
widgetVar="modalLogin"
minWidth="300"
width="300"
showEffect="slide"
draggable="false"
resizable="false"
visible="true">
<center>
<p:messages id="mensagens" showDetail="true" showSummary="false" />
<h:panelGrid columns="2">
<h:outputLabel value="Login" />
<h:inputText id="j_username" size="15" />
<h:outputLabel value="Senha" />
<h:inputSecret id="j_password" size="15" />
</h:panelGrid>
<br />
<h:commandButton value="Entrar" action="#{loginMB.logar}" />
</center>
</p:dialog>
</h:form>
</h:body>
</html>
/paginas/inicio.xhtml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.prime.com.tr/ui">
<h:head>
<title>
Spring + Security + Hibernate
</title>
<link href="#{facesContext.externalContext.requestContextPath}/css/redmond/skin.css" rel="stylesheet" type="text/css" />
</h:head>
<h:body>
<h:form prependId="false">
<p:dialog header="Spring + Security + Hibernate"
modal="true"
closable="false"
position="center"
widgetVar="modalInicio"
width="500"
height="400"
draggable="false"
resizable="false"
visible="true">
<center>
<img src="#{facesContext.externalContext.requestContextPath}/img/spring_security.jpg" />
</center>
<br />
<br />
<br />
<a href="#{facesContext.externalContext.requestContextPath}/paginas/admin/admin.jsf">
Página do administrador
</a>
<br />
<a href="#{facesContext.externalContext.requestContextPath}/paginas/usuario/usuario.jsf">
Página do usuário
</a>
<br />
<br />
<a href="#{facesContext.externalContext.requestContextPath}/j_spring_security_logout">
Sair
</a>
</p:dialog>
</h:form>
</h:body>
</html>
/paginas/admin/admin.xhtml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.prime.com.tr/ui">
<h:head>
<title>
Spring + Security + Hibernate
</title>
<link href="#{facesContext.externalContext.requestContextPath}/css/redmond/skin.css" rel="stylesheet" type="text/css" />
</h:head>
<h:body>
<p:dialog header="Página do administrador"
modal="true"
closable="true"
position="center"
widgetVar="modalAdmin"
minWidth="400"
width="400"
draggable="true"
resizable="true"
visible="true">
<center>
<img src="#{facesContext.externalContext.requestContextPath}/img/spring_security.jpg" />
<br />
<br />
<br />
# Página do Administrador #
<br />
<br />
<br />
<a href="#{facesContext.externalContext.requestContextPath}/paginas/inicio.jsf">
Voltar
</a>
<br />
<br />
<a href="#{facesContext.externalContext.requestContextPath}/j_spring_security_logout">
Sair
</a>
</center>
</p:dialog>
</h:body>
</html>
/paginas/usuario/usuario.xhtml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.prime.com.tr/ui">
<h:head>
<title>
Spring + Security + Hibernate
</title>
<link href="#{facesContext.externalContext.requestContextPath}/css/redmond/skin.css" rel="stylesheet" type="text/css" />
</h:head>
<h:body>
<p:dialog header="Página do Usuário"
modal="true"
closable="false"
position="center"
widgetVar="modalUsuario"
minWidth="400"
width="400"
draggable="false"
resizable="false"
visible="true">
<center>
<img src="#{facesContext.externalContext.requestContextPath}/img/spring_security.jpg" />
<br />
<br />
<br />
# Página do usuário #
<br />
<br />
<br />
<a href="#{facesContext.externalContext.requestContextPath}/paginas/inicio.jsf">
Voltar
</a>
<br />
<br />
<a href="#{facesContext.externalContext.requestContextPath}/j_spring_security_logout">
Sair
</a>
</center>
</p:dialog>
</h:body>
</html>
/acessonegado.xhtml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.prime.com.tr/ui">
<h:head>
<title>
<h:outputText value="Spring + Security + Hibernate" />
</title>
<link href="#{facesContext.externalContext.requestContextPath}/css/redmond/skin.css" rel="stylesheet" type="text/css" />
</h:head>
<h:body style="font-size: 10pt">
<p:dialog header="Ops! Acesso Negado!"
modal="true"
closable="true"
position="center"
widgetVar="modalNegado"
minWidth="500"
width="400"
showEffect="shake"
draggable="true"
resizable="true"
visible="true">
<center>
<img src="#{facesContext.externalContext.requestContextPath}/img/acesso_negado.gif" />
<br />
<br />
<br />
# Acesso Negado #
<br />
<br />
<br />
<a href="#{facesContext.externalContext.requestContextPath}/paginas/inicio.jsf">
Voltar
</a>
</center>
</p:dialog>
</h:body>
</html>
seguranca.sql
Script utilizado para o banco de dados (Mysql)
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for perfil
-- ----------------------------
DROP TABLE IF EXISTS `perfil`;
CREATE TABLE `perfil` (
`id_perfil` bigint(20) NOT NULL AUTO_INCREMENT,
`descricao` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id_perfil`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Table structure for usuario
-- ----------------------------
DROP TABLE IF EXISTS `usuario`;
CREATE TABLE `usuario` (
`id_usuario` bigint(20) NOT NULL AUTO_INCREMENT,
`ativo` bit(1) NOT NULL,
`login` varchar(255) DEFAULT NULL,
`senha` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id_usuario`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Table structure for usuario_perfil
-- ----------------------------
DROP TABLE IF EXISTS `usuario_perfil`;
CREATE TABLE `usuario_perfil` (
`id_perfil` bigint(20) NOT NULL,
`id_usuario` bigint(20) NOT NULL,
KEY `FK57CD23FD9DB9E69B` (`id_perfil`),
KEY `FK57CD23FD5A9933B9` (`id_usuario`),
KEY `FK57CD23FD67F47FA6` (`id_perfil`),
KEY `FK57CD23FDD7B1BC0E` (`id_usuario`),
KEY `FK57CD23FD28906DBF` (`id_perfil`),
KEY `FK57CD23FD2A939115` (`id_usuario`),
CONSTRAINT `FK57CD23FD2A939115` FOREIGN KEY (`id_usuario`) REFERENCES `usuario` (`id_usuario`),
CONSTRAINT `FK57CD23FD28906DBF` FOREIGN KEY (`id_perfil`) REFERENCES `perfil` (`id_perfil`),
CONSTRAINT `FK57CD23FD5A9933B9` FOREIGN KEY (`id_usuario`) REFERENCES `usuario` (`id_usuario`),
CONSTRAINT `FK57CD23FD67F47FA6` FOREIGN KEY (`id_perfil`) REFERENCES `perfil` (`id_perfil`),
CONSTRAINT `FK57CD23FD9DB9E69B` FOREIGN KEY (`id_perfil`) REFERENCES `perfil` (`id_perfil`),
CONSTRAINT `FK57CD23FDD7B1BC0E` FOREIGN KEY (`id_usuario`) REFERENCES `usuario` (`id_usuario`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records
-- ----------------------------
INSERT INTO `perfil` VALUES ('1', 'ROLE_ADM');
INSERT INTO `perfil` VALUES ('2', 'ROLE_USER');
INSERT INTO `usuario` VALUES ('1', true, 'admin', '12345');
INSERT INTO `usuario` VALUES ('2', true, 'user', '12345');
INSERT INTO `usuario_perfil` VALUES ('1', '1');
INSERT INTO `usuario_perfil` VALUES ('2', '2');
O código fonte do projeto está disponível no github e no 4shared.