我还没有找到一个真正的解决这个问题的方法,即使它真的很常见…
我有这样的上下文:
- JSF应用程序运行在Glassfish Server v3.1, JDK6。所有这些都在我的个人电脑上安装了WinVista(最后一个应该不重要)。
- 使用SSL和基本身份验证(容器的安全性)
- 我已经在我的后台bean中完成了logout()方法,使会话无效并发送重定向。
我不能使容器再次显示登录框来验证用户,并且能够更改用户…我的用户总是可以返回,在浏览器中按下后退按钮或只是写URL,并继续在那里做事情,当假定不应该有一个现有的会话。
我正在获取创建我的支持bean的用户名:
private void setName() {
this.name = FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal().getName();
}
我用这个名字来执行操作…
然后注销我的xhtml代码:
<h:panelGroup id="logOut">
<h:form>
<h:commandLink id="linkLogOut" action="#{visitor.logout}" value=" Clic here to Log Out" />
</h:form>
</h:panelGroup>
在我的bean中调用这个方法::
public void logout() throws IOException {
// FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
this.name = null;
FacesContext fc = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession)fc.getExternalContext().getSession(false);
session.invalidate();
FacesContext.getCurrentInstance().getExternalContext().redirect("https://localhost:8080/");
}
我用:
声明我的支持bean@Named(value="visitor")
@SessionScoped
…我也在做重定向从部署描述符…结果是一样的。
如果我关闭浏览器,会话将丢失,容器将再次要求我输入user/pass。
有什么建议吗?
非常感谢!
Alejandro。我不能使容器再次显示登录框来验证用户,并且能够更改用户…我的用户总是可以返回,在浏览器中按back按钮或只是写URL,并继续在那里做事情,当假定不应该有一个现有的会话
这些页面可能从浏览器缓存中显示,而不是从服务器重新请求。为了阻止这种情况,创建一个Filter
,它映射到感兴趣的URL模式(*.jsf
可能?),并在doFilter()
方法中执行以下工作:
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setHeader("Cache-Control", "no-cache,no-store,must-revalidate"); // HTTP 1.1
httpResponse.setHeader("Pragma", "no-cache"); // HTTP 1.0
httpResponse.setDateHeader("Expires", 0); // Proxies.
chain.doFilter(request, response);
测试前清空浏览器缓存
非常感谢您的回答。
我请了几天假…没有回复这个帖子。
我只是想分享我的解决方案。
基本的身份验证是绑定到浏览器的,一旦你完成了登录,应该应该关闭浏览器来完成注销…有什么不那么优雅的呢?
我更改为FORM身份验证,创建我的表单,并将用户信息发布给一个servlet,该servlet根据我的领域验证用户凭据,该servlet将用户重定向到应用程序或错误页面。显然,必须对web.xml中的安全约束进行适当的配置。
我在这里分享我的解决方案:
登录页面:<!-- This is the login page that implement the "Form Base" login -->
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Login Form</title>
</h:head>
<h:body>
<h2>Welcome to the secure messaging service!:</h2>
<form name="loginForm" method="POST" action="j_security_check">
<p><strong>Please type your user name: </strong>
<input type="text" name="j_username" size="25" /></p>
<p><strong>Please type your password: </strong>
<input type="password" size="15" name="j_password" /></p>
<p>
<input type="submit" value="Submit"/>
<input type="reset" value="Reset"/>
</p>
</form>
</h:body>
验证servlet方法:
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
String username;
String password;
username = request.getParameter("j_username").toString();
password = request.getParameter("j_password").toString();
request.login(username, password);
response.sendRedirect("/SecureMessageWebInterface/");
} catch (Exception e) {
response.sendRedirect("error.xhtml");
}
}
和配置文件中需要的部分....
<security-constraint>
<display-name>Web Interface</display-name>
<web-resource-collection>
<web-resource-name>SSL Pages</web-resource-name>
<description/>
<url-pattern>/</url-pattern>
</web-resource-collection>
<auth-constraint>
<description>All site is restricted</description>
<role-name>user</role-name>
</auth-constraint>
<user-data-constraint>
<description>Secure connection is required</description>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>webapps</realm-name>
<form-login-config>
<form-login-page>/login.xhtml</form-login-page>
<form-error-page>/error.xhtml</form-error-page>
</form-login-config>
</login-config>
我希望这能对别人有用。
祝你一切顺利,
Alejandro。