Seam 3如何处理“重定向以捕获视图".登录后功能? [英] How does Seam 3 handles the "redirect to capture view" feature after login?

查看:94
本文介绍了Seam 3如何处理“重定向以捕获视图".登录后功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的用例.

我有一个登录页面,该页面是/public/login.xhtml.我的所有其他页面都需要先登录才能进入.它们在/pages/目录中.

I have a login page which is /public/login.xhtml. All my other pages are required to log-in before reaching them. They are in /pages/ directory.

我想要那个:

  1. 如果我的用户访问http://host/myapp/pages/*,它将首先将他重定向到登录页面,然后将其重定向到他首先输入的URL.
  2. 如果我的用户访问http://host/myapp/,它将首先将他重定向到登录页面,然后将其重定向到/pages/home.xhtml.
  3. 如果我的用户访问http://host/myapp/public/login.xhtml,它将首先将他重定向到登录页面,然后将其重定向到/pages/home.xhtml.
  4. 如果我的用户访问了http://host/myapp/public/login.xhtml并且已经登录,它将重定向到/pages/home.xhtml.
  1. If my user access to http://host/myapp/pages/* it redirects him first to the login page, and then, to the URL he has firstly entered.
  2. If my user access to http://host/myapp/, it redirects him first to the login page, and then, to /pages/home.xhtml.
  3. If my user access to http://host/myapp/public/login.xhtml, it redirects him first to the login page, and then, to /pages/home.xhtml.
  4. If my user access to http://host/myapp/public/login.xhtml and is already logged in, it redirects to /pages/home.xhtml.


当前正在做什么?

在使用Seam 3(v3.1.0.Final)和Security + Faces模块的情况下,我的用例 n°1可自动使用:

With Seam 3 (v3.1.0.Final) and the Security + Faces module, my use case n°1 is automagically working with :

@ViewConfig
public interface PagesConfig {
    static enum Pages {
        @ViewPattern("/pages/*")
        @LoginView("/public/login.xhtml")
        @LoggedIn
        LOGGED_IN_PAGES,
    }
}

我的问题是我不知道Seam如何将重定向重定向到捕获视图".

My problem is that I don't understand how Seam's working to do that redirection to the "capture view".

使用Seam 2,很容易理解,在components.xml中,我们拥有

With Seam 2, it was easy to understand, in components.xml we had

<event type="org.jboss.seam.security.notLoggedIn">
    <action execute="#{redirect.captureCurrentView}" />
</event>
<event type="org.jboss.seam.security.loginSuccessful">
    <action execute="#{redirect.returnToCapturedView}" />
</event>

因此,我们捕获了事件notLoggedInloginSuccessful,以使用redirect组件进行处理.

So we captured the events notLoggedIn and loginSuccessful to handle that with a redirect component.

在Seam 3中,我没有发现该配置:@Observes LoggedInEvent似乎没有任何内容,并且没有Redirect类...

In Seam 3, I didn't found that configuration : nothing seems to @Observes LoggedInEvent, and there is no Redirect class...

通过该/index.htm文件获得 n°2点:

<html><head>
    <meta http-equiv="Refresh" content="0; URL=pages/home.xhtml">
</head></html>

但是对于我的第3点,我尝试了无法完全解决问题的解决方案.

But for my point n°3, I've tried solutions which don't fully work.

首先我在login.xhtml中尝试过:

<f:metadata>
    <s:viewAction action="#{loginAction.redirectToHome}" if="#{identity.loggedIn}" immediate="true" />
</f:metadata>

无论是否使用onPostback="true",登录后,我仍然在登录页面中看到该错误消息(两次):"无法找到带有from-view-id«/public的匹配导航案例/login.xhtml»进行操作#{identity.login}",结果为成功".".只有当我现在重新访问http://host/myapp/public/login.xhtml时,我的viewAction才会将我重定向到家中.

And with or without onPostback="true", after I login, I'm still in the login page with that error message (twice) : "Unable to find matching navigation case with from-view-id «/public/login.xhtml» for action «#{identity.login}» with outcome «success».". It's only if I now re-access to http://host/myapp/public/login.xhtml that my viewAction redirects me to the home.

我还尝试了faces-config.xml中的导航规则:

I also tried that navigation-rule in faces-config.xml :

<navigation-rule>
    <from-view-id>/public/login.xhtml</from-view-id>

    <navigation-case>
        <if>#{identity.loggedIn}</if>
        <to-view-id>/pages/home.xhtml</to-view-id>
        <redirect />
    </navigation-case>
</navigation-rule>

但是随后,我的用例n°1被禁用:每次登录时,我都被重定向到家中.

But then, my use case n°1 was disabled : every time I logged-in, I was redirected to the home.

最后,对于我的 n°4点s:viewAction完成了任务.

Finally, for my point n°4, the s:viewAction does the job.

那么有人会知道正确处理这4个用例(我认为是常见用例)的最佳实践吗,特别是第3点?

So does somebody knows the best practices in order to correctly handle those 4 use cases (which I think are common use cases), especially the point n°3?

推荐答案

最后,这就是我所做的.

Finally here is what I did.

<f:metadata>
    <s:viewAction action="#{loginAction.redirectToHome}" immediate="true" />
</f:metadata>

所以我删除了if="#{identity.loggedIn}"以便调用我的redirectToHome方法,该方法重定向到 /pages/home.xhtml.

So I removed the if="#{identity.loggedIn}" in order to call my redirectToHome method which redirects to the /pages/home.xhtml.

  • 如果用户已经通过身份验证,则将其重定向到主页.
  • 如果不是,则将其重定向到主页,这要感谢我的@ViewConfig

这是loginAction:

public void redirectToHome() throws IOException {
    externalContext.redirect(externalContext.encodeActionURL(externalContext.getRequestContextPath()+"/pages/home.xhtml"));
}

当时我遇到的问题是我注销时.

这是我的注销操作:

<h:commandLink  action="/public/login" actionListener="#{securityAction.logout()}" value="Disconnect" immediate="true" />

securityAction.logout()方法:

public void logout() {
    identity.logout();
    if (!conversation.isTransient()) {
        conversation.end();
    }
}

问题是我被重定向到登录页面(由于我认为是@ViewConfig),但没有抛出PreLoginEvent ,所以没有调用Seam LoginListener.observePreLoginEvent,因此我的上一个URL没有加入会话中.因此,当我登录(立即注销后)时,我停留在登录页面上,但是登录了.

The problem is that I was redirected to the login page (thanks to the @ViewConfig I think), but no PreLoginEvent were thrown, so the Seam LoginListener.observePreLoginEvent wasn't called, and so my previous URL wasn't put in session. So when I logged in (immediatly after logout), I was stuck on the login page, but was logged in.

感谢 Brian Leathem

Thanks to Brian Leathem and he's previous answer, here is what I did : in my authenticate method of my BaseAuthenticator, I called that method after authentication :

private void overrideRedirectToLogin() {
    final String PRE_LOGIN_URL = LoginListener.class.getName() + "_PRE_LOGIN_URL";
    final ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
    final Map<String, Object> sessionMap = externalContext.getSessionMap();
    String redirectURL = (String) sessionMap.get(PRE_LOGIN_URL);

    if (redirectURL == null) {
        final HttpServletRequest request = (HttpServletRequest) externalContext.getRequest();
        redirectURL = request.getRequestURL().toString();
    }

    sessionMap.put(PRE_LOGIN_URL, redirectURL.replace("/public/login.xhtml", "/pages/home.xhtml"));
}

使用该解决方案,我没有在会话中设置以前的URL,但是至少,我的用户被重定向到了主页.

With that solution, my previous URL wasn't set in session, but at least, my user is redirected to the home page.

这篇关于Seam 3如何处理“重定向以捕获视图".登录后功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆