0

2 つの JSF ページといくつかのマネージド Bean と 1 つのフィルターがあります。

すべてとフィルターが正しく機能します。
- ユーザーはログインする必要があります。 -別のページを探す場合、
ユーザーは直接移動するか、リダイレクトされます (この場合) 。 - ユーザーがログインすると、ページをナビゲートできます。 login.xhtmlhom.xhtml

問題は、以下のコードの後に​​説明されます。

login.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>

home.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


更新

この問題は、ネストされたwhile isのHTTP Status 500呼び出しによるものです。auth.isLoggedIn()ifauthnull

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");
      }
   }

ブラウザーは次のように開きます。

この Web ページにはリダイレクト ループがあります
の Web ページ 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 に答える