Программное обеспечение безопасности Spring в памяти UserDetailsService: имя пользователя и роли, БЕЗ пароля

#java #spring #security #authorization #programmatic-config

Вопрос:

ОБНОВЛЕНИЕ: Я не смог решить проблему, представленную здесь, но самым простым и эффективным решением моей проблемы было НЕ использовать службу UserDetailsService в памяти. Подробная информация о моем полученном решении содержится в последующем посте.


Краткие сведения

Со старым SpringSecurity.xml Мне никогда не нужно было вводить пароль для поддержки дополнительных ролей через службу UserDetailsService в памяти. Это было очень удобно, особенно на этапе разработки.

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

примеры

В приведенных ниже примерах «пользователь» выполняет аутентификацию и авторизацию в Active Directory через adAuthProvider. Программные примеры представляют собой полное содержание метода SecurityConfig configure(AuthenticationManagerBuilder auth).

security.xml: (это работало годами, то, что я хочу повторить)

   <sec:user-service id="xmlUserDetailsService">
    <sec:user name="user" authorities="ROLE_USER" />
  </sec:user-service>
 

Неудачная программная попытка:
(прямой перевод вышесказанного, обратите внимание, что «пользователь» не устанавливает пароль… как в приведенном выше XML).
Броски при запуске сервера: (org.springframework.beans.Исключение BeanInstantiationException: Не удалось создать экземпляр [javax.servlet.Фильтр]: Фабричный метод ‘springSecurityFilterChain’ выдал исключение; вложенное исключение-java.lang.Исключение IllegalArgumentException: Невозможно передать конструктору нулевые или пустые значения)

   auth.authenticationProvider(adAuthProvider);
  auth.inMemoryAuthentication()
  .passwordEncoder(passwordEncoder)
  .withUser("user").roles("USER")
 

Успешно, добавление пароля для «пользователя»:
(исключение исчезает)

   auth.authenticationProvider(adAuthProvider);
  auth.inMemoryAuthentication()
  .passwordEncoder(passwordEncoder)
  .withUser("user").password(passwordEncoder.encode("user")).roles("USER")
 

вопрос:

  1. Я предполагаю, что XML и программные конфигурации должны быть эквивалентны. Таким образом, я предполагаю, что есть способ избежать ввода пароля в учетные записи пользователей в памяти. Это правильно?
  2. Предполагая, что вышесказанное верно, как мне это сделать? Не могли бы вы привести пример для всего метода?

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

Комментарии:

1. Они не эквивалентны XML, у которого также есть пароль, хотя он случайный. Они также отличаются тем, что XML-файл выполняет настройку InMemoryUserDetailsService , которую вы, вероятно, затем используете в своей конфигурации AD для сопоставления ролей. В вашей версии Java он настраивается полностью DaoAuthenticationProvider , в то время как вам, вероятно, все еще нужно UserDetailsService получить роли пользователей. Но чтобы исправить это, просто назначьте случайный пароль, такой же, как в XML.

2. Ty Deinum. Вы правы, что в XML информация предоставляется через службу UserDetailsService, хотя поле пароля было необязательным, а не обязательным, как в поставщике программной аутентификации. Я не видел программного примера того, как настроить службу UserDetailsService отдельно от поставщика проверки подлинности, но, вероятно, смогу его найти. Знаете ли вы, является ли в программном сервисе UserDetailsService пароль необязательным, как в XML? Или это было бы напрасным усилием? Имейте в виду, что я намерен выполнить аутентификацию и большую часть авторизации в AD, несколько ролей в svc.

3. Пароль не является необязательным для пользователя, но в XML, если он не указан, генерируется случайный пароль. Поэтому просто назначьте случайный (или дымный) пароль при создании InMemoryUserDetailsService .

Ответ №1:

Я надеюсь, что следующее поможет следующему гуглеру решить мою проблему.

Во-первых, моя благодарность Дейну, он заставил меня думать в правильном направлении.

Простое добавление с использованием фиктивного пароля в код исходного сообщения не сработало, но это сработало еще лучше для моих нужд:

  • Я уже использовал пользовательский поставщик аутентификации. Было легко разместить и прочитать дополнительные роли для пользователей из значения в файле свойств с синтаксисом JSON: springsecurity.extraRoles=[{«имя пользователя»:»Значение имени пользователя», «роли»:[«ROLE_XTRA1», «ROLE_XTRA2»]}].
  • Дополнительные роли редко меняются, поэтому они считываются в статическую карту и добавляются к ролям пользователей, полученным из AD, в рамках процесса аутентификации ().
  • И поскольку у меня уже было свойство deploy.environment=DEV, я использовал его, чтобы отключить механизм в PROD. Система защиты от ошибок при развертывании.

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