VRaptor - Controle de Acesso Dinâmico

3 respostas
D

Iniciei uma discução na lista do vraptor, mais ainda não cheguei numa solução que me agradace.

Minha situação é a seguinte, tenho dois perfis básicos, um é o ADM, esse é o administrador do sistema todo, outro é o ADM_CLIENTE, esse é o meu cliente, que tem restrições de algumas paginas, mais ele pode criar novos perfis conforme a sua necessidade. Por exemplo:

Cadastro de Produtos, onde tenho um CRUD básico.

O Cliente pode criar um perfil onde o funcionário dele, pode somente criar e visualizar os dados dos produtos, mais não pode atualizar ou excluir. Mais ele também pode criar outro perfil dando todas as permissões para outro funcionario.

Qual a solução vocês me sugerem?

3 Respostas

Lucas_Cavalcanti

você pode usar uma convenção de nomes e autorizar baseado nisso…

você tem os modelos (Produto, Item, etc) e os métodos do crud (visualizar, atualizar, criar, deletar e listar).
se os métodos sempre tiverem esse nome, vc pode autorizar pelo nome do modelo+metodos

no VRaptor vc pegaria esses nomes assim, num interceptor:

ResourceMethod method // o que veio do intercept

String modelo = method.getResource().getType().getSimpleName().replace("Controller", "");
String metodo = method.getMethod().getName();
cinei

Apesar de achar que da forma que faço é meio trabalhoso, mas permite ao administrador conceder qualquer permissão pré-definida no sistema:
De forma simplificada, tenho o seguinte:

É feita a anotação @Restricao (há uma interface para isso) nos métodos importantes de cada Controller:

@Restricao({"Incluir", "Alterar", "AlterarUnidadeConsumo", "AlterarUnidadeCompra"})
@Path("/estProduto/armazenar")
public void armazenar (EstProduto estProduto){
        ...
}

Os controles são cadastrados no banco com suas respectivas restrições, que também serão utilizados para gerar o menu dinâmico. Se o usuário não tiver permissão alguma naquele Controller nem precisa mostrar no menu.
Os usuários são agrupados em perfis que receberão suas respectivas permissões (sempre guardadas no banco de dados).

Ao tentar executar uma ação, o filtro checa e existência de uma anotação. Se houver, checa se há permissão para o perfil do usuário:

boolean temPermissao = true;
if ((userInfo.getUser() !=null) && (!userInfo.getUser().getPerfil().isAdministrador()) && 
	(!userInfo.getUser().getPerfil().isDesenvolvedor())){
	if(method.getMethod().isAnnotationPresent(Restricao.class)) {
		temPermissao = verificaRestricao(userInfo.getUser().getPerfil().getId(), method.getResource().getType().getSimpleName(), 
			method.getMethod().getAnnotation(Restricao.class).value());
	} 		
}
...

private boolean verificaRestricao(Long idPerfil, String controller, String[] restricoes){
	int pos = controller.indexOf("Controller");
	if (pos > 0) {
		controller = controller.substring(0, pos);
	}
	boolean temPermissao = false;
	for (String restricao : restricoes) {
		temPermissao =  permissaoDao.permissaoEm(idPerfil, controller, restricao); //verificar se o usuário possui esta permissão
		if (temPermissao) break;
	}
	return temPermissao;
}

É isto …

D

Olá pessoal, obrigado pelas dicas.

Pois é, não tinha me lembrado do menu dinâmico, bem lembrado @cinei.

Vendo as duas soluções, pra evitar criar mais uma anotação, da pra fazer um mix das duas soluções propostas.

Nesse caso interceptar somente as uris que estão cadastradas no banco.

Quando chegar em casa, vou tentar fazer algo nesse sentido, daí volto aqui e posto a solução pra compartilhar e discutir melhor.

Criado 4 de fevereiro de 2011
Ultima resposta 7 de fev. de 2011
Respostas 3
Participantes 3