0

jsf プロジェクト用の単純なログイン システムを作成します。プロジェクトでは、ユーザーのログイン状態を確認するフィルターを作成します。

  • ログインすると、要求されたページに進みます。

  • ログインしていないか、セッションが破棄されている場合は、ログイン ページにリダイレクトします

私の問題は、フィルターを適用すると、すべての h:commandLink がクリック後に何も処理されないことです。しかし、フィルターを削除すると、すべてがうまく機能します。

h:commandButton を fileter で使用しようとすると、すべてが正しく機能します。

この問題を解決するにはどうすればよいですか? 私は長い間研究していますが、解決策は見つかりませんでした。私を助けてください!

フィルタ コード:

    @WebFilter(filterName = "AuthenticationFilter", urlPatterns = {"*.htm"}, dispatcherTypes = {DispatcherType.FORWARD, DispatcherType.REQUEST})
public class AuthenticationFilter implements Filter {

    // The filter configuration object we are associated with.  If
    // this value is null, this filter instance is not currently
    // configured. 
    private FilterConfig filterConfig = null;

    @Inject
    private AuthenticationManager authenticationManager;  

    public AuthenticationFilter() {
    } 

    /**
     * @param request The servlet request we are processing
     * @param response The servlet response we are creating
     * @param chain The filter chain we are processing
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet error occurs
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {

        Throwable problem = null;        
        try {
            HttpServletRequest req = (HttpServletRequest) request; 
            String requestUrl = req.getRequestURI(); 

            String contextPath = req.getContextPath(); 
            if(contextPath.equals("/")){
                contextPath = "";
            }
            String jsfUrl = requestUrl.replaceFirst(contextPath, "");

            if (authenticationManager.allowedAccess(jsfUrl) || requestUrl.equalsIgnoreCase(contextPath+"/login.htm")) {
                chain.doFilter(request, response);                
            } 
            else {
                String redirectPath = contextPath+"/login.htm";
                ((HttpServletResponse) response).sendRedirect(redirectPath); // Not logged in, so redirect to error page.
            }
        } 
        catch (Throwable t) {
            // If an exception is thrown somewhere down the filter chain,
            // we still want to execute our after processing, and then
            // rethrow the problem after that.
            problem = t;
        }

        // If there was a problem, we want to rethrow it if it is
        // a known type, otherwise log it.
        if (problem != null) {
            if (problem instanceof ServletException) {
                throw (ServletException) problem;
            }
            if (problem instanceof IOException) {
                throw (IOException) problem;
            }
            sendProcessingError(problem, response);
        }
    }

    /**
     * Return the filter configuration object for this filter.
     */
    public FilterConfig getFilterConfig() {
        return (this.filterConfig);
    }

    /**
     * Set the filter configuration object for this filter.
     *
     * @param filterConfig The filter configuration object
     */
    public void setFilterConfig(FilterConfig filterConfig) {
        this.filterConfig = filterConfig;
    }

    @Override
    public void destroy() {        
    }

    @Override
    public void init(FilterConfig filterConfig) {        
        this.filterConfig = filterConfig;
        if (filterConfig != null) {
        }
    }
}

JSF コード:

<h:body>
<f:view contentType="text/html" locale="#{authenticationManager.languageCode}">
<div class="header">
    <h:form id="topForm" prependId="false">
        <div class="logo">
            <h1><img src="#{facesContext.externalContext.requestContextPath}/resources/images/login-logo2.png" width="220" height="64"/></h1>
        </div>  
        <ul class="navTop">
            <li>
                <a href="#"><span class="pictograms">f</span>#{authenticationManager.currentUser.firstName} #{authenticationManager.currentUser.lastName}</a>
            </li>
            <li>
                <a href="#"><span class="pictograms">m</span>Messages</a>
            </li>
            <li class="logout">
                <h:commandButton action="#{authenticationManager.logout()}" value="aaaaaaa" style="color:#fff;" />
                <h:commandLink action="#{authenticationManager.logout()}" value="#{label.Logout}"/>
                <h:commandLink immediate="true" action="#{authenticationManager.logout}" id="logoutLink">
                    <span class="pictograms">E</span>***This link is not work correctly***
                </h:commandLink>
            </li>
        </ul>           
        <ui:insert name="mainmenu"/>
    </h:form>
</div>

4

2 に答える 2

1

具体的な問題は、JSF デフォルト リソースの提供がjsf.jsフィルタによってブロックされているために発生します。このリソースは、JSF コマンド リンクと JSF ajax リクエストの機能に必須です (ajax のないプレーンなコマンド ボタンは機能します)。

JSF リソースを認証チェックから除外する必要があります。ResourceHandler.RESOURCE_IDENTIFIERこれを行うには、リクエスト URI が webapp コンテキスト パス(値が ) の後に始まるかどうかを確認するだけです/javax.faces.resource

だから基本的に:

HttpServletRequest req = (HttpServletRequest) request;

if (req.getRequestURI().startsWith(req.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER)) {
    chain.doFilter(request, response); // Let it continue.
    return;
}

ファイル拡張子をチェックするのは面倒であり、考えられるすべてのリソース要求を十分にカバーすることはできません。

于 2012-11-18T23:16:20.040 に答える
0

調査の結果、解決策は見つかりませんでした。だから私は多くの可能な方法にゲストを招待し、これについての説明を見つけました.

フィルター パターン "*.htm" ですべてをフィルター処理すると、.js.htm、.css.htm、.gif.htm、.jpg.htm などのすべての要求が login.htm ページにリダイレクトされます。

ポイントは、.js.htm を正しいファイルではなくログイン ページにリダイレクトすることです。そのため、jsf.js.htm などの重要なライブラリが login.htm にリダイレクトされました。これが、h:commandLink が正しく機能しない主な原因です。

これが私のような誰かを助けることを願っています。

try {
        HttpServletRequest req = (HttpServletRequest) request; 
        String requestUrl = req.getRequestURI(); 

        if(requestUrl.endsWith(".js.htm") 
            || requestUrl.endsWith(".css.htm") 
            || requestUrl.endsWith(".gif.htm") 
            || requestUrl.endsWith(".png.htm") 
            || requestUrl.endsWith(".jpg.htm") 
            || requestUrl.endsWith(".jpeg.htm")){
            chain.doFilter(request, response);            
        }
        else{
            String contextPath = req.getContextPath(); 
            if(contextPath.equals("/")){
                contextPath = "";
            }
            String jsfUrl = requestUrl.replaceFirst(contextPath, "");

            if (authenticationManager.allowedAccess(jsfUrl) || requestUrl.equalsIgnoreCase(contextPath+"/login.htm")) {
                chain.doFilter(request, response);                
            } 
            else {
                String redirectPath = contextPath+"/login.htm";
                ((HttpServletResponse) response).sendRedirect(redirectPath); // Not logged in, so redirect to error page.
            }
        }
    } 
于 2012-11-18T13:07:52.063 に答える