0

我有两个 JSF 页面和一些托管 bean 和一个过滤器。

一切正常,过滤器工作正常
- 用户必须登录。 - 因此,如果他寻找另一个页面(在这种情况下) ,
用户可以直接进入或重定向到它 - 一旦用户登录,他就可以浏览这些页面。 login.xhtmlhom.xhtml

问题将在下面的代码之后进行解释;

登录.xhtml:

  <h:form>
     <h:panelGrid columns="2">
     <h:outputLabel value="name:"/> <h:inputText value="#{user.name}"/>
     <h:outputLabel value="password:"/> <h:inputSecret value="#{user.password}"/>
     </h:panelGrid>
     <h:commandButton id="btn"  value="login" action="#{user.login()}"/>
  </h:form>

主页.xhtml:

<h:body>
   Hello #{user.name}. You are welcome
</h:body>

用户:

@ManagedBean
@SessionScoped
public class User implements Serializable
{
   String name; //Getter & Setter
   String password; //Getter & Setter
   Authentication authentication;

   public User()
   {
      authentication = new Authentication();
   }

   public String login()
   {
      if (this.getName().equals("user") &&(this.getPassword().equals("1234")))
      {
         authentication.setLoggedIn(true);
         FacesContext context = FacesContext.getCurrentInstance();
         context.getExternalContext().getSessionMap().put("auth", authentication);
         return "home";
      }
      else
      {
         authentication.setLoggedIn(false);
         FacesContext context = FacesContext.getCurrentInstance();
         context.getExternalContext().getSessionMap().put("auth", authentication);
         return "login";
      }
   }
}

验证:

@ManagedBean
@SessionScoped
public class Authentication implements Serializable
{
   private boolean authenticated; //Getter & Setter
}

筛选:

@WebFilter(value = "/faces/*")
public class LoginFilter implements Filter
{

   @Override
   public void init(FilterConfig filterConfig) throws ServletException
   {
      //throw new UnsupportedOperationException("Not supported yet.");
   }

   @Override
   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException
   {
      HttpServletRequest req = (HttpServletRequest) request;
      Authentication auth = (Authentication) req.getSession().getAttribute("auth");

      if ((auth != null && auth.isLoggedIn()) || (req.getRequestURI().equals("/LoginFilter_Simple/faces/login.xhtml")))
      {
         chain.doFilter(request, response);
      } else
      {
         HttpServletResponse res = (HttpServletResponse) response;
         res.sendRedirect(req.getContextPath() + "/faces/login.xhtml");
      }
   }

   @Override
   public void destroy()
   {
      //throw new UnsupportedOperationException("Not supported yet.");
   }
}

我尝试将此功能添加到我的过滤器中:
- 用户登录后,他可以浏览所有页面,除了login.xhtml
- 如果他在地址栏中键入,login.xhtml他将被重定向到home.xhtml

我在 doFilter 方法中添加了简单的代码,所以它变成了:

   @Override
   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException
   {
      HttpServletRequest req = (HttpServletRequest) request;
      Authentication auth = (Authentication) req.getSession().getAttribute("auth");

      if ((auth != null && auth.isLoggedIn()) || (req.getRequestURI().equals("/LoginFilter_Simple/faces/login.xhtml")))
      {
         if (auth.isLoggedIn() && req.getRequestURI().equals("/LoginFilter_Simple/faces/login.xhtml"))
         {
            HttpServletResponse res = (HttpServletResponse) response;
            res.sendRedirect(req.getContextPath() + "/faces/home.xhtml");
         } else
         {
            chain.doFilter(request, response);
         }
      } else
      {
         HttpServletResponse res = (HttpServletResponse) response;
         res.sendRedirect(req.getContextPath() + "/faces/login.xhtml");
      }
   }

甚至代码逻辑也很直观和容易
它给出了->HTTP Status 500


更新

问题HTTP Status 500是由于调用auth.isLoggedIn()嵌套的ifwhile authis null

更新doFilter以解决null问题:(但给出This web page has a redirect loop):

   @Override
   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException
   {
      HttpServletRequest req = (HttpServletRequest) request;
      Authentication auth = (Authentication) req.getSession().getAttribute("auth");

      if ((auth != null && auth.isLoggedIn()) || (req.getRequestURI().equals("/LoginFilter_Simple/faces/login.xhtml")))
      {
         if (auth != null)
         {
            if (auth.isLoggedIn() && req.getRequestURI().equals("/LoginFilter_Simple/faces/login.xhtml"))
            {
               HttpServletResponse res = (HttpServletResponse) response;
               res.sendRedirect(req.getContextPath() + "/faces/home.xhtml");
            } else
            {
               chain.doFilter(request, response);
            }
         } else
         {
            HttpServletResponse res = (HttpServletResponse) response;
            res.sendRedirect(req.getContextPath() + "/faces/login.xhtml");
         }
      } else
      {
         HttpServletResponse res = (HttpServletResponse) response;
         res.sendRedirect(req.getContextPath() + "/faces/login.xhtml");
      }
   }

浏览器打开:

此网页有重定向循环
位于的网页 http://localhost:8080/LoginFilter_Simple/faces/login.xhtml导致了过多的重定向。清除此站点的 cookie 或允许第三方 cookie 可能会解决问题。如果不是,则可能是服务器配置问题,而不是您的计算机问题。

4

1 回答 1

1

问题是你的逻辑。如果用户已经登录,您的第一个if将导致循环。以下应该工作。

boolean isLoggedIn = (auth != null && auth.isLoggedIn());

// Check if the user is accessing "login.xhtml"
if (req.getRequestURI().equals("/LoginFilter_Simple/faces/login.xhtml")) {
    if (isLoggedIn) {
        // Redirect to "home.xhtml"
        HttpServletResponse res = (HttpServletResponse) response;
        res.sendRedirect(req.getContextPath() + "/faces/home.xhtml");
    } else {
        // Otherwise, nothing to do if he has not logged in
        chain.doFilter(request, response);
    }

} else {
    // For all other pages,
    if (isLoggedIn) {
        // Nothing to do
        chain.doFilter(request, response);
    } else {
        // Redirect to "login.xhtml" if he has not logged in
        HttpServletResponse res = (HttpServletResponse) response;
        res.sendRedirect(req.getContextPath() + "/faces/login.xhtml");
    }
}
于 2013-04-22T07:36:36.393 回答