| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java EE (J2EE) и Spring > Сервлеты и кукисы |
| Автор: tolet 6.11.2008, 08:50 |
| Добрый день Всем! Ситуация такая: пользователь веб-приложения логинится на сервере - все проходит удачно (связывается с БД, проверяется логин и пароль). После этого кто-то другой заходит на тоже самое веб-приложение - и сразу попадает в сеанс только что залогиненного (не свой сеанс)! Выйти из его сеанса не может. Все данные логина и пароля передаются сервлетами через кукисы. Подскажите в чем может быть загвоздка и как ее можно обойти. Заранее благодарен за ответ. |
| Автор: necromancer 6.11.2008, 11:35 |
| причин может быть несколько как мне кажется: 1 не правильное упраление куками 2 кто то на промежуточном уровне кэшит куки? насчет этого не уверен 3 сессия всегда одна, по причине реализации сервлета как синглетона =) 4 какая то другая причина. вообще без кода похоже на гадание по кофейной гуще. PS А вот у меня прыщик, что это может быть? =) |
| Автор: tolet 6.11.2008, 12:13 | ||
Выжимка с кода:
|
| Автор: necromancer 6.11.2008, 12:58 |
| ага! а теперь ставим FireFox и смотрим что именно идет от клиентов к серверу. Могу предположить, что второй пользователь получает логин guest и идет дальше как зарегистрированный пользователь =) код записи/чтения мы увидели, а код зависящий от этих манипуляций нет, т.е. код менеджера безопастности в студию. PS на будущее , хранить пароль юзера в куках - зло. Хранить какие либо данный о пользователе в куках зло! Предположим что у тебя юзер имел роль dialer, ты поменял ему роль, но после того как он придет с куками, он снова будет диалер? =) |
| Автор: tolet 6.11.2008, 13:30 | ||
dealer - это не роль юзера - из этой переменной формируется ближайший адрес дилера для зарегистрированного пользователя Прошу прощения, я конечно могу показаться полным ламером (может я и на самом деле ламер - не учился я на программиста - изучаю все самостоятельно по книгам), но я не очень понимаю что имеется ввиду под менеджером безопасности. Это часть кода, которая проверяет параметры логина и пароля? или что? |
| Автор: necromancer 6.11.2008, 13:54 | ||
ты привел код где идет чтение/запись куков. Хотеолсь бы увидеть место где используются полученные переменные. to: Asal Достаточно хранить некое уникальное значение, желательно не несущее смысловой нагрузки, например некий UID (не PK) и уже понему делать какие то шаги по аутентификации юзера. Смоделируем ситуацию: Злоумышленник поставил перед вашим сервером свой прокси или снифер, через какой то промежуток времени у него будут ДОСТОВЕРНЫЕ данные о логинах и паролях. В случае же если идет обмен неким ключем, то при смене пароля или канала злоумышленник не сможет воспользоватся сгенерированным UID, так как он может быть например привязан к IP клиента и/или дате действия. Далее получив UID и даже получив доступ к системе, злоумышленник не сможет поменять пароль, так как при его смене в нормальной системе всегда запрашивается старый =) Доступно изъяснился? =) конечно все это ерунда если делается домашняя страничка =) с доступом к интим фото :Р PS на мой домашний портал кивать не стоит - используется стандартная процедура аутентификации через SEAM + нет времени на заморочки =) |
| Автор: tolet 6.11.2008, 14:11 | ||
Вот код, где используется часть данных (все выложить постесняюсь - придется выкладывать весь сервлет):
|
| Автор: necromancer 6.11.2008, 14:20 | ||
| ну опять ничего не понятно откуда сюда приходит login, как он выставляется. Что это класс, вдруг он синглетон и ты после логина, НЕ очищаешь поля login и т.д. PS на будущее: Logger log = Logger.getLogger(Main.class.getName()); перенести в инициализацию класса (там где объявляются глобальные переменные) а при выпадении ошибки делать: log.error(e); так же посмотри как правильно оборачивать соединения в блоки try catch
Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT id_user, login, password, date(last_visit) as date, time(last_visit) as time FROM db_users WHERE login=\'" + login + "\'"); используй PrepareStatement PrepareStatement ps = conn.createPrepareStatement("select ... from ... where login = ? "); ps.setString(1,login); ResultSet rs = ps.executeQuery(); PSS пора в отпуск =) |
| Автор: tolet 6.11.2008, 14:31 | ||||
эта переменная выставляется из кукисов (см. первый выложенный код)
как можно понять синглтон это или нет? |
| Автор: necromancer 6.11.2008, 14:49 | ||
| должно работать просто примерно так: метод
соотв при неудачной аутентификации бросать исключение. при удачно выполянть необходимые действия. тогда все будет примерно нормально. у тебя же видимо происходит такая ерунда, что после выставления переменной login она остается в данном сервлете навсегда выставленной. что необходимо сделать: при неудачной аутентификации вызывать метод: clear() { login = null; .... } но опять таки нестоит хранить переменные глобальные в сервлете. см выше. |
| Автор: tolet 6.11.2008, 15:10 |
| necromancer, большое спасибо за подробную консультацию. Буду пробовать |
| Автор: fronya 8.11.2008, 18:53 |
| Всем привет!! Интересная конечно тема использовать Cookies, но я не советую, это не есть хорошо!!! Есть куча проблема с ними.... Если используешь сервлеты, то может лучше использовать интерфейс HTTPSessian, а лучше всего если ты хочешь сам следить за пользователями присваивай им идентификационные номера сам и храни в базе данных с информацией о клиентах (по-моему намного удобней). С Cookies много проблем (- захотел я зайти под другим логином - а сессия таже, зашел по другим браузером - сессия изменилась, короч много всего учитывать надо). Желаю удачи!!! |