目标:希望在对用户进行身份验证时在会话中检索和存储用户相关信息(USER 表中超过 5 列),以便我可以在当前会话期间的不同时间点使用用户信息。
方法:我选择在我的JavaServerFaces应用程序中使用托管Bean(LoginBean.java
)进行身份验证。 我将检索用户信息并将它们存储在LoginBean.login()
方法的会话中。
参考: http://docs.oracle.com/javaee/6/tutorial/doc/glxce.html#glxef
豆代码:
@ManagedBean
@SessionScoped
public class LoginBean {
private String id;
private String password;
public LoginBean() {
System.out.println("LoginBean() called .....");
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String login() {
System.out.println("login() invoked .....");
FacesContext facesContext = FacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest)facesContext.getExternalContext().getRequest();
try {
request.login(id, password);
} catch (ServletException e) {
facesContext.addMessage(null, new FacesMessage("Login failed."));
return "error";
}
return "home";
}
public void logout() {
System.out.println("logout() invoked .....");
FacesContext facesContext = FacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest)facesContext.getExternalContext().getRequest();
try {
request.logout();
} catch (ServletException e) {
facesContext.addMessage(null, new FacesMessage("Logout failed."));
}
}
}
网络.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name>AuthenticationUsingLoginBean</display-name>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>jdbcRealm</realm-name>
<form-login-config>
<form-login-page>/login.xhtml</form-login-page>
<form-error-page>/error.xhtml</form-error-page>
</form-login-config>
</login-config>
<security-constraint>
<web-resource-collection>
<web-resource-name>All resources are restricted</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
</web-app>
登录.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>Form based authentication with login bean</title>
</h:head>
<h:body>
<h:form>
<h:outputLabel for="usernameInput">User ID:</h:outputLabel>
<h:inputText id="usernameInput" value="#{loginBean.id}" required="true" />
<h:message for="usernameInput"/>
<br />
<h:outputLabel for="passwordInput">Password:</h:outputLabel>
<h:inputSecret id="passwordInput" value="#{loginBean.password}" required="true" />
<h:message for="passwordInput" />
<br />
<h:commandButton value="Login" action="#{loginBean.login}" />
</h:form>
</h:body>
</html>
问题我已经启动了新的浏览器窗口并访问了主页(home.xhml
)。我被重定向到login.xhtml
,这很好。但是,在单击 UI 上的Login
按钮时login.xhtml
,LoginBean.login()
方法不会被调用。
注意 login.xhtml
应该是正确的,因为当我注释掉文件中LoginBean.login()
<login-config>
时web.xml
该方法被成功调用。 显然,我无法对其进行注释,因为身份验证无法按预期工作。
更新我在 tomcat 的 server.xml
文件中配置了必要的JDBCRealm
,并通过使用 j_security_check
实现基于表单的示例身份验证来确保它正常工作。
<Realm className="org.apache.catalina.realm.JDBCRealm"
driverName="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost/xyz"
connectionName="root"
connectionPassword="xxxxx"
userTable="USER" userCredCol="PASSWORD"
userRoleTable="USER_ROLE_MPNG" userNameCol="ID" roleNameCol="ROLE_NAME" />
使用的软件:阿帕奇-雄猫-7.0.47JSF 2.1 (Mojarra 2.1.6)
<h:commandButton value="Login" action="#{loginBean.login()}" />
注意登录后的()
。 您正在调用一个方法,而不是尝试在 LoginBean 中使用名为 login 的 var 获取/设置。
这不起作用的原因是因为您限制了web.xml
中的所有资源。您可以看到您的登录和错误页面,但这并不意味着它周围的一切都可以访问,相反。
溶液
为公共资源添加新的安全约束,如下所示:
<security-constraint>
<web-resource-collection>
<web-resource-name>Open Resources</web-resource-name>
<url-pattern>/public/*</url-pattern>
</web-resource-collection>
</security-constraint>
现在,创建一个新的子文件夹,其中login.xhtml
和error.xhtml
,并将其称为 public
,如安全约束中所述。将login.xhtml
和error.xhtml
移动到新创建的文件夹中,并相应地调整web.xml
中的登录配置。