Controle de permissões com o amigo JSF

Olá amigo, estou prestes a desenvolver um controle de permissões para uma aplicação utilizando Spring, Hibernate, JSF e Primefaces.

Tenho uma ideia de fazer a tabela das permissoes e usuarios, onde essas permissões seriam os booleanos que controlariam os “rendereds” das páginas.

Mas acho que isso vai ficar muito pesado para ficar em sessão, e as páginas ficarem dando buscas e buscas para saber se mostram ou não o item de menu ou botão por exemplo.

Alguem conhece uma forma melhor para eu implementar e controlar o que usuário pode ou não ver?

Eu delete isso pra cada managedBean…

e tenho um Listener (Na verdade um PhaseListener)
que intercepta…

e tenho um UsuarioLogado que possui metodos que verifica se o usuario tem ou não acesso…

e PS: sim, tenho um monte de rendered… nao tem como fugir

Neste seu caso, quando vc diz que em um usuariologado que verifica, no caso vc faz pra cada requisição uma consulta no banco, ou quando vc se loga vc ja carrega todas as permissões numa lista e verifica nela?

pelo visto os rendereds perseguem kk

você pode montar o menu dinamicamente, vou tentar fazer isso.

Meu menu era montado dinamicamente, com o tree, mas o cliente quer que cada botão, e ação do sistema esteja mapeada hehe, ai achei melhor fazer um só hehe

Eu monto o Menu dinamicamente tbem…

Não é difícil…
vou mostrar um pedaçin de código:

[code]
private void createMegaMenu() {
// initialize the model
megaModel = new DefaultMenuModel();

	MenuItem paginaInicial = new MenuItem();	
	paginaInicial.setId("itemPaginaInicial");
	paginaInicial.setIcon("ui-icon-home");
	paginaInicial.setStyleClass("menu");
	paginaInicial.setUrl("/default.xhtml?faces-redirect=true");
	paginaInicial.setValue("Minha página");
	megaModel.addMenuItem(paginaInicial);

	List<ModuloFacade> menus = extrairMenu();
	
	for(ModuloFacade menu : menus){
		List<ModuloFacade> submenus = buscarFilho(menu);
		Boolean add = false;
		
		if(ObjectUtil.nullOrEmpty(submenus)){
			continue;
		}

		Submenu topLevelMenu = new Submenu();
		topLevelMenu.setLabel(menu.getRotulo());
		topLevelMenu.setIcon(menu.getIcone());
		topLevelMenu.setStyleClass("menu");
		
		// Criar a coluna que os sub-menus devem ficar
		Column aColumn = new Column();

		for(ModuloFacade subSubMenu : submenus){
			List<ModuloFacade> subSubMenus = buscarFilho(subSubMenu);
			
			if(ObjectUtil.nullOrEmpty(subSubMenus)){
				continue;
			}
			
			Submenu nestedMenu = new Submenu();
			nestedMenu.setLabel(subSubMenu.getRotulo());
			nestedMenu.setIcon(subSubMenu.getIcone());

			
			for(ModuloFacade item : buscarFilho(subSubMenu)){
				MenuItem anItem = new MenuItem();
				anItem.setUrl(item.getOutcome()+"?faces-redirect=true");
				anItem.setValue(item.getRotulo());
				anItem.setIcon(item.getIcone());					
				
				if(modulosAcesso.contains(item)){
					// Adicionar o item de menu ao submenu
					nestedMenu.getChildren().add(anItem);

					// Adicionar o submenu a coluna
					aColumn.getChildren().add(nestedMenu);

					// Adicionar a coluna ao Menu superior
					topLevelMenu.getChildren().add(aColumn);
					add=true;
				}
			}
		}

		if(add){
			megaModel.addSubmenu(topLevelMenu);				
		}

	}

	MenuItem logOff = new MenuItem();
	FacesContext facesCtx = FacesContext.getCurrentInstance();
    ELContext elCtx = facesCtx.getELContext();
    ExpressionFactory expFact = facesCtx.getApplication().getExpressionFactory();
        
    logOff.setActionExpression(expFact.createMethodExpression(elCtx, "#{loginController.logoff}", String.class, new Class[0]));
	logOff.setId("itemLogOff");
	logOff.setIcon("ui-icon-power");
	logOff.setStyleClass("ui-menu-parent menu");
	logOff.setValue("Sair");
	
	megaModel.addMenuItem(logOff);

}[/code]

Como eu disse acima, ja tenho o menu dinamico, me falta a questão de cada click de botão dentro do sistema, hehe.

tipo cada clique do botão ele redirecionar para outra pagina ? com o menu dinamico faz isso

Acho que não entendi muito bem esse ‘requisito’!

Como assim?

Tipo, imagina que em uma tela de faturamento, tens várias opções, não estamos falando do menu, e sim de botões e links que permitem fazer ações no sistema, onde algumas dessas açõessó seram permitidas a quem tiver esse tipo de permissão.

então
o controller !
com rendered!
:smiley:

Intão kkk, vou fazer isso mesmo, quando o cara se logar eu coloco tudo num map e fico verificando.

Não cara!
faz no controller…

tipo

[code]public boolean getAcessoNovo(){
//alguma regra aqui
return true;
}

[/code]

Então no caso a cada “get” faço uma consulta no banco? pq o que eu iria fazer é que a cada “get” ele fosse no mapa e viss se o cara tem ou n aquela permissão.

darksteel3000 você pode criar uma classe que faça isso pra você e usar ela como um pai, mais ou menos assim:


public class PadraoBean {
  private boolean novoDesabilitado;
  private boolean editarDesabilitado;
  private boolean excluirDesabilitado;

  public PadraoBean(String tela) {
    // lerAutorizacao
    novoDesabilitado   = parametroNovo;
    editarDesabilitado  = parametroEditar;
    excluirDesabilitado = parametroExcluir;
  }

  // get e set
}

public class ClienteBean extends PadraoBean{

  public ClienteBean() {
    super("cliente");
  }
}

<p:commandButton disabled="#{clientBean.novoDesabilitado}"/>

É só pra você ter uma ideia, em vez de você escrever o código toda vez você irá ver no banco, mas o código só vai ta escrito no PadraoBean, aí você passa os parâmetros necessários pelo clienteBean.

Sim, eu tenho um BaseController … todos meus MB extendem… e pronto :slight_smile:

mas no caso, são regras específicas, só acrescentar outros métodos e tal.

PS: eu não consulto o banco toda hora, eu tenho o meu usuario na sessão (UsuarioLogado)
e esta classe encapsula suas permissões

d34d_d3v1l você guarda as permissões em uma lista ?

Isto esta encapsulado na minha regra de negócio né…

Eu tenho Modulo (representa um menu)…
Usuario , e Perfil…

Perfil possui n Modulos…

A ligação entre PerfilModulo, possui 4 booleans:

  • inserir
  • editar
  • excluir
  • relatorios

…UsuarioLogado possui:

  • Perfil

e dentro eu possui um metodo:
“possuiAcesso(String outcome)”

que eu verifico se o usuario tem acesso a determinado link…
Se nao tiver, o listener barra a entra e redireciona pra pagina Inicial!

Se tiver, ele chega lá… e vai perguntando:
possuiAcessoNovo ?
possuiAcessoEditar ?

e assim vai

Tive que implementar isso uma vez na emergência,sem salvar no banco,vou mostrar como ficou:

MB:

public class PermissaoController {

	public PermissaoController(){
		montaPermissoes();
	}

	public static String ADMINISTRADOR = "Administrador";
	
	Map&lt;String,List&gt;&lt;String&gt;&gt; permissoes  = new HashMap&lt;String, List&gt;&lt;String&gt;&gt;() ;

	void montaPermissoes(){
		permissoes.put(&quot;menuPreCadastro&quot;,Arrays.asList(ADMINISTRADOR));
}

public boolean temPermissao(String acao){
		boolean acesso = false;
		Usuario u = (Usuario)FacesUtils.getSession().getAttribute(&quot;usuario&quot;);
		String permissaoUsuario = u.getPerfil().getDescricao();
		if(permissoes.get(acao).contains(permissaoUsuario)){
			acesso = true;
		}
		return acesso;
	}

xhtml:

&lt;rich:dropDownMenu rendered="#{permissaoController.temPermissao('menuPreCadastro')}"&gt;