рельсы, хранящие пароль в сеансе - PullRequest
6 голосов
/ 17 ноября 2011

У меня есть приложение rails, которое делает вызов через web api, само приложение rails не имеет базы данных или пользовательского хранилища.При каждом вызове API необходимо отправлять имя пользователя и пароль для каждого запроса.

Я хотел бы предоставить механизм аутентификации для приложения rails.Я планирую сделать это следующим образом:

  1. Показать страницу входа в систему
  2. Получить имя пользователя и пароль
  3. Сохранить имя пользователя и пароль
  4. Выполните ручную аутентификацию с помощью warden.authenticate или authlogic.something (или, может быть, даже если это не требуется, можно просто проверить, сохранено ли что-то в сеансе)
  5. А затем, когда пользователь что-то делает, я передаю имя пользователя и пароль, которыебыл сохранен ранее.

Теперь моя проблема - где мне хранить пароль?Если я использую сеанс, я, очевидно, не могу использовать хранилище cookie, я могу использовать session_store = :active_record_store, но не уверен, безопасно ли это, также у меня нет базы данных на данный момент, так почему я должен создавать ее только для сеанса?Есть ли другой механизм для хранения паролей в течение сеанса?(очевидно, безопасный путь)

В предыдущих рельсах было:

  • MemoryStore
  • FileStore

Но теперь, похоже, оба они удалены.Таким образом, любое другое решение?

Заметки из ответов:

  1. Хранение зашифрованных паролей не будет работать, так как мне нужен необработанный пароль для отправки на сервер при выполнении вызовов API.
  2. У меня нет контроля над API, поэтому я не могу изменить его аутентификацию.
  3. В приложении rails нет поддержки профиля пользователя.Все управляется вызовами API.

Я наконец-то подумал о реализации пользовательского хранилища памяти, но, похоже, выдает ошибку stackoverflow.Я получил код от https://rails.lighthouseapp.com/projects/8994/tickets/1876-uninitialized-constant-actioncontrollersessionmemorystore

require 'action_dispatch'
module ActionDispatch
module Session
class CustomMemoryStore < ActionDispatch::Session::AbstractStore
  GLOBAL_HASH_TABLE = {} #:nodoc:

  private
    def get_session(env, sid)
      sid ||= generate_sid
      session = GLOBAL_HASH_TABLE[sid] || {}
      session = AbstractStore::SessionHash.new(self, env).merge(session)
      [sid, session]
    end

    def set_session(env, sid, session_data)
      GLOBAL_HASH_TABLE[sid] = session_data
      return true
    end
  end
 end
end
Steptools3::Application.config.session_store :custom_memory_store, :key => '_some_xyz'

Ответы [ 4 ]

2 голосов
/ 25 ноября 2011

Вы можете попробовать использовать Redis в качестве хранилища сеансов.Мы используем rails3-redis-session-store драгоценный камень.Источник можно найти здесь .

Он очень прост в настройке, и сеансы автоматически заканчиваются, что делает его безопасным.Пример конфигурации:

YourApp::Application.config.session_store :redis_session_store,
                                          :db => 0,
                                          :expire_after => 10.minutes,
                                          :key_prefix => "your_app:session:"

В качестве альтернативы можно использовать dalli и, таким образом, использовать memcached в качестве бэкэнда.

Надеюсь, это поможет.

1 голос
/ 27 ноября 2011

Я попытаюсь проанализировать ваш выбор:

Если сервер взломан с помощью CustomMemoryStore

Рассмотрим следующий сценарий:

  • 4 Пользователи A, B, C, D вошли в систему.
  • Ваш сервер взломан. Хакер получает контроль над сервером.
  • D сделал какую-то операцию.
  • Вы обнаружили, что ваш сервер взломан, и восстановили вашу систему.

С CustomMemoryStore хакер может получить пароли всех пользователей. Нетрудно внедрить некоторую логику в запущенный процесс Rails или выгрузить память и анализ. Хранение пароля в ActiveRecord, MongoDB, Redis имеет похожую проблему.

Если сервер взломан с помощью CookieStore?

Что, если произойдет предыдущий сценарий и вы используете CookieStore?

Давайте рассмотрим механизм CookieStore:

  • На сервере есть секретный ключ для подписи и проверки сеанса.
  • Каждый раз, когда браузер отправляет запрос, сервер расшифровывает сеанс, изменяет данные, подписывает сеанс и отправляет сеанс браузеру в файле cookie.

Другими словами, хакер не может получить пароль от куки или секретного ключа. Ему нужен и cookie, и секретный ключ, чтобы украсть пароль.

В этом случае пароли A, B, C являются безопасными. Только пароль D будет украден Хакером. Вы можете минимизировать ущерб, восстанавливая систему как можно скорее.

Проблема CustomMemoryStore

Помимо проблемы безопасности, я знаю, что вы знаете, что CustomMemoryStore не масштабируется. Тем не менее, проблема может быть больше, чем вы думаете. В действии контроллера вы отправите запрос другим веб-службам, он заблокирует весь ваш сервер, если удаленная служба работает медленно или не работает. Это может быть болезненно, даже если у вас есть только 1-10 пользователей одновременно.

Даже если вы решите запустить свое приложение на одном сервере, вы можете запустить процесс нескольких рельсов с помощью Passenger или Unicorn. CustomMemoryStore отрицает эти параметры.

Концерн безопасности клиента

Если проблема заключается в краже cookie со стороны браузера, вы можете рассмотреть EncryptedCookieStore . Он шифрует сеанс и сохраняет в клиенте cookie. Вы не можете получить пароль, если у вас есть только cookie или ключ. Вам нужен и cookie, и ключ для расшифровки пароля.

В чем основная проблема?

EncryptedCookieStore более безопасен, потому что он хранит зашифрованный пароль в cookie пользователя, а секретный ключ доступен только на сервере. Хакер не может получить пароль, если у него есть только cookie или секретный ключ - ему нужны оба.

Конечно, вы можете реализовать аналогичную логику с CustomMemoryStore. Например, сохраните зашифрованный пароль в памяти сервера, а отдельный ключ - в файле cookie. Если вы все же решили хранить зашифрованный пароль на сервере, я рекомендую использовать Redis для хранения. Это просто и быстро по сравнению с MySQL и MongoDB. CustomMemoryStore не предлагается из-за проблемы с масштабированием.

Другие предложения

Пароль другой системы - очень конфиденциальные данные, вы должны быть очень осторожны, чтобы иметь дело с проблемой безопасности. Если это государственная служба, вы должны очень тщательно написать свое Соглашение об условиях обслуживания и отказ от ответственности. Кроме того, вы должны запускать свои сервисы с HTTPS.

TL; DR

  • Используйте OAuth, если можете (ну, я знаю, что вы не можете)
  • EncryptedCookieStore должно быть простым и безопасным.
  • Если вы решили сохранить пароль на сервере, пожалуйста, зашифруйте его и сохраните секретный ключ на стороне клиента (cookie).
1 голос
/ 25 ноября 2011

Сеансовые куки-файлы шифруются с использованием сеансового ключа. Ваши данные должны быть защищены до тех пор, пока вы сохраняете свой ключ сессии надежным (128 символов) и в безопасности.

ActionController::Base.session = {
  :key         => '_foo_bar_session',
  :http_only   => true,
  :secret      => 'dldkdke420934indsknknkfsnh318u84e9u49832dfkdsajdsk'
}

Если вы хотите сохранить детали аутентификации вне сеанса браузера, вы можете сохранить их в постоянных cookie-файлах с подписью.

cookies.permanent.signed[:user_credentials] = [login, password]

Подписанные файлы cookie доступны как обычные файлы cookie:

cookies[:user_credentials]

Убедитесь, что вы установили сильный cookie_verifier_secret в файле инициализатора.

ActionController::Base.cookie_verifier_secret ='dskjkjfdshfddsfkhkr3898398430943'

Ссылка

Подписанные и постоянные куки в Rails 3

1 голос
/ 17 ноября 2011

Я бы порекомендовал сделать следующий шаг и настроить простую базу данных и сэкономить массу хлопот для себя и пользователя. Что произойдет, когда пользователь захочет вернуться на сайт, ему придется заново зарегистрироваться.

Я считаю Devise замечательным для этой цели и очень простым для интеграции.

Если есть проблема, когда вы не хотите, чтобы классический сервер баз данных работал, вы можетехочу посмотреть MongoDB

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...