Обновлено: Эта проблема оказалась ошибкой пользователя, пароли были изменены, поэтому хэш никогда не совпадал.
Я использую простую аутентификацию в наборе инструментов Spring 4.2.2, используя DAO, который считывает таблицу базы данных (Postgres) для имени пользователя, пароля и полномочий.
@EnableWebSecurity
@Configuration
class X extends WebSecurityConfigurerAdapter{
...
@Autowired
private SessionRegistry sessionRegistry;
@Autowired
private SessionAuthenticationStrategy sessionAuthenticationStrategy;
@Override
protected void configure(HttpSecurity http){
http.sessionManagement().sessionAuthenticationStrategy(sessionAuthenticationStrategy).maximumSessions(1).sessionRegistry(sessionRegistry).expiredUrl("/login.jsp");
//presumably unrelated additional code related to matchers, roles, https
}
@Bean
public SessionRegistry sessionRegistry(){
return new SessionRegistryImpl();
}
@Bean
public SessionAuthenticationStrategy sessionAuthenticationStrategy(){
return new ConcurrentSessionControlAuthenticationStrategy(sessionRegistry);
}
@Bean
public PasswordEncoder passwordEncoder(){
return new StandardPasswordEncoder();
}
...
}
Недавно я восстановил старую копию базы данных, старая база данных взята с сервера Redhat 6, новая — CentOS 7, хотя на самом деле, поскольку все это поддерживается базой данных, это не должно иметь значения. Часть аутентификации нашего кода совсем не изменилась, но поскольку я восстановил базу данных, несмотря на ввод правильных учетных данных, я получаю
BadCredentialsException: Bad credentials at
org.springframework.security.authentication.dao.DaoAuthenticationProvider.additionalAuthenticationChecks(DaoAuthenticationProvider.java:98) at
org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:165) at org.springframework.security.authentication.ProvideManager.authenticate(ProviderManager.java:167) at
....
Остальная часть трассировки стека - это все более стандартные биты трассировки стека spring/catalina/java, ничего нестандартного.
Он не просрочен, я удалил куки, он не отключен....
Этот код не изменился буквально за несколько лет, равно как и таблицы резервной базы данных или библиотеки Spring. Отладка Я могу подтвердить, что правильный пользователь извлекается по имени пользователя, поскольку он идет к аутентификации, что объект пользователя правильно создан с хэшем пароля и полномочиями. Поскольку большая часть этого выполняется поведением классов Spring по умолчанию, я не могу пройти через большую часть кода, как это происходит, поэтому очень сложно определить, где произошли фактические неверные учетные данные и что, черт возьми, могло измениться.
Погуглив, я обнаружил, что у многих пользователей есть проблемы, но почти все они имеют дело с изначально плохой конфигурацией. Это не такая уж проблема, так как этот код работал.
Есть ли какие-либо известные ошибки, связанные с безопасностью Spring, которые я мог бы проверить?
В противном случае, как я могу сортировать это дальше?
@Catchwa хорошая мысль, Postgres для протокола, я отредактирую, как только вернусь к клавиатуре
Еще несколько вещей, чтобы попробовать:
DaoAuthenticationProvider
, который позволяет вам установить точку останова (или просто записывать в консоль/файл) сгенерированный хэш пароля по сравнению с базой данных.StandardPasswordEncoder
(из здесь), но снова добавьте больше логов/брейкпойнтовО боже, я надеюсь, что это не так неприятно, как изменение кодировки символов по умолчанию между двумя младшими версиями базы данных, но это хорошая мысль.
Подтверждено, что и старый, и новый находятся в UTF-8, так что это не простая проблема с кодировкой.
Воссоздание пользователя действительно помогло, но, к сожалению, это нежизнеспособный вариант, потому что каскадное удаление сдуло слишком много его исходных данных.
Включив себя в процесс, он, кажется, терпит неудачу, потому что он отклоняет хэш, но, к сожалению, я не понимаю, почему. Я предполагаю, что это как-то связано с солью, но мне непонятно, почему это было бы правдой, поскольку я думал, что используемая соль была добавлена как последние несколько байтов хэш-кода.
Я предлагаю создать собственную версию StandardPasswordEncoder
и добавить больше элементов отладки/логирования: github.com/spring-projects/spring-security/blob/4.2.x/crypto/…
Я почти уверен, что на данный момент я определил проблему, к сожалению. Я почти уверен, что StandardPasswordEncoder имеет «секретную» последовательность байтов, специфичную для сервера.
Вы можете посмотреть код, на который я ссылаюсь - конструктор без аргументов приводит к пустому секрету
обернув StandardPasswordEncoder в пользовательский класс (он окончательный, поэтому я не могу его расширить), я смог определить, что секрет на самом деле представляет собой массив байтов нулевой длины. Он использует Springframework Digester, который довольно скучен, поскольку классы идут, я действительно не уверен, как дальше отлаживать....
Вероятно, это не поможет, но я имел в виду просто скопировать весь файл StandardPasswordEncoder
, поместить его в ваше приложение локально, а затем отредактировать его так, как вы хотите. Это дало бы вам неограниченную возможность входа в систему, где бы вы ни захотели.
Во-первых, большое спасибо за все ваше время и помощь. Как оказалось, они изменили пароли пользователя-администратора, и хеш должен законно не совпадать, потому что они не сказали мне, что мои учетные данные были НЕПРАВИЛЬНЫМИ. Так что я копал кроличью нору без дна.
Может быть полезно упомянуть продукт базы данных - например. MySQL, PostgreSQL и др.