Depois de pesquisar na Web e tentar várias maneiras diferentes, eis o que eu sugeriria para autenticação do Java EE 6:
Configure o domínio de segurança:
No meu caso, eu tinha os usuários no banco de dados. Então, segui esta postagem no blog para criar um JDBC Realm que pudesse autenticar usuários com base no nome de usuário e nas senhas com hash MD5 na minha tabela de banco de dados:
http://blog.gamatam.com/2009/11/jdbc-realm-setup-with-glassfish-v3.html
Nota: a postagem fala sobre um usuário e uma tabela de grupo no banco de dados. Eu tinha uma classe User com um atributo enumer UserType mapeado por meio de anotações javax.persistence no banco de dados. Eu configurei o domínio com a mesma tabela para usuários e grupos, usando a coluna userType como a coluna do grupo e funcionou bem.
Use autenticação de formulário:
Ainda seguindo a postagem do blog acima, configure seu web.xml e sun-web.xml, mas em vez de usar a autenticação BASIC, use o FORM (na verdade, não importa qual você usa, mas acabei usando o FORM). Use o HTML padrão, não o JSF.
Em seguida, use a dica do BalusC acima para inicializar com preguiça as informações do usuário no banco de dados. Ele sugeriu fazê-lo em um bean gerenciado, obtendo o principal do contexto de rostos. Eu usei, em vez disso, um bean de sessão com estado para armazenar informações da sessão para cada usuário, então injetei o contexto da sessão:
@Resource
private SessionContext sessionContext;
Com o diretor, posso verificar o nome de usuário e, usando o EJB Entity Manager, obter as informações do usuário no banco de dados e armazenar no meu SessionInformation
EJB.
Sair:
Também procurei a melhor maneira de sair. O melhor que eu encontrei está usando um Servlet:
@WebServlet(name = "LogoutServlet", urlPatterns = {"/logout"})
public class LogoutServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession(false);
// Destroys the session for this user.
if (session != null)
session.invalidate();
// Redirects back to the initial page.
response.sendRedirect(request.getContextPath());
}
}
Embora minha resposta esteja muito atrasada, considerando a data da pergunta, espero que isso ajude outras pessoas que acabam aqui do Google, exatamente como eu.
Tchau,
Vítor Souza
HttpServletResponse#login(user, password)
; dessa forma, você pode obter do DB o sal do usuário, as iterações e o que quer que seja usado para salgar, hash a senha que o usuário digitou usando esse sal e, em seguida, solicita que o contêiner se autentique comHttpServletResponse#login(user, password)
.Suponho que você deseja autenticação baseada em formulário usando descritores de implantação e
j_security_check
.Você também pode fazer isso no JSF usando apenas os mesmos nomes de campos predefinidos
j_username
ej_password
conforme demonstrado no tutorial.Por exemplo
Você pode fazer um carregamento lento no
User
getter para verificar se oUser
já está logado e, se não estiver, verifique se elePrincipal
está presente na solicitação e, se estiver, obtenha oUser
associadoj_username
.O
User
é obviamente acessível no JSF EL por#{auth.user}
.Para sair, faça um
HttpServletRequest#logout()
(e definaUser
como nulo!). Você pode obter um identificador doHttpServletRequest
JSF porExternalContext#getRequest()
. Você também pode invalidar completamente a sessão.Para o restante (definindo usuários, funções e restrições no descritor e no domínio de implementação), basta seguir o tutorial do Java EE 6 e a documentação do servletcontainer da maneira usual.
Atualização : você também pode usar o novo Servlet 3.0
HttpServletRequest#login()
para fazer um login programático, em vez de usar oj_security_check
que pode não ser acessível por um despachante em alguns contêineres de servlet. Neste caso, você pode usar um formulário JSF fullworthy e um feijão comusername
epassword
propriedades e umlogin
método que se parecem com isto:E essa visão no escopo do bean gerenciado que também se lembra da página solicitada inicialmente:
Desta forma, o
User
é acessível no JSF EL por#{user}
.fonte
j_security_check
não funcione em todos os servletcontainers.@WebServlet(name="testServlet", urlPatterns={"/ testServlet "}) @ServletSecurity(@HttpConstraint(rolesAllowed = {"testUser", "admin”}))
E por método nível:@ServletSecurity(httpMethodConstraints={ @HttpMethodConstraint("GET"), @HttpMethodConstraint(value="POST", rolesAllowed={"testUser"})})
FacesServlet
e você não pode (e não deseja) modificá-lo.RequestDispatcher.FORWARD_REQUEST_URI
. Os atributos de solicitação estão no JSF disponíveis porExternalContext#getRequestMap()
.Deve-se mencionar que é uma opção deixar completamente os problemas de autenticação para o controlador frontal, por exemplo, um servidor Web Apache e avaliar o HttpServletRequest.getRemoteUser (), que é a representação JAVA da variável de ambiente REMOTE_USER. Isso também permite designs sofisticados de login, como autenticação Shibboleth. A filtragem de solicitações para um contêiner de servlet por meio de um servidor da Web é um bom design para ambientes de produção, geralmente o mod_jk é usado para isso.
fonte
O problema HttpServletRequest.login não define o estado de autenticação na sessão foi corrigido no 3.0.1. Atualize o glassfish para a versão mais recente e pronto.
A atualização é bastante direta:
fonte