注销时清除客户端SSL状态(使用双向SSL)

Ace*_*unk 5 ssl-certificate java-ee jsf-2

我正在进行一个需要双向身份验证才能向服务器标识用户的项目。然后,服务器根据用户身份显示该用户可用的信息和选项。

我在主模板上放置了“退出”链接。这样做的目的是使所有内容无效/清除,然后将它们重定向到显示“您已退出”的不安全页面。使用“登录”按钮,将其重定向回登录页面。

登录页面应提示用户输入其证书(第一次)。但是,当您单击“注销”页面上的“登录”按钮时,它将使用先前用户的SSL状态,并且不会出现证书提示。

我真正需要的是一种注销方法(最好不要使用Java脚本),该方法将清除所有缓存,使所有会话对象无效,并清除SSL状态。

到目前为止,这是我所做的:

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() {}
}
Run Code Online (Sandbox Code Playgroud)

登出功能

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);
}
Run Code Online (Sandbox Code Playgroud)

----------------------编辑----------------------

我知道我说过我不想使用JavaScript,但是直到找到更好的解决方案之前,我都会与您分享我的工作方式。

我使用的是PrimeFaces按钮,其操作指向之前的signOut函数引用。oncomplete参数指向一个JavaScript,该JavaScript清除了Internet Explorer和Firefox的SSL状态(尚未尝试使用其他状态)。

登出按钮

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

JavaScript clearSSLState()

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

请务必注意,我的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>
Run Code Online (Sandbox Code Playgroud)

希望这对其他人有帮助。