Как стать автором
Обновить

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

Как вы наверное уже догадываетесь, для отключения авторизации нужно всего лишь в такой функции вернуть true.

Аутентификации. Авторизация - это другое

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

Для тестовой среды можно завести отдельный spring profile, скажем, "test_staging", для которого будет создаваться primary bean PasswordEncoder с нужной функциональностью, а чтобы код не утёк в прод, для maven, хранить подобные небезопасные конфиги в src/main/test, падать при обнаружении prod-профилия, рисовать staging-баннер в UI или ещё что-нибудь.

Но ещё более прямым способом, нежели создание своего PasswordEncoder, мне видится для тестового окружения через обычный security-конфиг добавлять тестового пользователя с обычным DelegatingPasswordEncoder: .withUser("test_admin").password("{noop}complex_password_@123!"). И в коде подсмотреть можно, и запомнить в браузере один раз труда не составит.

  1. История с профилями заканчивается на моменте использования чужого решения. Врядли получится поиграться с профилями в чужом закрытом проекте, даже если там тоже используется Spring.

  2. Профили это плохо, поскольку у вас начнут отличаться среды выполнения для теста и продакшна. Что означает например возможность получить невоспроизводимые ошибки - на проде есть, на тесте не воспроизводится.

Они у вас и так отличаются, только завуалированным, неочевидным методом, который, может поломать сторонний код. Может, кому-то в проекте нужен bean BCryptPasswordEncoder для взаимодействия по API, а вы ему такую свинью подкладываете: локально работает, а на staging ломается и почему непонятно.

Понимаю что вам очень хочется обвинить меня в некомпентности, но увы:

  1. Это абсолютно рабочее решение, которое используется уже 10 лет на своих и чужих проектах, которые через нас проходят. И каких-либо проблем до сих пор не было.

  2. Реализация подменяется не в каком-то одном BCryptPasswordEncoder а во всех, включая кастомные (если они присутствуют в проекте)

Так что все с этим проектом хорошо, рекомендую к использованию.

И ещё, className.contains("org/springframework/security/") && className.endsWith("Encoder") никуда не годится, проверка наследования через рефлексию делается методом isAssignableFrom

Это не сработает в окружении JavaAgent, поскольку код агента отделен от кода приложения - т.е нет import org.springframework.security.PasswordEncoder.

Class.forName же

нет, поскольку на этой стадии еще нет загрузки класса - это делает JVM.

Т.е Вы предлагаете как решение: пускать на тестовый стенд по plain аутентификации кого угодно. Окей, почему тогда не реврайтить запрос через nginx на admin/admin? Те же яйца только проще. Не говоря уже о том, что plain аутентификация в настоящее время повсеместно заменяется Oauth SSO и ваше решение никак не поможет уйти от тестовых учеток/ролей/групп.

  1. Самая главная проблема что уже достаточно давно нет возможности сделать «admin/admin» даже для тестов — теперь все хотят сложные пароли. И разумеется никакой nginx не поможет из‑за CSRF проверок.

  2. Для OAuth/SSO все тоже самое, просто отключение проверки пароля происходит на стороне OAuth сервера, после чего он спокойно авторизует клиентов. Проверено.

А если OAuth/SSO провайдер один для всех окружений? Или вообще сторонний, вроде Google/Github

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

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

Но отвечая на ваш вопрос: да, это тоже решаемо — эмуляцией такого провайдера своим тестовым.

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

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории