Segue uma sugestão de filtro:
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
boolean autorizado = false;
HttpServletRequest hrequest = (HttpServletRequest) request;
//processa as URIs que estão na lista de exceções.
String URI = hrequest.getRequestURI();
String ctx = hrequest.getContextPath();
for (int i = 0; i < enderecosLivres.length; i++) {
if (URI.startsWith(ctx + enderecosLivres[i] + "/")
|| URI.equals(ctx + "/")
|| URI.startsWith(ctx + "/login")
|| URI.contains("favicon.ico")) {
autorizado = true;
break;
}
}
HttpSession session = hrequest.getSession(true);
String usr = null;
String pwd = null;
if (!autorizado) { //não está na lista de exceções
usr = (String) session.getAttribute("corporativo_usr");
pwd = (String) session.getAttribute("corporativo_pwd");
if (!Validador.vazio(usr)) {
autorizado = controle.autorizar(usr, pwd, URI); //aqui está uma classe que faz a consulta ao banco.
}
}
if (autorizado) { //autorizado
chain.doFilter(request, response);
} else if (!autorizado && usr != null) { //não autorizado
RequestDispatcher rd = hrequest.getRequestDispatcher("/login/nautor.jsp");
rd.forward(request, response);
} else { //não logado
session.setAttribute("msg", "login");
session.setAttribute("URI", URI);
RequestDispatcher rd = hrequest.getRequestDispatcher("/login/index.jsp");
rd.forward(request, response);
}
}
O fragmento do web.xml fica assim (adapte-o a sua realidade):
<filter>
<filter-name>FiltroControleAcesso</filter-name>
<filter-class>br.com.corporativo.acessos.FiltroControleAcesso</filter-class>
<init-param>
<description>URLs a serem ignoradas pelo Controle de Acesso</description>
<param-name>enderecosLivres</param-name>
<param-value>/css;/img;/js;/principal;/index.jsp;/fckeditor;/userfiles</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>FiltroControleAcesso</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Observe que o método da consulta retorna boolean, facilitando um pouco. Esse método é a chave de tudo, pois nele comparamos a URI desejada com os mapeamentos que o usuário tem acesso por intermédio do seu grupo. O ideal é criar um DAO para isolar o acesso ao banco de dados.
As tabelas são simples:
usuarios —> id de usuário, nome, senha etc
grupos_usuarios —> id do usuário, id do grupo.
grupos —> id do grupo, nome do grupo, etc.
mapeamentos —> id do mapeamento, id do grupo, URI do mapeamento.
Estou considerando que um usuário pode pertencer a vários grupos e um grupo tem vários mapeamentos. Um mapeamento poderia aparecer em vários grupos se você quiser, mas eu preferi um modelo mais simples.
Procure implementar aos poucos de forma a poder testar e dominar completamente o modelo.
Boa Sorte!