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

Posted

技术标签:

【中文标题】我的过滤器之前的 JSF 表单登录页面重定向命中【英文标题】:JSF form-login-page redirect hits before my filter 【发布时间】:2011-12-09 06:34:27 【问题描述】:

我正在尝试在我的 java ee 6 应用程序中实现一个记住我的功能,但我在将它与内置安全功能结合起来时遇到了问题。我的 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】:

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

你基本上有 3 个选择:

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

【讨论】:

1.感觉这种方法会花费大量时间,同时会变得更糟,并且不得不重新发明一个 url 匹配系统等,只是为了解决一个非常小的问题。 2. 这有什么帮助?用户仍然会被重定向到 login.jsf,我不知道他来自哪里。 3. 我检查了 Spring Security,但它看起来完全有自己的安全机制,这意味着必须基本上重做我所有的安全代码/配置。即使它支持 request.login(),我是否不需要复制我的大部分限制设置? Shiro 看起来很有趣,如果它可以轻松实现的话 1.是的,你基本上是在重新发明一些***的尖峰。 2. 原始 URI 应该可用作请求属性之一(抱歉,不知道顶部的键,请在请求属性映射中查看)。 3. 我从未使用过 Spring Security,但认为它可以与 CMS 结合使用(来自 SS 文档:虽然我们建议人们使用 Spring Security 进行身份验证,而不是与现有的容器管理身份验证集成,但它仍然是支持 - 与您自己的专有身份验证系统集成。)。 关于2:HttpServletRequest.getRequestURI指向我的登录页面,而HttpServletRequest.getParameterMap是空的,所以我真的不认为原来的URL可用。 请求属性,而不是请求参数。 ExternalContext#getRequestMap() 应该提供所有这些的映射。

以上是关于我的过滤器之前的 JSF 表单登录页面重定向命中的主要内容,如果未能解决你的问题,请参考以下文章

使用 JSF 2.0 实现重定向登录的正确方法是啥?

如何使用 PrimeFaces 在 JSF 上重定向?

将 PrimeFaces 与 JSF 一起使用时 Shiro 重定向到错误的位置

JSF 重定向在过滤器中导致异常

JSF 页面不使用过滤器接口重定向

登录后重定向错误(Java EE w/JSF)