如何使用带有SHA-256配置安全领域的HttpServletRequest#login()程序化登录

时间:2012-04-24 14:55:10

标签: security jsf jsf-2 glassfish-3 servlet-3.0

我已阅读there,我使用的是使用sha-256摘要算法配置的glassfish 3.1.1安全域。有关于此的任何教程吗?也许我很沮丧,我想用这段代码登录:

public void login() throws NoSuchAlgorithmException {
    FacesContext context = FacesContext.getCurrentInstance();
    HttpServletRequest request = (HttpServletRequest)context.getExternalContext().getRequest();

    EntityManager em = emf.createEntityManager();
    boolean committed = false;
    try {
        FacesMessage msg = null;
        EntityTransaction entr = em.getTransaction();
        entr.begin();
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            md.update(password.getBytes());
            byte byteData[] = md.digest();
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < byteData.length; i++) {
                sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
            }
            password = sb.toString();
            Query query = em.createQuery("SELECT COUNT(u) FROM EntityUser u WHERE u.userName = :userName AND u.password = :password")
                    .setParameter("userName", userName).setParameter("password", password);
            long result = (long)query.getSingleResult();
            if (result == 1) {
                request.login(userName, password);
                msg = new FacesMessage();
                msg.setSeverity(FacesMessage.SEVERITY_INFO);
                msg.setSummary("You are logged in");
            }
            entr.commit();
            committed = true;
        } catch (ServletException e) {
            context.addMessage(null, new FacesMessage("wrong username or password"));
        }
        finally {
            if (!committed) entr.rollback();
        }
    } finally {
        em.close();
    }
}

结果变量返回1,但是request.login(userName,password); if条件总是抛出servletexception。

3 个答案:

答案 0 :(得分:1)

你能发布异常堆栈跟踪吗?这样就可以更容易地理解异常的来源。但从您当前提供的代码判断,您应该提供

request.login(userName, password);

密码为纯文本密码,而不是哈希密码。

Interface HttpServletRequest
ServletException - if the configured login mechanism does not support username password
authentication, or if a non-null caller identity had already been established (prior to 
the call to login), or if validation of the provided username and password fails.

答案 1 :(得分:0)

登录失败可能有很多原因。您刚检查了表中是否有适当的用户名和密码。 Glassfish在两个表中进行两次查询(在身份验证过程中)。一个到表指定为userTable,第二个指定为groupTable,它们是在安全领域定义中确定的。检查web.xml和glassfish-web.xml是否也正确。

答案 2 :(得分:0)

质疑问题是关于方法的整体

  

request.login(userName,password);

作者使一切正确,甚至他自己的用户数据库认证方式,但 request.login 需要设置认证领域,以供此方法使用。你有自己的,你不需要单独的 request.login 身份验证。对于你需要它的情况 - 这就是你如何做到jdbc-realm-setup-with-glassfish-v3

因此,在得到结果= 1后,您设置了context.getExternalContext().getSessionMap().put("user", u); 并发送重定向context.getExternalContext().redirect(context.getExternalContext().getRequestContextPath() + "какой-то модуль.xhtml");

并使用webfilter阻止访问/Pages/*.xhtml而无需登录。

@WebFilter("/Pages/*")
    public class LoggingFilter implements Filter {

        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            HttpServletRequest req = (HttpServletRequest)request;
            HttpServletResponse res = (HttpServletResponse)response;
            User user = (User) req.getSession().getAttribute("user");         
            if(user != null){
                chain.doFilter(request,response);
            }  
            else res.sendRedirect(req.getContextPath()+"/запрос_учетных_данных.xhtml");
        }

        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
        }

        @Override
        public void destroy() {
        }
    }