GUJ Discussões   :   últimos tópicos   |   categorias   |   GUJ Respostas

[RESOLVIDO] Controle de acesso - Salvo no banco de dados [RESOLVIDO]


#1

Estou a utilizar o vrpator, hibernate.

Como eu faço para pegar as ações do usuário e salvar no banco?
Isso mesmo, um log de acesso.
Guardando o que ele acessou, o que ele fez e tal...

Grato,


#2

Pode fazer um interceptor que salva a URL que determinado usuário está acessando.


#3

Boa ideia!

Muito interessante.

Alguém teria alguma outra ideia?


#4

Você pode fazer um filter, e salvar onde ele está acessando ou se quiser algo mais refinado, você no próprio método manda salvar no db.


#5

Na minha opinião, um log de acesso, além de não ser muito útil, vai deixar as suas requisições mais lentas...

Eu verificaria a real necessidade.


#6

Filter é o interceptor no vraptor.

No caso de salvar no db, toda alteração e inclusão, seria uma boa.
Mas não vai de encontro com os principios de OO?

Obrigado!


#7

Já trabalhei com aplicações onde cada ação do usuário tinha que ser auditada. ^^

As vezes, é um mau necessário. Dependendo da aplicação tudo poderá ocorrer sem problemas, por exemplo, caso a aplicação utilize EJB basta chamar um MDB e passar as informações a serem persistidas; desse modo não haverá problemas quanto ao desempenho ou atraso da requisição do cliente.


#8

Preciso, porque a aplicação vai ter vários usuários.
Cada usuário representa uma empresa.
Nossa aplicação, vai disponibilizar os produtos e as empresas vão falar quais produtos elas querem, e quais sãos seus preços.
Posteriormente, ela pode reclamar, falando que não adicionou tal produto, e tal preço não foi ela que colocou.

Dessa forma, precisamos sim de um log de acesso.

Entende?

Valeus.


#9

101574,

O que você precisa auditar? Alterações e inclusões?

Pode criar uma anotação @Audit onde todo método que estiver anotado com ela, vai ser auditado. Pode fazer essa anotação para classe, assim todos os métodos serão auditatos.

Outra solução:
1. colocar duas colunas nas tabelas do sistema: UPD_USER e UPD_DATE
2. mandar o usuário que está alterando.
3. criar um trigger que vai colocar o horário do sistema no campo upd_date...

Hebert Coelho,
Concordo com você, mas em casos onde vão fazer relatórios. Se não, eu acho que um log de acesso fica muito inflado. É mta informação para pouca utilização.


#10

Eu vi caso onde ñ era utilizado para relatório, mas sim para caso o algum usuário faça alguma caca. Para dedo duro mesmo, o cara deu mole e fica registrado lá. [=

Eu só não sou fã de trigger. É uma ação executada que você não sabe de onde veio e para onde vai, caso você não conheça o sistema. [=


#11

Poww galera,

Vocês são muito bons.

Gostei da anotação @Audit.
Vou utilizar essa.

Minha anotação vai salvar o usuário e açao no banco.

Seria basicamente isso né?

-> Vou precisar gerar relatórios de 3 em 3 meses das ações das empresas e enviar por e-mail.
Por isso que precisamos salvar no banco.


#12

Voltei!rsrsrs

Seguinte.
Fiz o interceptor.
Agora minha dúvida e como eu vou fazer para pegar os dados do usuário, o nome do metodo e salvar isso no banco.

Meu interceptor.

package br.com.softsol.compresempre.infra.interceptor;
import br.com.caelum.vraptor.InterceptionException;
import br.com.caelum.vraptor.Intercepts;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.core.InterceptorStack;
import br.com.caelum.vraptor.interceptor.Interceptor;
import br.com.caelum.vraptor.resource.ResourceMethod;
import br.com.softsol.compresempre.interfaces.Auditoria;
@Intercepts
public class AuditoriaInterceptor implements Interceptor{
	private final Result result;
	/*
	 * Anotação - Interceptar
	 * Onde encontrar a anotação, vai ser interceptada
	 * Metodo intercept vai ser executado.
	 */
	//Construtor
	public AuditoriaInterceptor(Result result){
		this.result = result;
	}
	public boolean accepts(ResourceMethod method) {
		return method.containsAnnotation(Auditoria.class);		
	}
	//Metodo intercept - o que deve ser feito quando é encontrado a anotação
	public void intercept(InterceptorStack stack, ResourceMethod method,
			Object resourceInstance) throws InterceptionException {
			System.out.println("Encontrou Intercept");
			// segue o curso padrão
			stack.next(method, resourceInstance);
			}
}

Anotação Auditoria

package br.com.softsol.compresempre.interfaces;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//Disponivel em tempo de execução
@Retention(RetentionPolicy.RUNTIME)
//Anotação para métodos
@Target(ElementType.METHOD)
public @interface Auditoria {
}

To criando uma classe chamada auditoria que vai ser persitida no bd.
Vou criar o dao para incluir.
Agora, como eu vou preencher que eu não to conseguindo pensar.
Valeus...


#13

Cria um DAO com @Component que recebe uma session.

Dai você pega o construtor do interceptor e recebe o seu dao e a sessão do seu usuário.

E para pegar a URL você pode receber o HTTPServletRequest no construtor. Se eu não me engano, lá também tem o método HTTP da requisição (GET ou POST).

E acho que você consegue pegar os parâmetros da requisição também. Se for útil saber O QUE o seu usuário enviou.


#14

Vou tentar aqui.
Novamente obrigado!


#15

Mano o que eu fiz.

[code]
@Intercepts
public class AuditoriaInterceptor implements Interceptor{

private final Result result;
private final AuditoriaDAO dao;
private final EmpresaWeb empresa;

/*
* Anotação - Interceptar
* Onde encontrar a anotação, vai ser interceptada
* Metodo intercept vai ser executado.
*/
//Construtor

public AuditoriaInterceptor(Result result, AuditoriaDAO dao,
EmpresaWeb empresa){
this.result = result;
this.dao = dao;
this.empresa = empresa;

}
[/code]

[quote]E para pegar a URL você pode receber o HTTPServletRequest no construtor. Se eu não me engano, lá também tem o método HTTP da requisição (GET ou POST).
E acho que você consegue pegar os parâmetros da requisição também. Se for útil saber O QUE o seu usuário enviou.

Como eu passo o paramentro?

//Metodo intercept - o que deve ser feito quando é encontrado a anotação
	public void intercept(InterceptorStack stack, ResourceMethod method,
			Object resourceInstance) throws InterceptionException {
			System.out.println("Encontrou Intercept");
			//Salvar no banco as informações
			//Como passar os paramentros?
			dao.salva();
			// segue o curso padrão
			stack.next(method, resourceInstance);
			}
}

Grato.


#16

public AuditoriaInterceptor(Result result, AuditoriaDAO dao,  
            EmpresaWeb empresa, HTTPServletRequest req){  
        this.result = result;  
        this.dao = dao;  
        this.empresa = empresa;  
          this.req = req;
    }

Faz assim ué:

this.dao.save(new Auditoria(empresa.getNome(), req.getContextPath()));// Eu não sei como que é o construtor de uma auditoria, se for por setter, instancia e manda a instância.

#17

Não consegui.

Meu interceptor completo.

package br.com.softsol.compresempre.infra.interceptor;
import javax.servlet.http.HttpServletRequest;
import br.com.caelum.vraptor.InterceptionException;
import br.com.caelum.vraptor.Intercepts;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.core.InterceptorStack;
import br.com.caelum.vraptor.interceptor.Interceptor;
import br.com.caelum.vraptor.resource.ResourceMethod;
import br.com.softsol.compresempre.controller.EmpresaController;
import br.com.softsol.compresempre.dao.AuditoriaDAO;
import br.com.softsol.compresempre.modelo.Auditoria;
import br.com.softsol.compresempre.modelo.Bairro;
import br.com.softsol.compresempre.modelo.EmpresaWeb;
@Intercepts
public class AuditoriaInterceptor implements Interceptor{
	private final Result result;
	private final AuditoriaDAO dao;
	private final EmpresaWeb empresa;
	private final HttpServletRequest req;
	/*
	 * Anotação - Interceptar
	 * Onde encontrar a anotação, vai ser interceptada
	 * Metodo intercept vai ser executado.
	 */
	//Construtor
	public AuditoriaInterceptor(Result result, AuditoriaDAO dao,
			EmpresaWeb empresa,HttpServletRequest req){
		this.result = result;
		this.dao = dao;
		this.empresa = empresa;
		this.req = req;
	}
	public boolean accepts(ResourceMethod method) {
		return method.containsAnnotation(br.com.softsol.compresempre.interfaces.Auditoria.class);		
	}
	//Metodo intercept - o que deve ser feito quando é encontrado a anotação
	public void intercept(InterceptorStack stack, ResourceMethod method,
			Object resourceInstance) throws InterceptionException {
			System.out.println("Encontrou Intercept");
			//Salvar no banco as informações
			this.dao.salva(new Auditoria(empresa.getId(),req.getContextPath()));
			// segue o curso padrão
			stack.next(method, resourceInstance);
			}
}

Meu Auditoria Completo

package br.com.softsol.compresempre.modelo;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Auditoria {
	// Variáveis
	@Id
	@GeneratedValue
	private Long id;
	private Long usuario;
	private String metodo;
	// Método set e get
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public Long getUsuario() {
		return usuario;
	}
	public void setUsuario(Long usuario) {
		this.usuario = usuario;
	}
	public String getMetodo() {
		return metodo;
	}
	public void setMetodo(String metodo) {
		this.metodo = metodo;
	}
}

Meu AuditoriaDAO Completo.

package br.com.softsol.compresempre.dao;
import org.hibernate.Session;
import org.hibernate.Transaction;
import br.com.caelum.vraptor.ioc.Component;
import br.com.softsol.compresempre.modelo.Auditoria;
@Component
public class AuditoriaDAO {
	private final Session session;
	public AuditoriaDAO(Session session) {
		this.session = session;
	}
	public void salva(Auditoria auditoria) {
		Transaction tx = session.beginTransaction();
		session.save(auditoria);
		tx.commit();
	}
}

Não to conseguindo. Eu entendi a lógica, mas não to conseguindo fazer.


#18

Você pode fazer por setter...

Acho que você não entendeu o que está sendo feito.

Você vai instanciar um objeto da classe a ser persisitida (Auditoria) e depois você vai popular as informações que você quer que sejam persistidas.
Existem 2 formas de fazer:
1. Pelo construtor, da forma que eu te mostrei, mas ai você vai precisar criar um construtor compatível na classe Auditoria.
2. Pelos métodos setters, que pode ser feito da forma como está agora:

Auditoria audit = new Auditoria();
audit.setUsuario(empresa.getId());
audit.setMetodo(req.getContextPath());
this.dao.salva(audit);

#19

Cara,

Desculpa, mas as vezes eu faço as coisas sem pensar.

Entendi, agora.

Agora, a ação ele ta pegando sempre /compresempre.

Sem querer abusar, mas já abusando.

Você sabe pq?

Valeus.Obrigadão.


#20

Por que esse é o nome do seu projeto, correto?

Então ele vai pegar o path do seu projeto.

Quando você for fazer o deploy da aplicação, imagino que vá fazer como ROOT. Assim o nome some da sua URL.

Você pode fazer um replace de "/compresempre" para ""