2016-07-07 4 views
7

Я хочу установить простой поставщик OAuth2 на основе весенней загрузки, пружинной защиты и пружины-oauth2.Поставщик oauth2 для обеспечения безопасности без гражданства

У меня все работает на машине с одним экземпляром: для авторизации OAuth2 пользователь отправляется на /oauth/authorize. Большинство пользователей не вошли в систему, поэтому они перенаправляются на /login по весенней безопасности, а затем обратно t /oauth/authorize, чтобы завершить авторизацию.

В конфигурации по умолчанию spring-security устанавливает cookie в браузере пользователя с идентификатором сеанса и сохраняет данные сеанса в памяти.

public static class SecurityConfiguration extends WebSecurityConfigurerAdapter { 
    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http 
      .authorizeRequests() 
      .and() 
      .formLogin() 
      .loginPage("/login") 
      .permitAll(); 
    } 
[...] 

Для того, чтобы обеспечить балансировку нагрузки и сине-зеленые развертывания без потери пользовательских сеансов, (я думаю) я должен выполнить следующие действия:

  • Отключить сторону сервера сеансов - для API который отвечает только за авторизацию OAuth2, я не думаю, что необходимо иметь общую базу данных для сеансов.
  • Вместо этого включите cookie с сохранением имени, содержащего аутентификацию пользователя, временную авторизацию.
  • магазин редирект URL для перенаправления /login в другом месте
    • Можно ли хранить это в форме авторизации или пользователя куки? Или что было бы «бесконфликтной» альтернативой?
  • Отключить CSRF (я знаю, как сделать это и oauth2 имеет auth_codes которые я думаю, имеют аналогичные цели. Просто для полноты картины.)

ли такой подход имеет смысл? Какие изменения необходимы?

+0

Что я грубо сделал: (a) отключено CSRF (b) сохранить URL-адрес перенаправления в cookie. Мне нужно только хранить коды oauth2. – Jan

ответ

0
  1. После того, как пользователь делает логин к вашему провайдеру, вы генерировать код авторизации, который направляет клиентское приложение (через редирект (обратный вызов) URL).

  2. Позже клиентское приложение отправляет запрос на ваш сервер для получения токена доступа. В этом запросе он содержит код авторизации.

  3. В этот момент вы должны иметь возможность сравнить код авторизации, отправленный клиентским приложением, с тем, который вы создали на первом месте. Здесь вам нужна общая память.

Если вы посмотрите на этом разделе протокола section-4.1 вам нужна разделяемая память между точками C и D.

Это не может быть достигнуто ни с чем за пределами ваших серверов, потому что это та точка, где вы подтверждаете, что клиентское приложение разрешено.

Как и в случае с токенами доступа и обновления в дальнейшем.

Для входа в систему (точки A и B) - это нормально, если в форме входа указан URL-адрес перенаправления (и состояние клиента - см. Раздел 4.1). Если это единственное место, где используется сеанс, вы можете избавиться от него. Но для кода авторизации вам по-прежнему потребуется разделяемая память (общая база данных).

+0

Привет, Алекс, вы дали описание потока OAuth2, но не ответили на мой вопрос. Извините, я не могу дать вам щедрость за это. – Jan

+0

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

+0

Хорошо, имеет смысл, я действительно сохраняю код авторизации в общей базе данных, так что часть существует. Но я хотел проверить, могу ли я избавиться от общего хранилища сеансов. – Jan

0

Это классическая проблема хранения распределенных сеансов. Прежде всего, понятия «сеанс» (идентификаторы сеанса и файлы cookie) в сочетании с «без гражданства» являются своего рода противоречием.

OAuth2 должен быть «без гражданства» делегировал среда авторизации при условии вы упорствовать первоначальный запрос ввода (включая перенаправление URL) на стороне сервера перед генерацией кода доступа.

Утечка этих сведений в файлы cookie перед получением учетных данных может быть подвергнута воздействию эксплойтов безопасности. Вы можете уменьшить риск, убедившись, что файл cookie HttpOnly (недоступен JS) и защищен (выпущен только через httpS), но я бы не рекомендовал этот подход в любом случае.

О вашей другой точке: функция памяти Spring Security, предназначенная для переноса ссылки только на учетные данные аутентификации, а не на исходные запросы auth2. Более того, сохраняемые опции (PersistentTokenBasedRememberMeServices) по умолчанию поддерживают только память (один узел) и jdbc.

Для корректировки этих параметров потребуются значительные изменения. Разумное, но требует больших усилий.

В моем опыте, есть два варианта, что приходит на ум:

  1. Настройка липких сессии с помощью балансировки нагрузки на переднюю (например: HAProxy, Nginx, F5, и т.д ...). Сеанс пользователя будет привязан к узлу, где учетные данные будут отправлены. Импликация заключается в том, что если этот узел опускается; пользователь должен будет повторно аутентифицироваться для создания новых токенов доступа, но указанные токены доступа должны быть точными, если они используются против других узлов.

  2. Настроить/внедрить прозрачное хранилище распределенных веб-сеансов. Некоторые поставщики распределенной памяти (например, hazelcast) предлагают plugins, которые настроены на серверы приложений, чтобы сделать это прозрачным для пользователя. В этом есть некоторые дополнительные накладные расходы, но почти нет дополнительного кода, необходимого для удовлетворения ваших требований.

Смежные вопросы