有没有简单的方法来预处理和重定向GET请求?

Fra*_*fka 11 authentication jsf jsf-2 servlet-filters

我正在寻找最佳实践答案.我想为GET请求做一些预处理.因此,例如,如果不允许用户查看该页面,则将其重定向到另一页面.但我不想使用普通的servlet过滤器,因为我想表达这种行为faces-config.xml.这是可能的,如何调用,怎么做?

我可以定义一些Filter bean,它还返回一个String,告诉faces-config.xml下一步该去哪里?

我用Google搜索,但只打了正常的过滤器.如果我使用的过滤器,可以一个@WebFilter@ManagedBean在同一时间?还是那种糟糕的风格?

Bal*_*usC 18

如果您在JSF之上进行HTTP请求身份验证,那么servlet过滤器确实是最好的方法.JSF"只是"一个MVC框架,并且未指定JSF API中的任何内容来过滤传入的HTTP请求以检查用户身份验证.在正常的GET请求中,JSF托管bean通常仅在即将创建和发送HTTP响应时构建,或者可能已经提交.这不受托管bean内部的控制.如果响应已经提交,您将无法再更改(重定向)它.在即将发送响应之前,确实需要进行身份验证和更改请求/响应.

如果您不是家庭主妇认证,那么您可以使用Java EE提供的容器管理认证,这将由<security-constraint>条目声明web.xml.请注意,这也与JSF分离,但它至少可以帮助您避免在homegrowing servlet过滤器和托管bean.

一般的做法是组背后一定URL格式,如:受限制的页面/app/*,/private/*,/secured/*,等,并采取一个事实,即JSF存储会话范围的Bean的优势HttpSession属性.想象一下,你有一个JSF会话作用域托管bean UserManager,它保存登录用户,然后你可以检查它如下:

@WebFilter(urlPatterns={"/app/*"})
public class AuthenticationFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        HttpSession session = request.getSession(false);
        UserManager userManager = (session != null) ? (UserManager) session.getAttribute("userManager") : null;

        if (userManager == null || !userManager.isLoggedIn()) {
            response.sendRedirect(request.getContextPath() + "/login.xhtml"); // No logged-in user found, so redirect to login page.
        } else {
            chain.doFilter(req, res); // Logged-in user found, so just continue request.
        }
    }

    // ...
}
Run Code Online (Sandbox Code Playgroud)

如果你使用的是JSF 2.2+,那么还有另一种方法可以在发送之前控制响应.你可以利用<f:viewAction>.将以下内容放在您的视图中:

<f:metadata>
    <f:viewAction action="#{authenticator.check}" />
</f:metadata>
Run Code Online (Sandbox Code Playgroud)

@Named
@RequestScoped // Scope doesn't matter actually. The listener will always be called on every request.
public class Authenticator {

    public String check() {
        if (authenticated) {
            return null;
        }
        else {
            return "login?faces-redirect=true";
        }
    }

    // ...
}
Run Code Online (Sandbox Code Playgroud)

保证在呈现响应之前触发此操作.否则,当您在例如中完成工作时@PostConstruct,java.lang.IllegalStateException: response already committed当第一次创建bean时,当响应已经部分呈现(并已提交)时,您可能会冒险.

在处理HTTP身份验证时,我不会认为它是一种"最佳"做法.它使它与JSF结合得太紧.你应该继续使用servlet过滤器.但出于其他目的,它可能没问题.

也可以看看: