我剛開始學習Java EE。我的目標是爲羽毛球運動員實施一個門戶網站(使用EJB 3和JSF),用戶可以在其中發佈和分析他們的結果。Java EE安全性 - 登錄後未重定向到初始頁面
爲了保持簡單(事實證明它確實沒有)我決定使用容器提供的安全系統(JBoss as7)。在遇到一些問題後,我設法使認證/授權起作用。但是,我有一個我無法解決的問題。
當我試圖訪問受保護的頁面時,我收到了安全系統攔截的預期結果。但是,在我登錄後,我不會重定向到最初請求的頁面。相反,我再次被要求登錄。 如果我手動鍵入原始地址,我可以毫無困難地訪問該頁面。
我已經閱讀了stackoverflow上的很多線程,但一直未能解決我的問題。如果有人能幫助我,我會很感激!
Authentication.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";
}
}
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>
home.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";
}
}
您正在使用哪個安全域(在WEB-INF/jboss-web.xml中定義)?它看起來像你不依賴於100%的JBoss認證模型。登錄模塊應該遵循以下模型:https://community.jboss.org/wiki/SecureAWebApplicationUsingACustomForm。如果你遵循這個模型,你不需要實現任何認證bean。 – Toni
我添加了faces-config和jboss-web文件。現在我已經儘可能簡單地保持它們。我實現身份驗證bean的原因是,我可以使用標記(從而能夠使用primefaces)。 –
Toss
這很有趣,那麼你並沒有真正使用安全域,對吧? – Toni