我刚开始学习 Java EE。我的目标是为羽毛球运动员实现一个门户网站(使用 EJB 3 和 JSF),用户可以在其中发布和分析他们的结果。
为了简单起见(事实证明并非如此),我决定使用容器提供的安全系统(JBoss as7)。在出现一些问题后,我设法让身份验证/授权正常工作。但是,我有一个问题我无法解决。
当我尝试访问受保护的页面时,如预期的那样,我被安全系统拦截了。但是,在我登录后,我并没有重定向到我最初请求的页面。相反,我再次被要求登录。如果我手动输入原始地址,我可以毫无问题地访问该页面。
我在stackoverflow上阅读了很多线程,但无法解决我的问题。如果有人可以帮助我,我将不胜感激!
身份验证.java:
@ManagedBean
@SessionScoped
public class Authentication {
private String username = "";
private String password = "";
private User user = new User();
@EJB
UserService service;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public User getUser() {
return user;
}
public void login() {
FacesContext context = FacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest) context
.getExternalContext().getRequest();
try {
Principal userPrincipal = request.getUserPrincipal();
if (userPrincipal != null) {
request.logout();
}
request.login(username, password);
user = service.find(username, password);
} catch (ServletException e) {
context.addMessage(null, new FacesMessage("Unknown login"));
}
}
public String logout() {
FacesContext.getCurrentInstance().getExternalContext()
.invalidateSession();
return "login";
}
}
登录.xhtml
<h:body>
<h:form>
<h:outputLabel for="username" value="Username" />
<h:inputText id="username" value="#{authentication.username}" required="true" />
<h:message for="username" />
<br />
<h:outputLabel for="password" value="Password" />
<h:inputSecret id="password" value="#{authentication.password}" required="true" />
<h:message for="password" />
<br />
<h:commandButton value="Login" action="#{authentication.login()}" />
<h:messages globalOnly="true" />
</h:form>
</h:body>
主页.xhtml
<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml'
xmlns:f='http://java.sun.com/jsf/core'
xmlns:h='http://java.sun.com/jsf/html'
xmlns:ui='http://java.sun.com/jsf/facelets'
xmlns:p="http://primefaces.org/ui">
<h:head>
<link type="text/css" rel="stylesheet"
href="#{request.contextPath}/themes/cupertino/skin.css" />
</h:head>
<h:body>
<h:form>
<h:commandButton action="login" value="Log in" />
</h:form>
</h:body>
web.xml
....
<display-name>BadmintonPortal</display-name>
<welcome-file-list>
<welcome-file>/pages/protected/user/user_home.xhtml</welcome-file>
</welcome-file-list>
<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>/faces/*</url-pattern>
<url-pattern>*.jsf</url-pattern>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<context-param>
<param-name>primefaces.THEME</param-name>
<param-value>cupertino</param-value>
</context-param>
<!-- Protected area definition -->
<security-constraint>
<web-resource-collection>
<web-resource-name>Restricted Area - ADMIN Only</web-resource-name>
<url-pattern>/pages/protected/admin/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>Restricted Area - USER and ADMIN</web-resource-name>
<url-pattern>/pages/protected/user/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>user</role-name>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<!-- Login page -->
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/pages/public/login.xhtml</form-login-page>
<form-error-page>/pages/public/loginError.xhtml</form-error-page>
</form-login-config>
</login-config>
<!-- System roles -->
<security-role>
<role-name>admin</role-name>
</security-role>
<security-role>
<role-name>user</role-name>
</security-role>
编辑:
忘记包含faces-config.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_1.xsd"
version="2.1">
<navigation-rule>
<navigation-case>
<from-outcome>login</from-outcome>
<to-view-id>/pages/protected/user/user_home.xhtml</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
</faces-config>
jboss-web.xml
<?xml version='1.0' encoding='UTF-8'?>
<jboss-web>
<context-root>BadmintonPortal</context-root>
<security-domain>java:/jaas/BadmintonPortalRealm</security-domain>
</jboss-web>
编辑2:
工作解决方案
@ManagedBean
@ViewScoped
public class Authentication {
...
public Authentication() {
ExternalContext eContext = FacesContext.getCurrentInstance()
.getExternalContext();
uri = (String) eContext.getRequestMap().get(
RequestDispatcher.FORWARD_REQUEST_URI);
}
public void login() {
FacesContext context = FacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest) context
.getExternalContext().getRequest();
try {
Principal userPrincipal = request.getUserPrincipal();
if (userPrincipal != null) {
request.logout();
}
request.login(username, password);
user = service.find(username, password);
context.getExternalContext().getSessionMap().put("user", user);
context.getExternalContext().redirect(uri);
} catch (ServletException e) {
context.addMessage(null, new FacesMessage("Unknown login"));
} catch (IOException e) {
e.printStackTrace();
}
}
public String logout() {
FacesContext.getCurrentInstance().getExternalContext()
.invalidateSession();
return "login";
}
}