Spring Security Programmatic в памяти UserDetailsService: имя пользователя и роли, БЕЗ пароля
РЕЗЮМЕ
Со старым SpringSecurity.xml мне никогда не нужно было предоставлять пароль для поддержки дополнительных ролей через userDetailsService в памяти. Это было очень удобно, особенно на этапе разработки.
При программном подходе легко предоставить имя пользователя + пароль + роли, но неясно, как предоставить только имя пользователя + роли. Я хотел бы узнать, как это сделать.
ПРИМЕРЫ
В приведенных ниже примерах «пользователь» выполняет аутентификацию и авторизацию в Active Directory через adAuthProvider. Программные примеры представляют собой полное содержание метода настройки SecurityConfig (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.Filter]: заводской метод '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")
ВОПРОС:
- Я предполагаю, что XML и программные конфигурации должны быть эквивалентны. Таким образом, я предполагаю, что есть способ избежать передачи пароля пользователю userDetails в памяти. Это верно?
- Предполагая, что вышесказанное верно, как мне это сделать? Не могли бы вы привести пример всего метода?
Я понимаю, что это, наверное, банальный вопрос. Я погуглил и легко просмотрел 100 примеров, но все они включают пароль. Ни один из них не показал, как использовать in-memory только для авторизации - полагаясь на провайдер аутентификации Active Directory для проверки пароля.
1 ответ
Надеюсь, следующее поможет следующему гуглеру решить мою проблему.
Во-первых, моя благодарность Дейнуму, он заставил меня думать в правильном направлении.
Простое добавление фиктивного пароля в код исходного сообщения не сработало, но это сработало даже лучше для моих нужд:
- Я уже использовал собственный AuthenticationProvider. Было легко разместить и прочитать дополнительные роли для пользователей из значения в файле свойств с синтаксисом JSON: springsecurity.extraRoles=[{"username":"usernameValue", "roles":["ROLE_XTRA1", "ROLE_XTRA2"]}].
- Дополнительные роли редко меняются, поэтому они считываются в статическую карту и добавляются к ролям пользователей, полученным из AD как часть процесса Authenticate().
- И поскольку у меня уже было свойство deploy.environment=DEV, я использовал его для отключения механизма в PROD. Защитная сетка от ошибок при развертывании.
Этого описания должно быть достаточно, но дайте мне знать, если кому-то понадобится более подробное объяснение любого из шагов.