1

だから私は私のものと似たような質問にかなり出くわしました。

認証 Bean では、認証が成功すると一部の Web リソースにアクセスし、失敗するとアクセスを「フィルタリング」して現在のログイン ページにリダイレクトする必要があります。ここで、その認証 Bean に、成功した場合に備えて次の行を追加しました。

FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(authentificationBean1.AUTH_STATE, "true") ;

AUTH_STATEは、Bean で次のように定義されています。

public static final String AUTH_STATE = ""; 

失敗した場合は、次のことを行います。

FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(authentificationBean1.AUTH_STATE, null) ;

フィルター (認証ページを除くすべてのファイルに適用されるフィルター) では、doFilter メソッドは次のようになります。

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

        if (((HttpServletRequest) request).getSession().getAttribute(authentificationBean1.AUTH_STATE) == null) {
            ((HttpServletResponse) response).sendRedirect("authentification.xhtml");

        } 

        if(((HttpServletRequest) request).getSession().getAttribute(authentificationBean1.AUTH_STATE) != null) {
            ((HttpServletResponse) response).sendRedirect("accueil.xhtml");
        }

    }

私の考えは、認証がうまくいった場合、authentificationBean1.AUTH_STATEセッション属性がnull以外に設定されるため、フィルターテストでウェルカムページ (accueil.xhtml) にリダイレクトできるようになるというものでした。その属性が null の場合、認証ページにとどまります。

全体を試食: フィルターは機能しているように見えますが、多すぎます。つまり、認証テストが成功しなければならない場合でも、ウェルカム ページに進むことができません。実際にはフィルターなしで正常に機能していました.JSFまたはフィルターでフィルターを使用することについて何かを見逃したようです.

PS:呼び出す別のフィルターがないため、chain.doFilterを適用しませんでしたが、そこに何かが疑われます。

ご指摘ありがとうございます。

編集 :

<filter>
        <filter-name>RestrictionFilter</filter-name>
        <filter-class>beans.RestrictionFilter</filter-class>
</filter>
<filter-mapping>
        <filter-name>RestrictionFilter</filter-name>
        <url-pattern>/faces/accueil.xhtml</url-pattern>
</filter-mapping>
4

1 に答える 1

3

フィルターは無限ループで実行され、毎回それ自体にリダイレクトされます。サーブレットへのリクエストを継続することはありません。HTTP の仕組みを誤解しているようです。response.sendRedirect()基本的に、まったく新しい HTTP リクエストを発行しています。このまったく新しい HTTP 要求は、フィルターを再度呼び出します。そのため、フィルタが にリダイレクトする条件に一致するとaccueil.xhtml、無限ループでそのページにリダイレクトし続け、リクエストを処理するためにサーブレットに進むことはありません。

さらに、 の意味も誤解していますchain.doFilter()。次のフィルターに明示的に進むことはありません。フィルターがないかのように要求を続行します。チェーンの次に別のフィルターがあるかどうかは、まったく関係ありません。フィルターがない場合は、ターゲット サーブレット (このFacesServlet場合、JSF ページの処理を担当するサーブレット) に到達します。

基本的には、次のような流れである必要があります。

  • ユーザーがログインしていない場合:
    • 現在リクエストされているページが でない場合はauthentification.xhtml、そこにリダイレクトします。
    • または、現在リクエストされているページがすでにauthentification.xhtmlである場合は、リクエストを続行します。
  • または、ユーザーがログインしている場合は、リクエストされたページに関係なくリクエストを続行します。

言い換えれば、これはそれを行うべきです:

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {    
    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;
    HttpSession session = request.getSession(false);
    String loginURL = request.getContextPath() + "/authentification.xhtml";

    boolean loggedIn = session != null && session.getAttribute(authentificationBean1.AUTH_STATE) != null;
    boolean loginRequest = request.getRequestURI().startsWith(loginURL);
    boolean resourceRequest = request.getRequestURI().startsWith(request.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER);

    if (loggedIn || loginRequest || resourceRequest)) {
        chain.doFilter(request, response);
    } else {
        response.sendRedirect(loginURL);
    }
}

JSF リソース (を介して含まれる CSS/JS/画像ファイル<h:outputStylesheet|outputScript|graphicImage>) のチェックも追加したことに注意してください。そうしないと、ログイン ページが表示されたときにそれらもブロックされます。/*また、このフィルターは、1 つのページだけでなく、マップできることにも注意してください。

于 2013-05-20T14:13:14.003 に答える