请求中带有凭据的JSF登录
我正在用JSF2.0开发一个web应用程序。我通过托管bean(LoginHandler)实现了登录,并检查用户是否使用过滤器登录 现在,我通过发送一个以用户名和密码为参数的请求,得到了能够登录到应用程序的请求。哪种方法最好 我试着使用f:metadata和preRenderView事件,但是过滤器似乎是更好的解决方案?我还尝试在登录页面的url上编写HTTPFilter,但问题是我需要将用户数据存储在托管bean中,并且当我第一次访问应用程序时,我没有一个会话可以从中获取托管bean Otpion 1:f:managedbean LoginHandler中的元数据和操作: 在登录页面上:请求中带有凭据的JSF登录,jsf,login,jsf-2,servlet-filters,Jsf,Login,Jsf 2,Servlet Filters,我正在用JSF2.0开发一个web应用程序。我通过托管bean(LoginHandler)实现了登录,并检查用户是否使用过滤器登录 现在,我通过发送一个以用户名和密码为参数的请求,得到了能够登录到应用程序的请求。哪种方法最好 我试着使用f:metadata和preRenderView事件,但是过滤器似乎是更好的解决方案?我还尝试在登录页面的url上编写HTTPFilter,但问题是我需要将用户数据存储在托管bean中,并且当我第一次访问应用程序时,我没有一个会话可以从中获取托管bean Otpi
<f:metadata>
<f:viewParam name="username" value="#{loginManager.username}"/>
<f:viewParam name="password" value="#{loginManager.password}"/>
<f:event type="preRenderView" listener="#{loginManager.singleSignOn}"/>
</f:metadata>
如前所述,选项2的问题是,在我第一次访问应用程序时,会话没有设置(即,我需要尝试登录两次,第二次一切正常)
谢谢
EDIT1:更新了注释和说明,以更好地反映类LoginHandler的角色
f:viewParam
处理用户输入servlet
与JSF
应用程序一起使用
会话范围bean是HTTPSessions
的属性,您将发现
关于原因的解释f:event
标记
通过使用
@ListnerFor(systemEventClass=typeOfEvent.class)
,通过调用
subscribeToEvent
方法,最后注册一个系统事件
faces config.xml
文件中的listner
<application>
<system-event-listener>
<system-event-listener-class>listenerClass</system-event-listener-class>
<system-event-class>eventClass</system-event-class>
</system-event-listener>
</application>
您的bean方法接受组件系统事件
public void singleSignOn(ComponentSystemEvent event) {
if (!login) {
//do JSF stuff here when validating credentials fails or passes
//eg. perform navigation
}
}
注意:这个问题有一个答案,它解决了如何用jsf实现过滤器
对于其他材料,我建议您继续
f:viewParam
处理用户输入servlet
与JSF
应用程序一起使用
会话范围bean是HTTPSessions
的属性,您将发现
关于原因的解释f:event
标记
通过使用
@ListnerFor(systemEventClass=typeOfEvent.class)
,通过调用
subscribeToEvent
方法,最后注册一个系统事件
faces config.xml
文件中的listner
<application>
<system-event-listener>
<system-event-listener-class>listenerClass</system-event-listener-class>
<system-event-class>eventClass</system-event-class>
</system-event-listener>
</application>
您的bean方法接受组件系统事件
public void singleSignOn(ComponentSystemEvent event) {
if (!login) {
//do JSF stuff here when validating credentials fails or passes
//eg. perform navigation
}
}
注意:这个问题有一个答案,它解决了如何用jsf实现过滤器
对于其他材料,我建议您继续。我参加了
预渲染视图
活动:
singleSignOn.xhtml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<f:metadata>
<f:viewParam name="userName" value="#{loginCredentials.userName}" />
<f:viewParam name="password" value="#{loginCredentials.password}" />
<f:event type="preRenderView" listener="#{loginHandler.singleSignOn}" />
</f:metadata>
<h:head>
<title>singleSignOn</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</h:head>
<h:body />
</html>
LoginCredentials和LoginHandler.login是绑定到登录页面上的
h:form
的相同bean/方法我使用了prerenderview
事件:
singleSignOn.xhtml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<f:metadata>
<f:viewParam name="userName" value="#{loginCredentials.userName}" />
<f:viewParam name="password" value="#{loginCredentials.password}" />
<f:event type="preRenderView" listener="#{loginHandler.singleSignOn}" />
</f:metadata>
<h:head>
<title>singleSignOn</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</h:head>
<h:body />
</html>
LoginCredentials和LoginHandler.login是绑定到登录页面上的
h:form
的同一bean/方法,选项2确实更常见。解决方案:不要检查loginHandler(className表示“服务”,服务无论如何不应该存储在会话中)。但更好的解决办法是不要创造本土产品。如果您对此已经有疑问,您肯定会(无意中)引入安全漏洞。最好使用一些现有的框架,如PicketLink、Shiro甚至SpringSecurity(如果您已经使用spring)。@Kukeltje感谢您的回答。我会坚持我目前的框架,但会考虑在第二个时刻升级为Spring。我的类LoginHandler是JSF应用程序中的一个sessionscoped bean,它从登录EJB调用逻辑,并保存有关当前登录用户的信息。这是我的第一个jsf/EJB应用程序,我还不熟悉最佳实践。我需要在过滤器中使用LoginHandler,以便让用户登录到应用程序中,有办法吗?编辑:更新了问题,明确了我使用LoginHandler的目的是为了将服务和保存状态的bean结合在一起?这不是一个好的设计。将它们拆分为一个LoginService(请求范围或甚至静态方法或..)和一个LoggedInUser(会话范围)。选择2确实更常见。解决方案:不要检查loginHandler(className表示“服务”,服务无论如何不应该存储在会话中)。但更好的解决办法是不要创造本土产品。如果您对此已经有疑问,您肯定会(无意中)引入安全漏洞。最好使用一些现有的框架,如PicketLink、Shiro甚至SpringSecurity(如果您已经使用spring)。@Kukeltje感谢您的回答。我会坚持我目前的框架,但会考虑在第二个时刻升级为Spring。我的类LoginHandler是JSF应用程序中的一个sessionscoped bean,它从登录EJB调用逻辑,并保存有关当前登录用户的信息。这是我的第一个jsf/EJB应用程序,我还不熟悉最佳实践。我需要在过滤器中使用LoginHandler,以便让用户登录到应用程序中,有办法吗?编辑:更新了问题,明确了我使用LoginHandler的目的是为了将服务和保存状态的bean结合在一起?这不是一个好的设计。