未登录时可以看到安全页面

Can see secured page while not logged in

我用Tomcat 7. 我的问题是未登录的用户不应该看到特定页面(home.xhtml 在我的例子中),但应该被重定向到登录页面。 行为是: 1、如果应用刚刚启动,没有人尝试登录,可以直接访问受限页面。 2. 如果有人登录和注销,然后试图访问提到的 home.xhtml,浏览器显示错误页面(同时它应该重定向到登录页面):

An Error Occurred:

viewId:/home.xhtml - View /home.xhtml could not be restored.
- Stack Trace

javax.faces.application.ViewExpiredException: viewId:/home.xhtml - View /home.xhtml could not be restored.
    at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:205)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:116)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
+ Component Tree

+ Scoped Variables

Jan 22, 2015 8:57:04 PM - Generated by Mojarra/Facelets

我的脸-config.xml:

<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.0"
    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">
    <navigation-rule>
        <from-view-id>/login.xhtml</from-view-id>
        <navigation-case>
            <from-outcome>home</from-outcome>
            <to-view-id>/home.xhtml</to-view-id>
        <redirect>     
        </redirect>
        </navigation-case>
 </navigation-rule>
</faces-config>

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 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-app_3_0.xsd">
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
    <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>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>login.xhtml</welcome-file>
    </welcome-file-list>
 </web-app>

过滤器:

public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) {

            HttpServletRequest req = (HttpServletRequest) request;
            HttpServletResponse res = (HttpServletResponse) response;
            HttpSession session = req.getSession();
            String reqURI = req.getRequestURI();
            if (reqURI.indexOf("/login.xhtml") >= 0
                    || (session != null && session.getAttribute("username") != null)
                    || reqURI.indexOf("/public/") >= 0
                    || reqURI.contains("javax.faces.resource"))
                try {
                    chain.doFilter(request, response);
                } catch (IOException e) {
                    System.out.println("IO exc after doFilter");
                } catch (ServletException e) {
                    System.out.println("Servlet exc after doFilter");
                }
            else
                try {
                    res.sendRedirect(req.getContextPath() + "/login.xhtml");
                } catch (IOException e) {
                    System.out.println("IO exc after redirect");
                }

    }

怎么了? 顺便说一句 none 我在捕手中的系统输出被打印出来了,所以异常在某个地方很深。

编辑 1: 我找到了与异常相关的问题部分的答案 here,但我仍然感到困惑,因为它显示了它应该显示的页面没...

您是否尝试检查 !session.getAttribute("username").isEmpty()。字符串作为空字符串传递,而不是转换为 Null。如果包含用户名,我还会添加,在执行 Null 和 isEmpty 检查之前查看它是否存在于会话属性中

我解开了那个谜... 我只是没有在 web.xml 中填充过滤器。我不知道应该这样做,因为这是我的第一个测试项目。 所以 web.xml 在我的例子中应该包含:

<filter>
   <filter-name>AuthFulter</filter-name>
   <filter-class>com.demshin.beans.AuthFilter</filter-class>
</filter>
<filter-mapping>
   <filter-name>AuthFulter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>