У меня есть 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>
EDIT
Теперь, когда я распечатываю идентификатор сессии между запросами, это фактически другой идентификатор сессии, но я понятия не имею, почему? пожалуйста, помогите.
EDIT2
@ BalusC: Я действительно объявил сессию недействительной. Тогда вы покажете мне, как принудительно выйти из системы, когда пользователь входит в систему где-то еще (/2057152/kak-sdelat-nedeistvitelnym-seans-polzovatelya-kogda-on-dvazhdy-registriruetsya-s-odinakovymi-uchetnymi-dannymi). Итак, внутри объекта User у меня есть это
@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
. Я комментирую сессию. Подтвердить, и она работает Но, как вы уже догадались, я не могу принудительно выйти из системы, когда пользователь входит в систему где-то еще. Видите ли вы очевидное решение для этого BalusC?