![]() |
![]() |
![]() |
|
![]() |
|
www.linkcom.com.br | ![]() |
|
Autenticação e Autorização
A segurança de uma aplicação pode ser dividida em duas partes: autenticação
e autorização.
A autenticação é o processo de identificação do usuário.
Geralmente, através de uma tela onde o usuário fornece seu login e senha.
Autorização é o processo onde o sistema verifica se determinado usuário possui
permissão para acessar alguma funcionalidade do sistema.
O NEO possui suporte apenas para a implementação do processo de autorização,
que é o processo mais complicado.
Uma das formas de se implementar a autorização é utilizando JAAS.
O NEO detecta se algum login foi feito utilizando JAAS, então
nenhum trabalho extra é necessário. Como a configuração via JAAS
muda de servidor para servidor, mostraremos um exemplo 'manual' de autenticação.
Como a autenticação e autorização andam juntas, vamos implementar
as duas ao mesmo tempo.
Para o processo de autorização o NEO necessita que algumas interfaces sejam implementadas,
são elas:
- User: POJO que representa um usuário no sistema
- Role: POJO que representa um papel (ou nível) no sistema
- Permission: POJO que representa a permissão de determinado papel para determinado controller do sistema
- AuthorizationDAO: DAO que fornece métodos para descobrir informações sobre a autorização
Essas interfaces não definem nenhum relacionamento entre User e Role. Esse relacionamento
é definido na aplicação, da forma que o desenvolvedor desejar.
Não é necessário que os POJOs sejam entidades do Hibernate. Mas como nossos dados
estão em um banco de dados, aproveitaremos o bean para fazer o mapeamento no banco de dados.
Um exemplo de implementação para essas interfaces seria o seguinte:
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;
}
}
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;
@Id
@GeneratedValue
public Integer getId() {
return id;
}
//API
@DescriptionProperty
public String getDescription() {
return description;
}
//API
public String getName() {
return name;
}
public void setDescription(String description) {
this.description = description;
}
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
}
package entity;
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;
}
}
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
Note que foi utilizado um bean extra, UsuarioPapel, para fazer o relacionamento
entre user e role.
Esse bean é apenas um bean de ligação, para fazer um relacionamento muitos para muitos.
package entity;
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;
}
}
Esses beans são entidades no banco de dados e também representam informações para
o processo de autorização.
O NEO irá detectar qualquer classe que implemente AuthorizationDAO
na aplicação, não coloque @Bean nessa classe. Essa classe pode ficar em qualquer pacote
e ter qualquer nome.
Essas classes ainda não tem efeito de autorização nenhum na aplicação,
uma vez que nenhum controller foi configurado com autorização.
Antes de prosseguirmos com a autorização vamos criar o processo de autenticação.
Crie na aplicação um novo módulo do NEO. Esse módulo, no exemplo desse tutorial
irá se chamar secured. Para criar um módulo do neo é necessário um DispatcherServlet,
no nosso caso para a URL /secured/* no web.xml. Criar o diretório /WEB-INF/jsp/secured.
E colocar um arquivo base.jsp em /WEB-INF/jsp/secured.
Vamos criar um filtro que apenas usuários logados no sistema possam acessar esse módulo.
Crie o filtro conforme o modelo:
package filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import br.com.linkcom.neo.core.standard.Neo;
public class AuthenticationFilter implements Filter {
String loginPage = "/modulo/login";
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if(Neo.getUser() == null){
request.getRequestDispatcher(loginPage)
.forward(request, response);
} else {
chain.doFilter(request, response);
}
}
public void destroy() {
}
public void init(FilterConfig config) throws ServletException {
}
}
O authenticationFilter irá redirecionar para um controller caso não exista usuário no sistema,
o código desse controller é o seguinte:
package controller;
import org.springframework.web.servlet.ModelAndView;
import dao.NeoAuthorizationDAO;
import entity.Usuario;
import br.com.linkcom.neo.authorization.User;
import br.com.linkcom.neo.controller.Controller;
import br.com.linkcom.neo.controller.DefaultAction;
import br.com.linkcom.neo.controller.MessageType;
import br.com.linkcom.neo.controller.MultiActionController;
import br.com.linkcom.neo.core.web.WebRequestContext;
import br.com.linkcom.neo.view.menu.MenuTag;
/**
* Controller que fará o login do usuário na aplicação.
* Se o login for efetuado com sucesso irá redirecionar para /secured/Index
*/
@Controller(path="/modulo/login")
public class LoginController extends MultiActionController {
private static final String AFTER_LOGIN_GO_TO = "/secured/Index";
NeoAuthorizationDAO authorizationDAO;
public void setAuthorizationDAO(NeoAuthorizationDAO authorizationDAO) {
this.authorizationDAO = authorizationDAO;
}
/**
* Action que envia para a página de login
*/
@DefaultAction
public ModelAndView doPage(WebRequestContext request, Usuario usuario){
return new ModelAndView("login", "usuario", usuario);
}
/**
* Efetua o login do usuário
*/
public ModelAndView doLogin(WebRequestContext request, Usuario usuario){
String login = usuario.getLogin();
//se foi passado o login na requisição, iremos verificar se o usuário existe e a senha está correta
if(login != null){
//buscamos o usuário do banco pelo login
User userByLogin = authorizationDAO.findUserByLogin(login);
// se o usuário existe e a senha está correta
if(userByLogin != null && userByLogin.getPassword().equals(usuario.getPassword())){
//Setando o atributo de seção USER fazemos o login do usuário no sistema.
request.setUserAttribute("USER", userByLogin);
//Limpamos o cache de permissões o menu.
//O menu será refeito levando em consideração as permissões do usuário
request.setUserAttribute(MenuTag.MENU_CACHE_MAP, null);
return new ModelAndView("redirect:"+AFTER_LOGIN_GO_TO);
}
//Se o login e/ou a senha não estiverem corretos, avisar o usuário
request.addMessage("Login e/ou senha inválidos", MessageType.ERROR);
}
//limpar o campo senha, e enviar para a tela de login já que o processo falhou
usuario.setPassword(null);
return doPage(request, usuario);
}
}
e o login.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="n" uri="neo"%> <%@ taglib prefix="t" uri="template"%> <n:form> <n:bean name="usuario"> <t:propertyConfig renderAs="double" mode="input"> <n:panelGrid columns="2" align="center" style="width: 180px; background-color: #F8F4EA; padding:2px; border: 1px solid #949087" columnStyles="font-size: 12px;"> <n:panel style="background-color:#6699CC; color:white; font-weight:bold" colspan="2"> Login </n:panel> <t:property name="login"/> <t:property name="password" label="Senha"/> <n:submit action="doLogin" panelColspan="2" panelAlign="right">Enviar</n:submit> </n:panelGrid> </t:propertyConfig> </n:bean> </n:form>Após criar as classes devemos registrar dois filtros no web.xml. O filtro de autenticação (o que criamos) e o filtro de autorização (fornecido pelo NEO).
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<!-- Listener que inicializa a aplicação -->
<listener>
<listener-class>br.com.linkcom.neo.core.web.init.ContextLoaderListener</listener-class>
</listener>
<!-- Filtro para criar o contexto do NEO -->
<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>
<!-- Filtro de autenticação. Verifica se o usuário está logado -->
<filter>
<filter-name>authenticationFilter</filter-name>
<filter-class>filter.AuthenticationFilter</filter-class>
</filter>
<!-- Esse filtro irá barrar todo acesso anonimo à /secured/* -->
<!-- Se desejar barrar acesso anonimo à outras URLs duplique o filter-mapping e altere a url-pattern -->
<filter-mapping>
<filter-name>authenticationFilter</filter-name>
<url-pattern>/secured/*</url-pattern>
</filter-mapping>
<!-- Filtro de autorização, verifica as permissões para determinado recurso -->
<filter>
<filter-name>authorizationFilter</filter-name>
<filter-class>br.com.linkcom.neo.authorization.AuthorizationFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>authorizationFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Servlet necessário para Ajax -->
<servlet>
<servlet-name>ajaxServlet</servlet-name>
<servlet-class>br.com.linkcom.neo.view.AjaxServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ajaxServlet</servlet-name>
<url-pattern>/ajax/*</url-pattern>
</servlet-mapping>
<!-- Servlet necessário do NEO, provê JS e CSS -->
<servlet>
<servlet-name>resourceServlet</servlet-name>
<servlet-class>br.com.linkcom.neo.view.ResourceServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>resourceServlet</servlet-name>
<url-pattern>/resource/*</url-pattern>
</servlet-mapping>
<!-- Servlet necessário para os inputs select-one-path e select-one-button -->
<servlet>
<servlet-name>selecionarCadastrarServlet</servlet-name>
<servlet-class>br.com.linkcom.neo.view.SelecionarCadastrarServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>selecionarCadastrarServlet</servlet-name>
<url-pattern>/SELECIONARCADASTRAR/*</url-pattern>
</servlet-mapping>
<!-- Módulo da aplicação -->
<servlet>
<servlet-name>modulo</servlet-name>
<servlet-class>br.com.linkcom.neo.controller.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>modulo</servlet-name>
<url-pattern>/modulo/*</url-pattern>
</servlet-mapping>
<!-- Módulo seguro da aplicação, só é possível acessar esse módulo se o usuário tiver logado no sistema -->
<servlet>
<servlet-name>secured</servlet-name>
<servlet-class>br.com.linkcom.neo.controller.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>secured</servlet-name>
<url-pattern>/secured/*</url-pattern>
</servlet-mapping>
</web-app>
A ordem dos filtros deve ser seguida. Primeiro vem o neoFilter, depois o authenticationFilter
e depois o authorizationFilter.
Nesse momento se quisermos acessar qualquer recurso dentro de /secured
o authenticationFilter irá interceptar a requisição e enviar o usuário para a tela de login
até que o usuário esteja logado no sistema.
O LoginController após logar o usuário no sistema faz o redirecionamento para
/secured/Index. Mas poderia ser para qualquer outro controller.
Lembre-se de implementar um controller para receber a requisição após o login no sistema.
|
Últimas postagens
Alguem ainda usa o NEO?
Autor: Nunes
sem hibernate
Autor: csilva2001
Erro ao fazer update [RESOLVIDO]
Autor: Tchaco
Erro CrudController
Autor: edu_fernandes
Artigos, Livros e documentação
Autor: Nunes
Crud Master Detail
Autor: carlos ribeiro
[RESOLVIDO] Problema ao iniciar aplicação com NEO
Autor: R.Albany
gerar relatórios
Autor: mouzer
[RESOLVIDO] Missing required Java project: 'Neo'
Autor: r3n4n
The method ognl(String) in the type NeoFunctions is not applicable for the arguments ()
Autor: r3n4n
Dúvida com videos em flash e jsp
Autor: thiago cassimiro
Criptografar senhas Postgresql
Autor: labavel
Fazer upload da imagem em disco e no banco
Autor: labavel
Estilo no detalhe
Autor: Tchaco
Acessar o equivalente ao Neo.getUser() dentro da JSP
Autor: konkix
Dúvida de iniciante
Autor: Eder
Acesso a banco de dados
Autor: Nunes
Gravar Imagem no Banco
Autor: Tchaco
Campos AUTOCOMPLETE
Autor: vanessa
Assinatura Digital
Autor: biharck
Projeto NEO pode ser utilizado em um grande cliente do grande ABC.
Autor: Nunes
Layout Mestre Detalhe
Autor: viniciusst
Problemas com o type CPFCNPJ
Autor: viniciusst
Combo de Estado
Autor: viniciusst
Suporte a dois SGBD's Simultâneos
Autor: biharck
Many-to-Many
Autor: Tux
Gerando relatórios
Autor: viniciusst
Problemas com filtro listagem
Autor: vberga
Projeto descontinuado
Autor: viniciusst
Crud com erro - MySQL
Autor: viniciusst
Erro de cast no DAO
Autor: biharck
@DescriptionProperty Multiplos
Autor: joaopedro
Geração de tabelas - CRUD
Autor: Nunes
iReport
Autor: jlevi
Impressão de PDF em Bamatech MP20-MI
Autor: Alisson
Retorno - Novidades
Autor: vinicius.janones
CRUD Avançado
Autor: cassioseffrin
CRUD
Autor: miltonmmjr
Upload Multiplo de Imagem
Autor: robmsjr
Problema com anotação
Autor: tulio
Integração com Hibernate
Autor: Nunes
Dúvida quanto à referência a imagens
Autor: mmfalcao
Problema com atributo do tipo byte[]
Autor: tulio
Relacionamento Many to Many
Autor: LeonardoBH
Problema ao subir aplicação de upload de arquivos
Autor: cassioseffrin
Neo versão 3.4.0
Autor: pedro.goncalves
Problemas neo 3.4 + jboss 5 e Cascade no Hibernate
Autor: vberga
Erro ao anotar @Bean
Autor: edson.goncalez
Suporte a paginação
Autor: int80h
Menu vertical
Autor: fabricio.costa
|
| Copyright © 2020 www.neoframework.com.br. Projeto sob a licença LGPL. |