我在JBoss AS 7上使用jsf2.0和java ee6
我有一个看起来像这样的LoginController.java:
@ManagedBean(name = "loginController")
@SessionScoped
public class LoginController implements Serializable{
private static final long serialVersionUID = 1119172305268193508L;
@Inject
private UserProvider userProvider;
@PostConstruct
public void initNewUser() {
user = new User();
}
private User user;
private String accountName;
private String password;
public String ownLogin() throws Exception {
HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance()
.getExternalContext().getRequest();
if (accountName != null) {
try {
if (exists(accountName)) {
user = userProvider.findUserByAccountName(accountName);
if (verifyPassword(user, password)) {
userProvider.saveChangedUser(user);
// OWASP SAYS: after login, destroy the session make a new one
// a so called handover
// Destroy the session
FacesContext facesContext = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession) facesContext.getExternalContext().getSession(false);
if(session != null){
session.invalidate();
}
// create new session after logout
session = (HttpSession) facesContext.getExternalContext().getSession(true);
setLogin(true);
}
}
/* some getters and setters */
}
OWASP表示,出于安全原因,登录后应删除会话(参见:V3.7)
我现在在我的代码中执行此操作:
FacesContext facesContext = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession) facesContext.getExternalContext().getSession(false);
if(session != null){
session.invalidate();
}
// create new session after logout
session = (HttpSession) facesContext.getExternalContext().getSession(true);
首先,我删除旧会话,然后进行新会话 在此之后,我将登录设置为true ...
当然,在运行整个代码之后,用户没有登录,因为LoginController是在旧的会话范围内管理的 - 并且在新的会话范围内,在范围内有一个新的LoginController而没有用户使用...
有什么办法可以在创建后将新的LoginController添加到新会话中吗?
或者通常的方法是什么?
答案 0 :(得分:4)
当您使会话无效时,其所有属性将在响应结束时被删除。但是,您将在仅存在于旧会话中的会话范围Bean实例上设置登录状态。
您基本上需要手动重新创建会话范围的bean,并在无效后将其放入新的会话中。
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
externalContext.invalidateSession();
LoginController loginController = new LoginController();
loginController.setUser(user);
externalContext.getSessionMap().put("loginController", loginController);
(看看ma,不再丑陋的javax.servlet
进口!)
顺便说一句,当你走这条路的时候,你也可以让你的LoginController
视图范围内的bean只在会话中处理User
。
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
externalContext.invalidateSession();
externalContext.getSessionMap().put("user", user);
(它将在整个EL上下文中由#{user}
提供,也可以在托管属性中使用;它不一定需要是JSF托管bean)