#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")
вопрос:
- Я предполагаю, что XML и программные конфигурации должны быть эквивалентны. Таким образом, я предполагаю, что есть способ избежать ввода пароля в учетные записи пользователей в памяти. Это правильно?
- Предполагая, что вышесказанное верно, как мне это сделать? Не могли бы вы привести пример для всего метода?
Я понимаю, что это, вероятно, тривиальный вопрос. Я легко прогуглил и просмотрел 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. Система защиты от ошибок при развертывании.
Этого описания должно быть достаточно, но дайте мне знать, если кому-нибудь понадобится более подробное объяснение какого-либо из шагов.