JSF表单登录页面重定向在我的过滤器之前命中

时间:2011-10-17 12:28:25

标签: security java-ee-6 servlet-filters

我正在尝试在我的java ee 6应用程序中实现remember-me功能,但是我将它与内置安全功能相结合的问题。我的web.xml中有以下配置:

<login-config>
    <auth-method>FORM</auth-method>
    <realm-name>my-realm</realm-name>
    <form-login-config>
        <form-login-page>/login.jsf</form-login-page>
        <form-error-page>/login.jsf</form-error-page>
    </form-login-config>
</login-config>

我正在尝试创建的是一个过滤器,如果他们有一个包含某些数据的cookie,则会自动记录其会话中的某个人已过期。这是有效的,但是当调用过滤器时,重定向到login.jsf已经生效,然后我才能对其进行任何更改。我假设在java ee自己的安全系统之前调用过滤器,因为它们实际上是在安全页面上调用的,但事实并非如此。有没有办法让用户访问他们请求的同一页面而不是重定向到login.jsf?

过滤:

@WebFilter(
    filterName="authFilter",
    servletNames={
        "Faces Servlet"
    }
)
public class AuthFilter implements Filter {

    public AuthFilter() {
    }

    @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){
            String uuid = CookieUtil.getCookieValue(req, "rememberme");
            if(uuid != null){
                UserBean userBean = EJBUtil.lookup(UserBean.class);
                RememberMe rememberme = userBean.findRememberMe(uuid);
                if(rememberme != null){
                    user = rememberme.getUser();
                    try{
                        req.login(user.getEmail(), user.getPasswordDigest());
                        req.getSession().setAttribute("user", user);
                        CookieUtil.addCookie(res, "rememberme", uuid, CookieUtil.AGE_ONE_YEAR);
                    }catch(ServletException e){}
                }
                else{
                    CookieUtil.removeCookie(res, "rememberme");
                }
            }
        }
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
    }

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

1 个答案:

答案 0 :(得分:2)

确实在所有过滤器之前调用了容器管理的身份验证。这是一项安全限制。

你基本上有3种选择:

  • 使用程序化过滤和登录,以便您获得更精细的控制。
  • 执行与preRenderView关联的bean的login.jsf事件方法中的工作。
  • 抓住一个框架,在透明的容器管理安全性之上支持“记住我”工具,例如Apache Shiro或Spring Security。