Проблема входа через OAuth

Вопрос или проблема

Я работаю с микросервисной архитектурой, где моя API-GATEWAY работает на порту 9090, а сервис входа работает на порту 8082.
Итак, проблема в следующем: когда я пытаюсь аутентифицироваться с помощью Google OAuth, запрос корректно передается в сервис входа, но сервис входа рассматривает его как статический ресурс для этого URL-адреса входа Google OAuth.

package com.example.login.Security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import com.example.login.Service.CustomUserService;
import com.example.login.oauth.config.OAuth2LoginFailureHandler;
import com.example.login.oauth.config.OAuth2LoginSuccessHandler;

import jakarta.servlet.http.HttpServletRequest;

@Configuration
public class AppConfig {

    @Autowired
    private JwtAuthenticationEntryPoint authenticationEntryPoint;

    @Autowired
    private JwtTokenValidattor jwtTokenValidator;

    @Autowired
    private CustomUserService customUserService;

    @Autowired
    private OAuth2LoginSuccessHandler oAuth2LoginSuccessHandler;
    @Autowired
    private OAuth2LoginFailureHandler oAuth2LoginFailureHandler;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;
    private final String[] PUBLIC_URL = { "/login/jwt", "/login/register", "/login/api/payment/create",
            "/login/api/payment/update", "/swagger-ui.html", "/swagger-ui/**", "/v3/api-docs/**", "/user/fetch/qrdata",
            "/oauth2/**", "/login/oauth2/**", "/login/oauth2/authorization/google" };

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.cors(Customizer.withDefaults()).csrf(csrf -> csrf.disable())
                .authorizeHttpRequests(
                        (auth) -> auth.requestMatchers(PUBLIC_URL).permitAll().anyRequest().authenticated())
                .oauth2Login(oauth -> oauth.successHandler(oAuth2LoginSuccessHandler)
                        .failureHandler(oAuth2LoginFailureHandler))
                .exceptionHandling((ex) -> ex.authenticationEntryPoint(this.authenticationEntryPoint))
                .sessionManagement((s) -> s.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
        http.authenticationProvider(authenticationProvider());
        http.addFilterBefore(this.jwtTokenValidator, UsernamePasswordAuthenticationFilter.class);
        http.addFilterBefore((request, response, chain) -> {
            if (request instanceof HttpServletRequest) {
                HttpServletRequest httpRequest = (HttpServletRequest) request;
                System.out.println("URL запроса : " + httpRequest.getRequestURI());

            }
            chain.doFilter(request, response);
        }, UsernamePasswordAuthenticationFilter.class);
        DefaultSecurityFilterChain defaultSecurityFilterChain = http.build();
        return defaultSecurityFilterChain;
    }

    @Bean
    public AuthenticationManager authenticationManagerBean(AuthenticationConfiguration authenticationConfiguration)
            throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setUserDetailsService(this.customUserService);
        daoAuthenticationProvider.setPasswordEncoder(passwordEncoder);
        return daoAuthenticationProvider;
    }

    @Bean
    public OidcUserService oidService() {
        return new OidcUserService();
    }
}
package com.example.login.oauth.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;

import com.example.login.Security.JWTConstant;

@Configuration
public class OAuth2ClientConfig {

    @Value("${app.base-url}") 
    private String baseUrl;

    @Bean
    public ClientRegistrationRepository clientRegistrationRepository() {
        return new InMemoryClientRegistrationRepository(this.googleClientRegistration());
    }

    private ClientRegistration googleClientRegistration() {
        return ClientRegistration.withRegistrationId(JWTConstant.GOOGLE_REGISTRATION_ID)
                .clientId(JWTConstant.GOOGLE_CLIENT_ID)
                .clientSecret(JWTConstant.GOOGLE_CLIENT_SECRET)
                .redirectUri(baseUrl + JWTConstant.GOOGLE_REDIRECT_URI_SUFFIX)
                .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
                .scope(JWTConstant.GOOGLE_SCOPE)
                .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_POST)
                .authorizationUri(JWTConstant.GOOGLE_AUTHORISATION_URL)
                .tokenUri(JWTConstant.GOOGLE_TOKEN_URI)
                .userInfoUri(JWTConstant.GOOGLE_USER_INFO_URI)
                .userNameAttributeName(JWTConstant.ATTRIBUTE_NAME)
                .clientName(JWTConstant.GOOGLE_CLIENT_NAME)
                .build();
    }
}
Выше я поделился всей конфигурацией oauth и конфигурацией безопасности, где я правильно включил вход с помощью oauth2, но все равно сталкиваюсь с проблемой, которая ниже---->
URL запроса : /login/oauth2/authorization/google
2024-10-08T16:42:54.705+05:30 DEBUG 21452 --- [login-service] [nio-8082-exec-2] o.s.web.servlet.DispatcherServlet        : GET "/login/oauth2/authorization/google", параметры={}
2024-10-08T16:42:54.717+05:30 DEBUG 21452 --- [login-service] [nio-8082-exec-2] o.s.w.s.handler.SimpleUrlHandlerMapping  : Сопоставлено с ResourceHttpRequestHandler [classpath [META-INF/resources/], classpath [resources/], classpath [static/], classpath [public/], ServletContext [/]]
2024-10-08T16:42:54.732+05:30 DEBUG 21452 --- [login-service] [nio-8082-exec-2] o.s.w.s.r.ResourceHttpRequestHandler     : Ресурс не найден
2024-10-08T16:42:54.737+05:30 DEBUG 21452 --- [login-service] [nio-8082-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Разрешено [org.springframework.web.servlet.resource.NoResourceFoundException: No static resource login/oauth2/authorization/google.]
2024-10-08T16:42:54.738+05:30 DEBUG 21452 --- [login-service] [nio-8082-exec-2] o.s.web.servlet.DispatcherServlet        : Завершено 404 NOT_FOUND

Ответ или решение

Проблема, с которой вы столкнулись, заключается в том, что Spring Security не обрабатывает ваш запрос на аутентификацию через Google OAuth как ожидается, а вместо этого воспринимает его как запрос на статический ресурс. Вот несколько шагов, которые помогут вам решить эту проблему.

1. Убедитесь, что правильные URL-адреса разрешены

В вашем конфигурационном классе безопасности (AppConfig), вы указали массив PUBLIC_URL, который включает паттерны, связанные с OAuth2. Убедитесь, что в этом массиве прописан корректный путь:

private final String[] PUBLIC_URL = {
    "/login/jwt", 
    "/login/register", 
    "/login/api/payment/create",
    "/login/api/payment/update", 
    "/swagger-ui.html", 
    "/swagger-ui/**", 
    "/v3/api-docs/**", 
    "/user/fetch/qrdata",
    "/oauth2/**",   // Убедитесь, что этот паттерн тут
    "/login/oauth2/**", // Это тоже должно быть
    "/login/oauth2/authorization/google" // И это тоже
};

2. Настройте маршрутизацию запросов

Вам необходимо убедиться, что ваши запросы поступают в нужный контроллер, а не обрабатываются как статические ресурсы. Для этого добавьте в код мэппинг для обработки запросов OAuth:

http.authorizeHttpRequests(auth -> 
    auth.requestMatchers(PUBLIC_URL).permitAll()
        .anyRequest().authenticated()
);

Эта часть кода должна быть corretamente настроена, чтобы разрешить доступ к /login/oauth2/authorization/google.

3. Настройте контроллеры для обработки запросов

Если запросы все еще обрабатываются неправильно, убедитесь, что у вас существует контроллер, который может обрабатывать эти запросы. Если вы используете Spring Security с OAuth2, вы можете использовать стандартный механизм, предоставляемый Spring, чтобы обрабатывать OAuth2 запросы. Например:

@RestController
@RequestMapping("/login")
public class LoginController {

    @GetMapping("/oauth2/authorization/google")
    public String redirectGoogle() {
        // Логика для обработки редиректа
        return "redirect:/oauth2/authorization/google";
    }
}

4. Проверьте настройки Redirection URL

В конфигурации OAuth у вас есть следующее:

.redirectUri(baseUrl + JWTConstant.GOOGLE_REDIRECT_URI_SUFFIX)

Убедитесь, что JWTConstant.GOOGLE_REDIRECT_URI_SUFFIX корректен и совпадает с тем, что вы указали в консоли разработчика Google.

5. Логи и отладка

Если после всех настроек проблема остается, просмотрите логи более детально. Возможно, что сервер не видит ваши настройки или есть какой-то конфликт с другими конфигурациями. Включите режим отладки, чтобы посмотреть, как Spring обрабатывает входящие запросы.

Вы можете добавить следующее в ваш файл application.properties:

logging.level.org.springframework=DEBUG

6. Зависимости и версии

Также проверьте, что версии ваших зависимостей Spring Boot и Spring Security соответствуют друг другу и поддерживают функциональность, которую вы используете.

Заключение

Эти шаги должны помочь вам устранить проблему с обработкой запросов OAuth2 в вашем сервисе аутентификации. Если проблема все еще не решена, вам может понадобиться предоставить больше информации о конфигурации вашего приложения и любые связанные запросы, которые вы делаете.

Оцените материал
Добавить комментарий

Капча загружается...