我正在开发一个需要双向身份验证来向服务器识别用户的项目。然后,服务器会根据用户的身份显示该用户可用的信息和选项。
我在主模板上放置了一个“退出”链接。这样做的目的是使所有内容无效/清除并将它们重定向到显示“您已注销”的非安全页面。使用“登录”按钮将他们重定向回登录页面。
登录页面应该提示用户输入他们的证书(它确实是第一次)。但是,当您单击“已注销”页面上的“登录”按钮时,它使用的是前一个用户的 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() {}
}
退出功能
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,但在找到更好的解决方案之前我会这样做,我会与你分享我是如何做到的。
我正在使用 PrimeFaces 按钮,其动作指向前面的 signOut 函数引用。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>
希望这对其他人有帮助。