У меня есть home.jsf
, которые вызывают сервлет входа в систему, который ищет базу данных и запрашивает объект user
, учитывая имя пользователя и пароль. Затем я сохраняю этот объект user
в сеансе под именем атрибута user
, как этот request.getSession().setAttribute("user", user);
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
boolean remember = "true".equals(request.getParameter("remember"));
//Hashing the password with SHA-256 algorithms
password = hash(password);
HttpSession s = request.getSession(false);
if (s != null) {
logger.log(Level.INFO, "Id: {0}", s.getId());
}
User user = scholarEJB.findUserByUserNamePassword(username, password);
try {
if (user != null) {
request.login(username, password);
request.getSession().setAttribute("user", user);
if (remember) {
String uuid = UUID.randomUUID().toString();
UserCookie uc = new UserCookie(uuid, user.getId());
scholarEJB.persist(uc);
Helper.addCookie(response, Helper.COOKIE_NAME, uuid, Helper.COOKIE_AGE);
}else{
//If the user decide they dont want us to remember them
//anymore, delete any cookie associate with this user off
//the table
scholarEJB.deleteUserCookie(user.getId());
Helper.removeCookie(response, Helper.COOKIE_NAME);
}
response.sendRedirect("CentralFeed.jsf");
}else{
response.sendRedirect("LoginError.jsf");
}
} catch (Exception e) {
response.sendRedirect("LoginError.jsf");
}
Затем у меня есть Filer, который отображает всю мою защищенную страницу, которая попытается извлечь пользовательский объект из сеанса, иначе перенаправите меня на home.jsf
для входа снова
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession s = request.getSession(false);
if (s != null) {
logger.log(Level.INFO, "Id Before: {0}", s.getId());
}
User user = (User) request.getSession().getAttribute("user");
s = request.getSession(false);
if (s != null) {
logger.log(Level.INFO, "Id After: {0}", s.getId());
}
if (user == null) {
String uuid = Helper.getCookieValue(request, Helper.COOKIE_NAME);
if (uuid != null) {
user = scholarEJB.findUserByUUID(uuid);
if (user != null) {
request.getSession().setAttribute("user", user); //Login
Helper.addCookie(response, Helper.COOKIE_NAME, uuid, Helper.COOKIE_AGE);
} else {
Helper.removeCookie(response, Helper.COOKIE_NAME);
}
}
}
if (user == null) {
response.sendRedirect("home.jsf");
} else {
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
response.setDateHeader("Expires", 0); // Proxies.
chain.doFilter(req, res);
}
Теперь, как вы видите здесь, я также манипулирую Cookie, но это происходит только тогда, когда я проверяю remember me
. Итак, теперь я нахожусь в CentralFeed.jsf
, но затем любой запрос, который я отправляю отсюда, вернется к home.jsf
для входа снова. Я прохожу через отладчик, поэтому, когда я впервые вхожу в систему, при первом входе в фильтр я успешно извлекаю объект user
из сеанса на request.getSession().getAttribute("user");
. Но после этого, когда я вернусь в фильтр, я больше не являюсь атрибутом сеанса user
. Я установил тайм-аут сеанса на 30 минут в моем web.xml
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
ИЗМЕНИТЬ
Теперь, когда я распечатываю идентификатор сеанса между запросом, это факт другого идентификатора сеанса, но я понятия не имею, почему? пожалуйста, помогите.
EDIT2
@BalusC: Я действительно сделал недействительным сеанс. Тогда вы показываете мне, как принудительно выйти из системы, когда пользователь заходит в другое место (http://stackoverflow.com/info/2372311/jsf-how-to-invalidate-an-user-session-when-he-logs- два раза-с-же-credentia). Итак, внутри пользовательского объекта я это
@Entity
public class User implements Serializable, HttpSessionBindingListener {
@Transient
private static Map<User, HttpSession> logins = new HashMap<User, HttpSession>();
@Override
public void valueBound(HttpSessionBindingEvent event) {
HttpSession session = logins.remove(this);
if (session != null) {
session.invalidate(); //This is where I invalidate the session
}
logins.put(this, event.getSession());
}
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
logins.remove(this);
}
}
В методе valueBound
я сделал недействительным сеанс, когда я его прокомментирую, все работает. Я прохожу через отладчик, и вот что происходит. Когда я впервые войду в систему, LoginServlet поймает его. Затем строка request.getSession().setAttribute("user", user);
вызывает метод valueBound
. Затем фильтр получил вызов, а строка chain.doFilter(req, res);
снова вызовет метод valueBound
, на этот раз session
не является нулевым, поэтому он попадает в if и session.invalidate
. Я комментирую session.invalidate и работает. Но, как вы могли бы догадаться, я не могу выйти из системы, когда пользователь заходит в другое место. Вы видите очевидное решение для этого BalusC?