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

2024-05-20

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

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


您需要实施javax.servlet.Filter http://docs.oracle.com/javaee/6/api/javax/servlet/Filter.html课堂上,做所需的工作doFilter()方法并将其映射到覆盖受限页面的 URL 模式上,/user/*或许?在 - 的里面doFilter()您应该以某种方式检查会话中登录用户的存在。此外,您还需要考虑 JSF ajax 和资源请求。 JSF ajax 请求需要特殊的 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 http://omnifaces.org,上面的代码可以减少如下:

@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 页面 https://stackoverflow.com/tags/servlet-filters/info
  • 如何处理数据库中用户的身份验证/授权? https://stackoverflow.com/questions/9965708/how-to-handle-authentication-authorization-with-users-in-a-database
  • 使用 JSF 2.0 / Facelets,有没有办法将全局侦听器附加到所有 AJAX 调用? https://stackoverflow.com/questions/9305144/using-jsf-2-0-facelets-is-there-a-way-to-attach-a-global-listener-to-all-ajax/
  • 避免 JSF Web 应用程序上的后退按钮 https://stackoverflow.com/questions/10305718/avoid-back-button-on-jsf-web-application
  • JSF:如何控制 JSF 中的访问和权限? https://stackoverflow.com/questions/12516349/jsf-how-control-access-and-rights-in-jsf
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 JSF 中实现登录过滤器? 的相关文章

随机推荐

  • 运行多个并行 Selenium WebDriver 会话

    我想知道我们是否能够运行两个 Selenium WebDriver 会话 或者如何使用同一个 WebDriver 处理两个浏览器窗口并并行运行它们 尝试像下面这样定义您的 TestNg 套件 然后它将同时开始运行两者
  • 如何在 gulp.src 中使用基本正则表达式?

    我正在尝试选择两个文件gulp src highcharts js and highcharts src js 当然 我知道我可以使用数组表达式显式添加这两个表达式 但出于学习目的 我尝试为它们编写一个表达式 我读过可以使用简单的正则表达式
  • Nginx url 限制 502 网关

    我有一个问题 但我接受绕过此功能的其他建议 基本上 我在 get 请求中向我的服务器发送大约 3000 个字符的大行文本 然后服务器将其作为 url 中的参数发送到谷歌翻译 问题 当 url gt 1900 个字符时 Nginx 会抛出 5
  • 我在在线程序挑战编译器中遇到演示错误

    include
  • KeyboardAvoidingView - 隐藏键盘时重置高度

    我正在使用 React NativeKeyboardAvoidingView设置我的高度View当显示键盘时 但是当我关闭应用程序中的键盘时 视图的高度不会变回原来的值
  • ng-cli 6 和 font Awesome 图标不起作用

    我正在使用 font awesome 4 70 Angular 6 0 8 和 cli 6 0 8 完整版本如下 我正在尝试用 cli 的 ng build 替换我们现有的 webpack 进程 我遇到了 font Awesome 图标未显
  • Java &= 运算符应用 & 或 && 吗?

    Assuming boolean a false 我想知道是否这样做 a b 相当于 a a b logical AND a is false hence b is not evaluated 或者另一方面 这意味着 a a b Bitwi
  • 在 React Native 中将 Props 传递到屏幕

    我已经开始学习 React Native 并且一如既往地从创建可重用组件开始 我了解了如何在创建自定义组件时传递和访问 props 我想在 React Native 中创建一个基本屏幕 它具有通用属性 并且我的应用程序中的所有屏幕都可以设置
  • 如何使用 Passport 验证 Supertest 请求?

    我使用 Passport js 进行身份验证 本地策略 并使用 Mocha 和 Supertest 进行测试 如何使用 Supertest 创建会话并发出经过身份验证的请求 正如 zeMirco 指出的那样 底层superagent模块支持
  • CakePHP 多站点(如 WPMU + 域映射)...可能吗?

    所以我刚刚开始使用 CakePHP 想知道是否可以执行以下操作 一次安装 Cake 并使用超级管理员登录 然后 管理员有权访问指定的 子站点 并能够在这些子站点上创建 编辑内容和用户 最后 能够将域名 不是子域 而是唯一域 映射到路由 所以
  • 使用 C# 从 DateTime 获取日期

    愚蠢的问题 给定日期时间中的日期 我知道它是星期二 例如我如何知道它的 tue 2 和 mon 1 等 Thanks 您正在寻找星期几 http msdn microsoft com en us library system datetim
  • 双精度类型二维多维数组的 pinvoke 编组作为 c# 和 c++ 之间的输入和输出

    我有以下我正在尝试解决的双物质类型的 2d 多维数组的 c 和 c pinvoke 编组 我已经查看了以下热门内容以获得我目前拥有的内容使用双精度数组进行 P Invoke 在 C 和 C 之间编组数据 https stackoverflo
  • WinRT 定时注销

    我正在开发一个 WinRT 应用程序 要求之一是应用程序应具有 定时注销 功能 这意味着在任何屏幕上 如果应用程序空闲了 10 分钟 应用程序应该注销并导航回主屏幕 显然 执行此操作的强力方法是在每个页面的每个网格上连接指针按下事件 并在触
  • HTML 默认图像大小

    我在我的代码上显示 3 张图片 图片具有不同的尺寸 宽度和高度 div class row div class col lg 12 h2 class page header Gallery h2 div div class col md 4
  • 具有多个 from 子句的 Either 的 language-ext 任务

    我正在用 language ext 学习 FP 我遇到了一个我无法克服的问题 我将代码简化为以下示例 using System using System Threading Tasks using LanguageExt using sta
  • 嵌入式 Jetty - 以编程方式添加基于表单的身份验证

    有没有一种方法可以按如下方式以编程方式添加基于表单的身份验证 我用的是我自己的LdapLoginModule 最初我使用基本身份验证并且工作正常 但现在我想在登录页面上进行更多控制 例如显示徽标等 有没有好的样品 我正在使用嵌入式 jett
  • Julia:如何更新到软件包的最新版本(即 Flux)

    I have Julia 1 1 在本例中 我想更新到软件包的最新版本Flux 8 3 0根据Flux jl 的文档 https fluxml ai Flux jl stable 当我打字时 Pkg status Flux I get St
  • 如何为新的 Silverlight 应用程序在 WCF、REST、POX 和 RIA 服务之间进行选择

    There a lotSilverlight 应用程序连接回其服务器的不同方式 包括 WCF Windows 通信基础 http msdn microsoft com en us netframework aa663324 aspx RES
  • JAXB - 列表<可序列化>?

    我使用 xjc 制作了一些课程 public class MyType XmlElementRefs XmlElementRef name MyInnerType type JAXBElement class required false
  • 如何在 JSF 中实现登录过滤器?

    即使用户知道某些页面的网址 我也想阻止某些页面的访问 例如 localhost 8080 user home xhtml 需要先登录 如果没有登录则重定向到 index xhtml 在 JSF 中如何做到这一点 我在谷歌上看到需要一个过滤器