2012-06-07 5 views
4

Я пытался создать безопасную страницу входа с помощью jsf, и я использовал эти фрагменты кода как решение, найденное в this question. Моя проблема заключается в том, что я могу получить доступ к /restricted/secret.xhtml без входа в систему, нет перенаправления, так как фильтр не применяется, потому что если я перейду непосредственно к /restricted/secret.xhtml, то # {user.loggedIn } оценивает значение false, и я все еще могу просмотреть страницу. Вот мой код:jsf фильтр кажется не работает

AuthFilter.java

public class AuthFilter implements Filter { 

private FilterConfig config; 

@Override 
public void destroy() { 
    this.config = null; 
} 

@Override 
public void doFilter(ServletRequest req, ServletResponse resp, 
     FilterChain ch) throws IOException, ServletException { 

    HttpSession s = ((HttpServletRequest) req).getSession(); 
    if (s.getAttribute(UserBean.CREDENTIAL)==null) 
    { 
     ((HttpServletResponse) resp).sendRedirect("/login.faces"); 
    }else 
    { 
     ch.doFilter(req, resp); 
    } 
} 
@Override 
public void init(FilterConfig config) throws ServletException { 
    this.config = config; 
} 
} 

UserBean.java

@ManagedBean(name="user") 
@SessionScoped 
public class UserBean implements Serializable { 

private String name; 
private String password; 
protected static final String CREDENTIAL = "ontherun"; 

private static final long serialVersionUID = 1L; 

public String getName() 
{ 
    return this.name; 
} 

public void setName(String newName) 
{ 
    this.name = newName; 
} 

public String getPassword() 
{ 
    return this.password; 
} 

public void setPassword(String newPassword) 
{ 
    this.password = newPassword; 
} 

public boolean isLoggedIn() 
{ 
    return FacesContext.getCurrentInstance().getExternalContext() 
      .getSessionMap().get(CREDENTIAL) != null; 
} 

public String logout() { 
    FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(CREDENTIAL); 
    return null; 
} 


public String login() 
{ 
    FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(CREDENTIAL, this.name); 
    return "secret"; 
} 
} 

Вот мой login.xhtml; страница работает правильно, поэтому нет проблем с файлом шаблона.

<!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:ui="http://java.sun.com/jsf/facelets" 
    xmlns:h="http://java.sun.com/jsf/html"> 
<head><title>IGNORED</title></head> 

<body> 
<ui:composition template="/templates/masterLayoutTemplate.xhtml"> 
<ui:define name="windowTitle"> 
      #{msgs.window_title} 
</ui:define> 

<ui:define name="header"> 
    <ui:include src="/sections/login/header.xhtml"></ui:include> 
</ui:define> 

<ui:define name="footer"> 
    <ui:include src="/sections/login/footer.xhtml"></ui:include> 
</ui:define> 

<ui:define name="content"> 
     <h:form> 
      <h:panelGrid columns="2"> 
       #{msgs.namePrompt} 
      <h:inputText id="name" value="#{user.name}"/> 
       #{msgs.passwordPrompt} 
      <h:inputSecret id="password" value="#{user.password}"/> 
      </h:panelGrid> 
      <p> 
      <h:commandButton value="#{msgs.loginButtonText}" action="#{user.login }"/> 
      </p> 
      <p> 
       You are logged in : #{user.loggedIn} 
      </p> 
      <p> 
      <h:commandButton value="logout" action="#{user.logout }"/> 
      </p> 
     </h:form> 
</ui:define> 
</ui:composition> 
</body> 
</html> 

Вот secret.xhtml, который должен быть ограничен:

<!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:ui="http://java.sun.com/jsf/facelets" 
    xmlns:h="http://java.sun.com/jsf/html"> 
<head><title>IGNORED</title></head> 

<body> 
<ui:composition template="/templates/masterLayoutTemplate.xhtml"> 
<ui:define name="windowTitle"> 
    #{msgs.window_title} 
</ui:define> 


<ui:define name="content"> 
     <h:head></h:head> 
     <h:body> 
      <p>You are #{user.loggedIn}</p> 
     </h:body> 


</ui:define> 
</ui:composition> 
</body> 
</html> 

А вот мои файлы конфигурации: web.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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 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>OnTheRun</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>/faces/*</url-pattern> 
</servlet-mapping> 

<welcome-file-list> 
    <welcome-file>faces/index.xhtml</welcome-file> 
</welcome-file-list> 

<filter> 
     <filter-name>AuthFilter</filter-name> 
     <filter-class>on.run.AuthFilter</filter-class> 
</filter> 
<filter-mapping> 
     <filter-name>AuthFilter</filter-name> 
     <url-pattern>/restricted/*</url-pattern> 
</filter-mapping> 

<context-param> 
    <param-name>javax.faces.PROJECT_STAGE</param-name> 
    <param-value>Development</param-value> 
</context-param> 

</web-app> 

и лица-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_0.xsd" 
version="2.0"> 
<application> 
    <resource-bundle> 
     <base-name>on.run.messages</base-name> 
     <var>msgs</var> 
    </resource-bundle> 
</application> 



<navigation-rule> 
     <from-view-id>/index.xhtml</from-view-id> 
    <navigation-case> 
     <from-outcome>login</from-outcome> 
     <to-view-id>/profile.xhtml</to-view-id> 
     <redirect/> 
    </navigation-case> 
</navigation-rule> 

<navigation-rule> 
     <from-view-id>/login.xhtml</from-view-id> 
    <navigation-case> 
     <from-outcome>secret</from-outcome> 
     <to-view-id>/restricted/secret.xhtml</to-view-id> 
     <redirect/> 
    </navigation-case> 
</navigation-rule> 
</faces-config> 

My directory structure loo кс, как это: dirStruct2

ответ

4

Вы сопоставляются FacesServlet на /faces/* вместо *.xhtml. Таким образом, все запросы JSF будут иметь префикс /faces в URL-адресе. Но вы набрали AuthFilter на /restricted/* вместо /faces/restricted/*, поэтому он никогда не будет нажимать на /faces/* URL.

Вы можете решить эту проблему в 2 способами:

  1. Карта FacesServlet на *.xhtml, а не на /faces/*. Это имеет дополнительное преимущество, что конечный пользователь никогда не сможет увидеть исходный исходный код JSF, когда конечный пользователь целенаправленно удаляет путь /faces из URL-адреса в адресной строке браузера.

  2. AuthFilter/faces/restricted/* вместо /restricted/*.

Я лично рекомендую первый способ. В итоге вы получаете более короткий и более удобный URL-адрес, и вы сразу же предотвращаете утечку исходного кода JSF.

+0

Благодарим вас за помощь. Мне также пришлось изменить в фильтре путь перенаправления на «../login.xhtml». Есть ли более элегантный способ сделать это> Я имею в виду, как я могу установить свой путь для загрузки каталога проектов? В моем случае, если я просто напишу login.xhtml или /login.xhtml, он перенаправляет на localhost/login.xhtml, а не на localhost/ProjectName/login.xhtml. – Pio

+0

Используйте 'String loginURL = request.getContextPath() +" /login.xhtml ";'. – BalusC

+0

Спасибо, это работает как шарм. – Pio

Смежные вопросы