5

サーバーに対してユーザーを識別するために双方向認証を必要とするプロジェクトに取り組んでいます。サーバーは、ユーザーのIDに基づいて、そのユーザーが利用できる情報とオプションを表示します。

メインテンプレートに「サインアウト」リンクを配置しました。これの目的は、すべてを無効化/クリアし、「サインアウトしました」という安全でないページにリダイレクトすることです。ログインページにリダイレクトする「サインイン」ボタンを使用します。

ログインページは、ユーザーに証明書の入力を求めるプロンプトを表示する必要があります(初めての場合)。ただし、[サインアウト]ページの[サインイン]ボタンをクリックすると、前のユーザーのSSL状態が使用され、証明書のプロンプトは表示されません。

私が本当に必要としているのは、すべてのキャッシュをクリアし、すべてのセッションオブジェクトを無効にし、SSL状態をクリアするログアウトメソッド(Javaスクリプトを使用しないことをお勧めします)です。

これが私がこれまでにしたことです:

1.)web.xmlにセキュリティ制約を設定し、ページマッチングパターン「/ secure/*」にhttps経由でのみアクセスできるようにします。これはうまく機能しています...

2.)キャッシュを防ぐフィルターを作成しました...

3.)サインアウトする関数を作成しました...

ありとあらゆる助けをいただければ幸いです。

フィルタコード:

@WebFilter("/secure/*")
public class NoCacheFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
        httpResponse.setHeader("Cache-Control", "no-cache,no-store,must-revalidate");
        httpResponse.setHeader("Pragma", "no-cache");
        httpResponse.setDateHeader("Expires", 0L); // Proxies.
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {}
}

サインアウト機能

public void signOut() {
    ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
    HttpServletRequest request = (HttpServletRequest) externalContext.getRequest();

    // Log Out of the Session
    request.logout();

    // Invalidate the Session objects
    externalContext.invalidateSession();
    if (externalContext.getRequestCookieMap().get(OPEN_TOKEN_COOKIE) != null) {
        externalContext.addResponseCookie(OPEN_TOKEN_COOKIE,null,Collections.<String, Object>singletonMap("maxAge", 0));
    }

    // Redirect to the Sign out page
    String signOutURL = MessageFormat.format("http://{0}{1}/{2}",externalContext.getRequestServerName(),externalContext.getRequestContextPath(),"goodbye.jsf");
    externalContext.redirect(signOutURL);
}

- - - - - - - - - - - 編集 - - - - - - - - - - -

JavaScriptを使用したくないと述べたことは知っていますが、より良い解決策が見つかるまで、それをどのように行ったかを皆さんと共有します。

以前にsignOut関数参照を指すアクションでPrimeFacesボタンを使用しています。oncompleteパラメーターは、Internet ExplorerおよびFirefoxのSSL状態をクリアするJavaScriptを指します(他のパラメーターはまだ試していません)。

サインアウトボタン

<p:commandButton value="Sign out" action="#{adminNavigationBean.signOut}" oncomplete="clearSSLState();" styleClass="commandButton"/>

JavaScript clearSSLState()

<script type="text/javascript">
    function clearSSLState() {
        document.execCommand("ClearAuthenticationCache");
        window.crypto.logout();
    }
</script>

goodbye.xhtmlページが/secure/フォルダーにないことに注意することが重要です。そうである場合、ユーザーはすぐに証明書を選択するように求められます。これはweb.xmlのセキュリティ制約が原因であり、正しい動作です。

web.xmlセキュリティ制約

<security-constraint>
    <web-resource-collection>
        <web-resource-name>Protected Context</web-resource-name>
        <url-pattern>/secure/*</url-pattern>
    </web-resource-collection>
    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint>

これが他の人に役立つことを願っています。

4

0 に答える 0