检查会话是否存在 JSF

发布于 2024-12-15 22:41:10 字数 257 浏览 5 评论 0原文

我有一个登录页面,其中有一个 User bean 来验证一个人的用户名和密码。该 Bean 是会话范围的。 如果有人写了一个URL并试图跳转登录页面,我如何检查并将他重定向到登录页面?

另一方面。假设我已经登录并且正在工作,突然我出去了一段时间并且我的会话过期了。当我返回并尝试与表单交互时,它会发送一条消息,提醒我会话过期。发生这种情况时,如何再次重定向到登录表单?

提前致谢。希望我能解释一下自己。

莫贾拉 2.1.4、雄猫 7、战斧 1.1.11

I have a login page where I have a User bean to authenticate username and password for a person. This Bean is Session Scoped.
If someone writes a URL and tries to jump the login page, how can I check that and redirect him to the login page?

On the other hand. Suppose I have logged in and I was working and suddenly I go out for a while and my session expires. When I return and try to interact with the form it sends a message alerting me the session expiration. How can I redirecto again to the login form when this occurs?

Thanks in advance. Hope I explain myself.

Mojarra 2.1.4, Tomcat 7, Tomahawk 1.1.11

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

幸福不弃 2024-12-22 22:41:10

如果有人写了一个 URL 并尝试跳转登录页面,我如何检查并将他重定向到登录页面?

您似乎使用了自行开发的身份验证。在这种情况下,您需要实现 servlet 过滤器。 JSF 将会话范围的托管 bean 存储为 HttpSession 的属性,因此您只需在 doFilter() 方法中进行检查即可:

HttpServletRequest req = (HttpServletRequest) request;
UserManager userManager = (UserManager) req.getSession().getAttribute("userManager");

if (userManager != null && userManager.isLoggedIn()) {
    chain.doFilter(request, response);
} else {
    HttpServletResponse res = (HttpServletResponse) response;
    res.sendRedirect(req.getContextPath() + "/login.xhtml");
}

将此过滤器映射到覆盖安全页面的 URL 模式上,例如/app/*


当我返回并尝试与表单交互时,它会发送一条消息,提醒我会话过期。发生这种情况时如何再次重定向到登录表单?

我知道这涉及 Ajax 请求?对于正常请求,您可以在 web.xml 中使用 。如果无法在 web.xml 中将状态保存方法设置为客户端,如下所示

<context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
</context-param>

,那么您需要实现自定义 ExceptionHandler

public class ViewExpiredExceptionHandler extends ExceptionHandlerWrapper {

    private ExceptionHandler wrapped;

    public ViewExpiredExceptionHandler(ExceptionHandler wrapped) {
        this.wrapped = wrapped;
    }

    @Override
    public void handle() throws FacesException {
        FacesContext facesContext = FacesContext.getCurrentInstance();

        for (Iterator<ExceptionQueuedEvent> iter = getUnhandledExceptionQueuedEvents().iterator(); iter.hasNext();) {
            Throwable exception = iter.next().getContext().getException();

            if (exception instanceof ViewExpiredException) {
                facesContext.getApplication().getNavigationHandler().handleNavigation(facesContext, null, "viewexpired");
                facesContext.renderResponse();
                iter.remove();
            }
        }

        getWrapped().handle();
    }

    @Override
    public ExceptionHandler getWrapped() {
        return wrapped;
    }

}

(请注意,此特定示例导航到 viewexpired< /code>,所以它期望a /viewexpired.xhtml 作为错误页面)

以上需要通过以下 ExceptionHandlerFactory 实现:

public class ViewExpiredExceptionHandlerFactory extends ExceptionHandlerFactory {

    private ExceptionHandlerFactory parent;

    public ViewExpiredExceptionHandlerFactory(ExceptionHandlerFactory parent) {
        this.parent = parent;
    }

    @Override
    public ExceptionHandler getExceptionHandler() {
        return new ViewExpiredExceptionHandler(parent.getExceptionHandler());
    }

}

依次需要在 faces-config.xml 作为如下:

<factory>
    <exception-handler-factory>com.example.ViewExpiredExceptionHandlerFactory</exception-handler-factory>
</factory>

If someone writes a URL and tries to jump the login page, how can I check that and redirect him to the login page?

You seem to using homegrown authentication. In that case, you need to implement a servlet filter. JSF stores session scoped managed beans as attributes of HttpSession, so you could just check on that in doFilter() method:

HttpServletRequest req = (HttpServletRequest) request;
UserManager userManager = (UserManager) req.getSession().getAttribute("userManager");

if (userManager != null && userManager.isLoggedIn()) {
    chain.doFilter(request, response);
} else {
    HttpServletResponse res = (HttpServletResponse) response;
    res.sendRedirect(req.getContextPath() + "/login.xhtml");
}

Map this filter on an URL pattern covering the secured pages, e.g. /app/*.


When I return and try to interact with the form it sends a message alerting me the session expiration. How can I redirect again to the login form when this occurs?

I understand that this concerns Ajax requests? For normal requests you could have used an <error-page> in web.xml. If setting the state saving method to client in web.xml as follows

<context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
</context-param>

is not an option, then you need to implement a custom ExceptionHandler:

public class ViewExpiredExceptionHandler extends ExceptionHandlerWrapper {

    private ExceptionHandler wrapped;

    public ViewExpiredExceptionHandler(ExceptionHandler wrapped) {
        this.wrapped = wrapped;
    }

    @Override
    public void handle() throws FacesException {
        FacesContext facesContext = FacesContext.getCurrentInstance();

        for (Iterator<ExceptionQueuedEvent> iter = getUnhandledExceptionQueuedEvents().iterator(); iter.hasNext();) {
            Throwable exception = iter.next().getContext().getException();

            if (exception instanceof ViewExpiredException) {
                facesContext.getApplication().getNavigationHandler().handleNavigation(facesContext, null, "viewexpired");
                facesContext.renderResponse();
                iter.remove();
            }
        }

        getWrapped().handle();
    }

    @Override
    public ExceptionHandler getWrapped() {
        return wrapped;
    }

}

(note that this particular example navigates to viewexpired, so it expects a /viewexpired.xhtml as error page)

The above needs to be baked by the following ExceptionHandlerFactory implementation:

public class ViewExpiredExceptionHandlerFactory extends ExceptionHandlerFactory {

    private ExceptionHandlerFactory parent;

    public ViewExpiredExceptionHandlerFactory(ExceptionHandlerFactory parent) {
        this.parent = parent;
    }

    @Override
    public ExceptionHandler getExceptionHandler() {
        return new ViewExpiredExceptionHandler(parent.getExceptionHandler());
    }

}

which in turn needs to be registered in faces-config.xml as follows:

<factory>
    <exception-handler-factory>com.example.ViewExpiredExceptionHandlerFactory</exception-handler-factory>
</factory>
孤檠 2024-12-22 22:41:10

如果您正在实现自己的系统,您可以向用户添加一个名为 session 的属性或其他属性。此属性可以是布尔值,因此每当会话启动时,您都可以将此属性设置为 true。编写一个名为 permission 的方法,例如:

public void permission() throws IOException {

        if(userStatelessBean.getSession() == false) {
            System.out.println("*** The user has no permission to visit this page. *** ");
            ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
            context.redirect("login.xhtml");
        } else {
            System.out.println("*** The session is still active. User is logged in. *** ");
        }
    }

在您想要对其进行限制的每个 jsf 页面(本例)上,您可以在最开始添加以下代码页面开头:

<f:metadata>
     <f:event type="preRenderView" listener="#{sesija.permission()}"/>
</f:metadata>

这将在呈现页面之前调用对象名称为 sesija 的 JSF ManagedBean,并检查您在指定方法中创建的规则是否满足。

我希望你觉得这很有用,

谢谢。

If you are implementing your own system you can add an attribute to user called session or whatever. This attribute can be boolean so whenever the session starts you can set this attribute to true. Write a method called permission for example:

public void permission() throws IOException {

        if(userStatelessBean.getSession() == false) {
            System.out.println("*** The user has no permission to visit this page. *** ");
            ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
            context.redirect("login.xhtml");
        } else {
            System.out.println("*** The session is still active. User is logged in. *** ");
        }
    }

On each of your jsf page (for this example) that you want to have restrictions on, you can add the following code at the very beginning of your page:

<f:metadata>
     <f:event type="preRenderView" listener="#{sesija.permission()}"/>
</f:metadata>

What this is going to do is call the JSF ManagedBean with object name sesija before rendering the page and check whether the rulles you've created in specified method are satisfied or not.

I hope you find this useful,

Thank you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文