Как я могу настроить сервер аутентификации Spring OAuth2, чтобы он действовал как сервер аутентификации, так и сервер ре ⇐ JAVA
Как я могу настроить сервер аутентификации Spring OAuth2, чтобы он действовал как сервер аутентификации, так и сервер ре
В настоящее время я работаю над системой входа/управления пользователями OAuth 2.0 с использованием Spring Security. Поскольку я пишу свой собственный сервер авторизации (на основе таких документов, как здесь), используя модуль spring-security-oauth2-authorization-server, я также реализую панель управления пользователями/администрирования. Естественно, конечные точки управления пользователями находятся на сервере аутентификации. Таким образом, сервер аутентификации действует как сервер авторизации и (что-то вроде) сервера ресурсов. Чтобы авторизовать пользователя на использование панели администратора, ему, конечно, необходимо войти в систему, поэтому сначала он перенаправляется на конечную точку сервера аутентификации /authorize, которая затем перенаправляет его в меню входа в систему. Затем поток предоставления кода авторизации выполняется обычным образом. Но каждый шаг выполняется на одном и том же сервере (т. е. аутентификация и доступ к защищенным конечным точкам администратора)!
Я изо всех сил пытаюсь настроить наш сервер аутентификации для работы в качестве сервера аутентификации И сервера ресурсов из-за следующих проблем:
Сервер авторизации сохраняет securityContext в сеансе. Идентификатор сеанса (JSESSIONID) затем сохраняется в браузере пользователя в виде файла cookie. Проблема в том, что когда пользователь пытается получить доступ к защищенной конечной точке на сервере аутентификации, такой как конечная точка {...}/admin/users, одного файла cookie достаточно, чтобы авторизовать его для выполнения запроса. до этой конечной точки. Это означает, что можно обойти весь поток авторизации, когда сначала необходимо запросить токен носителя для доступа к защищенной конечной точке. Нам бы хотелось, чтобы защищенные конечные точки были доступны ТОЛЬКО с помощью токена носителя и только токена носителя, а не сеанса (или их комбинации).
Вот сокращенная версия текущей конфигурации безопасности:
@Bean @Заказ(1) public CorsFilter corsFilter (CorsConfigurationSource corsConfigurationSource) { logger.info("Создание bean-компонента corsFilter"); вернуть новый CorsFilter(corsConfigurationSource); } /** * Настраивает конечные точки сервера авторизации. */ @Бин @Заказ(2) public SecurityFilterChain авторизацияServerSecurityFilterChain(HttpSecurity http, RegisteredClientRepository clientRepository) выдает исключение { OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); http.getConfigurer(OAuth2AuthorizationServerConfigurer.class) .registeredClientRepository(clientRepository) // автоматически подключается из ClientConfig.java .oidc(Customizer.withDefaults()); http.ExceptionHandling((исключения) -> исключения .defaultAuthenticationEntryPointFor( новый LoginUrlAuthenticationEntryPoint("/login"), новый MediaTypeRequestMatcher(MediaType.TEXT_HTML) ) ); http.oauth2ResourceServer((resourceServer) -> resourcesServer .jwt(Customizer.withDefaults())); http.csrf(AbstractHttpConfigurer::disable); вернуть http.build(); } @Бин @Заказ(3) public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) выдает исключение { http.securityMatcher(new NegatedRequestMatcher(new AntPathRequestMatcher("/admin/**"))); http.authorizeHttpRequests((авторизовать) -> разрешать .requestMatchers(новый AntPathRequestMatcher("/register")).permitAll() .requestMatchers(новый AntPathRequestMatcher("/recover")).permitAll() .requestMatchers(новый AntPathRequestMatcher("/error/**")).permitAll() .requestMatchers(новый AntPathRequestMatcher("/css/**")).permitAll() .requestMatchers(новый AntPathRequestMatcher("/js/**")).permitAll() .requestMatchers(новый AntPathRequestMatcher("/favicon.ico")).permitAll() .anyRequest().аутентифицированный()); http.oauth2ResourceServer((resourceServer) -> resourcesServer .jwt(Customizer.withDefaults())); // устанавливаем пользовательскую форму входа http.formLogin(форма -> { form.loginPage("/login"); форма.permitAll(); }); http.logout(conf -> { // URL выхода из системы по умолчанию conf.logoutSuccessHandler(logoutSuccessHandler()); }); http.csrf(AbstractHttpConfigurer::disable); http.cors(AbstractHttpConfigurer::disable); вернуть http.build(); } @Бин @Заказ(4) public SecurityFilterChain adminResourceFilterChain(HttpSecurity http) выдает исключение { // обрабатываем пользовательские конечные точки в этой цепочке фильтров http.authorizeHttpRequests((авторизовать) -> разрешать .requestMatchers(новый AntPathRequestMatcher("/admin/**")).hasRole("ADMIN") .anyRequest().аутентифицированный()); http.sessionManagement(conf -> conf.sessionCreationPolicy(SessionCreationPolicy.STATELESS)); http.oauth2ResourceServer((resourceServer) -> resourcesServer .jwt(Customizer.withDefaults())); http.csrf(AbstractHttpConfigurer::disable); http.cors(AbstractHttpConfigurer::disable); вернуть http.build(); } Как настроить сервер авторизации, чтобы конечные точки администратора были защищены независимо от контекста безопасности сеанса?
Для целей раскрытия информации я много отлаживал и попробовал практически все основы! Я также попробовал еще несколько вещей:
Согласно документации Spring Security, в конфигурации безопасности для .sessionManagement можно установить значение STATELESS. Я надеялся, что это решит проблему, но установка этого параметра в цепочке фильтров сервера ресурсов привела к другой проблеме: если для флага управления сеансом установлено значение STATELESS, вход в систему не обрабатывается должным образом. После запроса POST из формы входа вместо перенаправления на «redirect_url» из запроса /authorize сервер аутентификации перенаправляет на «/»…? Я думаю, это связано с тем, что модуль сервера аутентификации использует для некоторых своих фильтров контекст безопасности, сохраненный в сеансе.
У меня также были некоторые проблемы с CORS, и я подумал, что это может вызвать это. Учитывая, что в документации сказано:
CORS должен быть обработан до Spring Security, поскольку предварительный запрос не будет содержать никаких файлов cookie (т. е. JSESSIONID). Если запрос не содержит файлов cookie и Spring Security стоит первым, запрос определит, что пользователь не аутентифицирован (поскольку в запросе нет файлов cookie), и отклонит его.
Это объясняет, что интерфейсное приложение Vue.js работает неправильно, но не вызовы отладки через Postman. Теперь я деактивировал CORS, чтобы не решать эти проблемы.
В настоящее время я работаю над системой входа/управления пользователями OAuth 2.0 с использованием Spring Security. Поскольку я пишу свой собственный сервер авторизации (на основе таких документов, как здесь), используя модуль spring-security-oauth2-authorization-server, я также реализую панель управления пользователями/администрирования. Естественно, конечные точки управления пользователями находятся на сервере аутентификации. Таким образом, сервер аутентификации действует как сервер авторизации и (что-то вроде) сервера ресурсов. Чтобы авторизовать пользователя на использование панели администратора, ему, конечно, необходимо войти в систему, поэтому сначала он перенаправляется на конечную точку сервера аутентификации /authorize, которая затем перенаправляет его в меню входа в систему. Затем поток предоставления кода авторизации выполняется обычным образом. Но каждый шаг выполняется на одном и том же сервере (т. е. аутентификация и доступ к защищенным конечным точкам администратора)!
Я изо всех сил пытаюсь настроить наш сервер аутентификации для работы в качестве сервера аутентификации И сервера ресурсов из-за следующих проблем:
Сервер авторизации сохраняет securityContext в сеансе. Идентификатор сеанса (JSESSIONID) затем сохраняется в браузере пользователя в виде файла cookie. Проблема в том, что когда пользователь пытается получить доступ к защищенной конечной точке на сервере аутентификации, такой как конечная точка {...}/admin/users, одного файла cookie достаточно, чтобы авторизовать его для выполнения запроса. до этой конечной точки. Это означает, что можно обойти весь поток авторизации, когда сначала необходимо запросить токен носителя для доступа к защищенной конечной точке. Нам бы хотелось, чтобы защищенные конечные точки были доступны ТОЛЬКО с помощью токена носителя и только токена носителя, а не сеанса (или их комбинации).
Вот сокращенная версия текущей конфигурации безопасности:
@Bean @Заказ(1) public CorsFilter corsFilter (CorsConfigurationSource corsConfigurationSource) { logger.info("Создание bean-компонента corsFilter"); вернуть новый CorsFilter(corsConfigurationSource); } /** * Настраивает конечные точки сервера авторизации. */ @Бин @Заказ(2) public SecurityFilterChain авторизацияServerSecurityFilterChain(HttpSecurity http, RegisteredClientRepository clientRepository) выдает исключение { OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); http.getConfigurer(OAuth2AuthorizationServerConfigurer.class) .registeredClientRepository(clientRepository) // автоматически подключается из ClientConfig.java .oidc(Customizer.withDefaults()); http.ExceptionHandling((исключения) -> исключения .defaultAuthenticationEntryPointFor( новый LoginUrlAuthenticationEntryPoint("/login"), новый MediaTypeRequestMatcher(MediaType.TEXT_HTML) ) ); http.oauth2ResourceServer((resourceServer) -> resourcesServer .jwt(Customizer.withDefaults())); http.csrf(AbstractHttpConfigurer::disable); вернуть http.build(); } @Бин @Заказ(3) public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) выдает исключение { http.securityMatcher(new NegatedRequestMatcher(new AntPathRequestMatcher("/admin/**"))); http.authorizeHttpRequests((авторизовать) -> разрешать .requestMatchers(новый AntPathRequestMatcher("/register")).permitAll() .requestMatchers(новый AntPathRequestMatcher("/recover")).permitAll() .requestMatchers(новый AntPathRequestMatcher("/error/**")).permitAll() .requestMatchers(новый AntPathRequestMatcher("/css/**")).permitAll() .requestMatchers(новый AntPathRequestMatcher("/js/**")).permitAll() .requestMatchers(новый AntPathRequestMatcher("/favicon.ico")).permitAll() .anyRequest().аутентифицированный()); http.oauth2ResourceServer((resourceServer) -> resourcesServer .jwt(Customizer.withDefaults())); // устанавливаем пользовательскую форму входа http.formLogin(форма -> { form.loginPage("/login"); форма.permitAll(); }); http.logout(conf -> { // URL выхода из системы по умолчанию conf.logoutSuccessHandler(logoutSuccessHandler()); }); http.csrf(AbstractHttpConfigurer::disable); http.cors(AbstractHttpConfigurer::disable); вернуть http.build(); } @Бин @Заказ(4) public SecurityFilterChain adminResourceFilterChain(HttpSecurity http) выдает исключение { // обрабатываем пользовательские конечные точки в этой цепочке фильтров http.authorizeHttpRequests((авторизовать) -> разрешать .requestMatchers(новый AntPathRequestMatcher("/admin/**")).hasRole("ADMIN") .anyRequest().аутентифицированный()); http.sessionManagement(conf -> conf.sessionCreationPolicy(SessionCreationPolicy.STATELESS)); http.oauth2ResourceServer((resourceServer) -> resourcesServer .jwt(Customizer.withDefaults())); http.csrf(AbstractHttpConfigurer::disable); http.cors(AbstractHttpConfigurer::disable); вернуть http.build(); } Как настроить сервер авторизации, чтобы конечные точки администратора были защищены независимо от контекста безопасности сеанса?
Для целей раскрытия информации я много отлаживал и попробовал практически все основы! Я также попробовал еще несколько вещей:
Согласно документации Spring Security, в конфигурации безопасности для .sessionManagement можно установить значение STATELESS. Я надеялся, что это решит проблему, но установка этого параметра в цепочке фильтров сервера ресурсов привела к другой проблеме: если для флага управления сеансом установлено значение STATELESS, вход в систему не обрабатывается должным образом. После запроса POST из формы входа вместо перенаправления на «redirect_url» из запроса /authorize сервер аутентификации перенаправляет на «/»…? Я думаю, это связано с тем, что модуль сервера аутентификации использует для некоторых своих фильтров контекст безопасности, сохраненный в сеансе.
У меня также были некоторые проблемы с CORS, и я подумал, что это может вызвать это. Учитывая, что в документации сказано:
CORS должен быть обработан до Spring Security, поскольку предварительный запрос не будет содержать никаких файлов cookie (т. е. JSESSIONID). Если запрос не содержит файлов cookie и Spring Security стоит первым, запрос определит, что пользователь не аутентифицирован (поскольку в запросе нет файлов cookie), и отклонит его.
Это объясняет, что интерфейсное приложение Vue.js работает неправильно, но не вызовы отладки через Postman. Теперь я деактивировал CORS, чтобы не решать эти проблемы.
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Как сделать так, чтобы четвертый ряд изображений действовал как первые 3 ряда?
Anonymous » » в форуме Html - 0 Ответы
- 6 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Как сделать так, чтобы четвертый ряд изображений действовал как первые 3 ряда?
Anonymous » » в форуме CSS - 0 Ответы
- 1 Просмотры
-
Последнее сообщение Anonymous
-