Seam 3如何处理“重定向以捕获视图".登录后功能? [英] How does Seam 3 handles the "redirect to capture view" feature after login?
问题描述
这是我的用例.
我有一个登录页面,该页面是/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.
我想要那个:
- 如果我的用户访问
http://host/myapp/pages/*
,它将首先将他重定向到登录页面,然后将其重定向到他首先输入的URL. - 如果我的用户访问
http://host/myapp/
,它将首先将他重定向到登录页面,然后将其重定向到/pages/home.xhtml
. - 如果我的用户访问
http://host/myapp/public/login.xhtml
,它将首先将他重定向到登录页面,然后将其重定向到/pages/home.xhtml
. - 如果我的用户访问了
http://host/myapp/public/login.xhtml
并且已经登录,它将重定向到/pages/home.xhtml
.
- 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. - If my user access to
http://host/myapp/
, it redirects him first to the login page, and then, to/pages/home.xhtml
. - 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
. - 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>
因此,我们捕获了事件notLoggedIn
和loginSuccessful
,以使用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屋!