为了账号安全,请及时绑定邮箱和手机立即绑定

如何在JSF中实现登录过滤器?

/ 猿问

如何在JSF中实现登录过滤器?

慕桂英546537 2019-10-21 16:12:23

如何在JSF中实现登录过滤器?

我想阻止某些页面的访问,即使用户知道某些页面的网址。例如,/localhost:8080/user/home.xhtml(需要先登录)如果没有登录,则重定向到/index.xhtml.

如何在JSF中做到这一点?我在谷歌上读到需要一个过滤器,但我不知道怎么做。


查看完整描述

2 回答

?
月关宝盒

您需要实现javax.servlet.Filter类中,执行所需的工作。doFilter()方法,并将其映射到覆盖受限页的URL模式上,/user/*也许吧?内部doFilter()您应该以某种方式检查登录用户在会话中的存在。此外,还需要考虑JSF、Ajax和资源请求。JSFAjax请求需要一个特殊的XML响应来让JavaScript执行重定向。JSF资源请求需要跳过,否则登录页面将不再有任何CSS/JS/映像。

假设你有一个/login.xhtml页面,该页面将登录用户存储在JSF托管bean中。externalContext.getSessionMap().put("user", user),然后你就可以通过session.getAttribute("user")通常的方式如下:

@WebFilter("/user/*")public class AuthorizationFilter implements Filter {

    private static final String AJAX_REDIRECT_XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
        + "<partial-response><redirect url=\"%s\"></redirect></partial-response>";

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {    
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        HttpSession session = request.getSession(false);
        String loginURL = request.getContextPath() + "/login.xhtml";

        boolean loggedIn = (session != null) && (session.getAttribute("user") != null);
        boolean loginRequest = request.getRequestURI().equals(loginURL);
        boolean resourceRequest = request.getRequestURI().startsWith(request.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER + "/");
        boolean ajaxRequest = "partial/ajax".equals(request.getHeader("Faces-Request"));

        if (loggedIn || loginRequest || resourceRequest) {
            if (!resourceRequest) { // Prevent browser from caching restricted resources. See also https:
            //stackoverflow.com/q/4194207/157882
                response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
                response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
                response.setDateHeader("Expires", 0); // Proxies.
            }

            chain.doFilter(request, response); // So, just continue request.
        }
        else if (ajaxRequest) {
            response.setContentType("text/xml");
            response.setCharacterEncoding("UTF-8");
            response.getWriter().printf(AJAX_REDIRECT_XML, loginURL);
             // So, return special XML response instructing JSF ajax to send a redirect.
        }
        else {
            response.sendRedirect(loginURL); // So, just perform standard synchronous redirect.
        }
    }


    // You need to override init() and destroy() as well, but they can be kept empty.}

此外,过滤器还禁用了安全页面上的浏览器缓存,因此浏览器回退按钮将不再显示它们。

万一您碰巧使用JSF实用程序库OmniFaces,上述代码可简化如下:

@WebFilter("/user/*")public class AuthorizationFilter extends HttpFilter {

    @Override
    public void doFilter(HttpServletRequest request, HttpServletResponse response, HttpSession session, FilterChain chain)
     throws ServletException, IOException {
        String loginURL = request.getContextPath() + "/login.xhtml";

        boolean loggedIn = (session != null) && (session.getAttribute("user") != null);
        boolean loginRequest = request.getRequestURI().equals(loginURL);
        boolean resourceRequest = Servlets.isFacesResourceRequest(request);

        if (loggedIn || loginRequest || resourceRequest) {
            if (!resourceRequest) { // Prevent browser from caching restricted resources. See also 
            https://stackoverflow.com/q/4194207/157882
                Servlets.setNoCacheHeaders(response);
            }

            chain.doFilter(request, response); // So, just continue request.
        }
        else {
            Servlets.facesRedirect(request, response, loginURL);
        }
    }}

另见:

  • 我们的servlet过滤wiki页面

  • 如何与数据库中的用户进行身份验证/授权?

  • 使用JSF2.0/Facelets,是否有一种将全局侦听器附加到所有Ajax调用的方法?

  • 在JSF web应用程序中避免后退按钮

  • JSF:如何在JSF中控制访问和权限?



查看完整回答
反对 回复 2019-10-22
?
慕神8447489

虽然使用一个简单的servlet过滤器当然是合法的,但也有一些替代方法,如

  • 弹簧安全

  • JavaEE安全

  • 阿帕奇·希罗



查看完整回答
反对 回复 2019-10-22

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信