개발지식/트러블슈팅

스프링 시큐리티 소셜로그인 무한 리디렉션, successHandler 작동이 안되는 문제

다오__ 2024. 3. 9. 03:18

1.무한 리디렉션

2024-03-08T15:50:10.416+09:00 DEBUG 1740 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : Securing GET /
2024-03-08T15:50:10.424+09:00 DEBUG 1740 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : Secured GET /
2024-03-08T15:50:10.441+09:00 DEBUG 1740 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : Securing GET /index.html 
2024-03-08T15:50:10.442+09:00 DEBUG 1740 --- [nio-8080-exec-1] o.s.s.w.a.AnonymousAuthenticationFilter  : Set SecurityContextHolder to anonymous SecurityContext
2024-03-08T15:50:10.479+09:00 DEBUG 1740 --- [nio-8080-exec-1] o.s.s.w.s.HttpSessionRequestCache        : Saved request http://localhost:8080/index.html?continue to session
2024-03-08T15:50:10.480+09:00 DEBUG 1740 --- [nio-8080-exec-1] o.s.s.web.DefaultRedirectStrategy        : Redirecting to http://localhost:8080/auth/login
Securing GET /favicon.ico
2024-03-08T16:07:50.411+09:00 DEBUG 12224 --- [nio-8080-exec-5] o.s.s.w.a.AnonymousAuthenticationFilter  : Set SecurityContextHolder to anonymous SecurityContext
2024-03-08T16:07:50.411+09:00 DEBUG 12224 --- [nio-8080-exec-5] o.s.s.web.DefaultRedirectStrategy        : Redirecting to http://localhost:8080/auth/login
2024-03-08T16:07:50.415+09:00 DEBUG 12224 --- [nio-8080-exec-6] o.s.security.web.FilterChainProxy        : Securing GET /auth/login
2024-03-08T16:07:50.416+09:00 DEBUG 12224 --- [nio-8080-exec-6] o.s.security.web.FilterChainProxy        : Secured GET /auth/login
2024-03-08T16:07:50.420+09:00 DEBUG 12224 --- [nio-8080-exec-6] o.s.s.w.a.AnonymousAuthenticationFilter  : Set SecurityContextHolder to anonymous SecurityContext
2024-03-08T16:15:25.893+09:00 DEBUG 12224 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy        : Securing GET /static/images/kakao_login_button.png?continue

 


localhost:8080 접속 시,  .loginPage("/auth/login") 페이지로 리디렉션 되는 문제


원인 파악
정적 리소스 index.html에 접근하려고 할 때, 해당 자원에 접근이 허용되지 않아 설정에 의해 자동 리디렉션됨을 알게됨.

시도1
http.authorizeHttpRequests.requestMathcers(PathRequest.toStaticResources().atCommonLocations()).permitAll())로 정적자원에 접근하도록 허용

시도2
브라우저의 캐시 문제일수도 있다고 생각해서 브라우저의 방문 기록과 캐시를 제거

시도3
시큐리티의 세션설정을 stateless하게 설정했는데, 아직 JWT구현이 되지 않은 상태이기에 이를 해제

시도4 디렉토리 계층구조 문제인가 싶어 statc/html/index.html로 이동

시도5 
WebSecurityCustomizer를 이용, WebSecurity구성에서 직접 정적자원에 대한 보안을 해제

    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        return web -> web.ignoring().requestMatchers("/css/**", "/js/**", "/images/**", "/webjars/**", "/html");
    }

 


해결
시도5까지 진행해봤지만, 간단한 문제였던 것 같다.디렉토리 /html폴더를 지우고 다시 statc/index.html을 새로만드니 해결이 되었다. 

*혹시나 싶어, 시도한것들을 차례차례 되돌려봤는데, 왠걸? 이상없이 잘 작동한다.
시도1 까지 지웠는데,,, index.html에 잘 접속된다.. 결국 이유를 못찾은채로 해결이 되었다.

아마 index.html을 새로만드니 해결이 된걸로 보아.. 
기존에 index.html을 만들어뒀고, 그 다음에 설정을 했기 때문에, 무언가 새로고침이 안된건가? 싶다. 

앞으로는 파일을 만들고 refresh를 사용해보아야겠다.

 

 


successHandler 작동이 안되는 문제

 

                .oauth2Login(oauth2Login -> oauth2Login
                        .loginPage("/auth/login")
                        .successHandler(urlAuthenticationSuccessHandler)
                        .defaultSuccessUrl("/auth/login/success")
                        .failureUrl("/auth/login/fail")

urlAuthenticationSuccessHandler를 @Component 어노테이션을 달고 시큐리티 설정파일에서 주입받았다.

코드상으로는 몇번을 확인했기에, 이상이 없을꺼라...생각이 든다.

 

시도 1. 에서 successHandler와 defaultSuccessUrl 순서변경

시도 2 세션 STATELESS 설정을 주석처리

시도 3 캐시삭제후 재 로그인, 에러로그가 발생

org.springframework.security.web.firewall.RequestRejectedException: The request was rejected because the URL contained a potentially malicious String ";"


방화벽에서 ;문자를 막아놓은 것 같다.


시도 4 내장 톰캣 서버의 설정에서 ; 경로문자, 쿼리문자로 허용

application.properties 내부

server.tomcat.relaxed-query-chars=;
server.tomcat.relaxed-path-chars=;


시도 5 WebSecurity의 httpFireWall()을 통해 ; 허용

SecurityConfig 내부

...
    @Bean
    public HttpFirewall allowUrlEncodedSlashHttpFirewall() {
        StrictHttpFirewall firewall = new StrictHttpFirewall();
        firewall.setAllowSemicolon(true); // 세미콜론 허용
        return firewall;
    }

    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        return web -> web.httpFirewall(allowUrlEncodedSlashHttpFirewall());
    }

위의 에러로그는 해결 했다.

 

2024-03-08T21:14:22.203+09:00 DEBUG 7916 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy        : Securing GET /error
2024-03-08T21:14:22.204+09:00 DEBUG 7916 --- [nio-8080-exec-2] o.s.s.w.a.AnonymousAuthenticationFilter  : Set SecurityContextHolder to anonymous SecurityContext
2024-03-08T21:14:22.208+09:00 DEBUG 7916 --- [nio-8080-exec-2] o.s.s.w.s.HttpSessionRequestCache        : Saved request http://localhost:8080/error?continue to session
2024-03-08T21:14:22.210+09:00 DEBUG 7916 --- [nio-8080-exec-2] s.w.a.DelegatingAuthenticationEntryPoint : Trying to match using And [Not [RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]], Not [And [Or [Ant [pattern='/login'], Ant [pattern='/favicon.ico']], And [Not [RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]], MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@24dfd41c, matchingMediaTypes=[application/xhtml+xml, image/*, text/html, text/plain], useEquals=false, ignoredMediaTypes=[*/*]]]]], org.springframework.security.config.annotation.web.configurers.oauth2.client.OAuth2LoginConfigurer$$Lambda$1356/0x0000026033885cf8@2528bdc7]
2024-03-08T21:14:22.211+09:00 DEBUG 7916 --- [nio-8080-exec-2] s.w.a.DelegatingAuthenticationEntryPoint : Match found! Executing org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint@776adcee


페이지는 success로 넘어가는데 로그는 error 페이지로 이동고,

Set SecurityContextHolder to anonymous SecurityContext, 익명사용자로써 저장된다.. 즉 인증이 안됐다는 얘기인데,, 커스텀을 하지 않으면 디폴트로 보관이 될 텐데..이상하다

 

시도 6 /error로 이동하는 문제는 favicon.ico 파일이 없어 /error페이지로 넘어가는 것이었다.. favicon파일을 넣어주니 /error는 사라졌다.

 

시도 7 handlerSuccess() 제거해 디폴트로만 작동되게 해봤지만 로그기록에선 여전히 anonymous SecurityContext로 저장된다.

 

시도 8 @Component어노테이션 제거 후 HandlerConfig 파일을 만들어서 @Bean으로 주입

혹시나 싶어 해봤지만, 역시나 안된다.

 

시도 9 SuccessHandler사용을 하지않고 일단 패스하고, 데이터베이스에 사용자정보를 저장하기 위해 OAuth2UserService를 커스텀한 customOAuth2UserService를 만들었다. 하지만 이것도 동작을 안한다.

                .oauth2Login(oauth2Login -> oauth2Login
                        .loginPage("/auth/login")
                        .userInfoEndpoint(userInfoEndpoint -> userInfoEndpoint
                                .userService(customOAuth2UserService))
@Slf4j
@Service
public class CustomOAuth2UserService extends DefaultOAuth2UserService {

    @Override
    public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
        OAuth2User oAuth2User = super.loadUser(userRequest);
        String string = oAuth2User.getAttributes().toString();
        log.info("method=loadUser oAuth2User.getAttributes().toString()=\n{}", string);
        return null;
    }
}

 

 

시도10 시큐리티 공식문서. 설정 파일 내부에서 넣어주었다.

    private OAuth2UserService<OAuth2UserRequest, OAuth2User> oauth2UserService() {
        return new CustomOAuth2UserService();
    }

.successHandler(this.oauth2UserService())



시도11 카카오 공식문서
https://kakao-tam.tistory.com/54

시도12 스택오버플로우
https://stackoverflow.com/questions/62804390/error-trying-to-authenticate-a-web-application-with-oauth2-and-strava-using-spri

시도13 시큐리티 설정파일을 동작하지 않게하고 디폴트상태에서 로그인 시도
에러확인

[invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: 401 Unauthorized: [no body]

리디렉션주소가 꼬인건지 이것도 원인을 못찾았다. {baseUrl}/login/oauth2/code/{registrationId}

baseUrl : http:localhost:8080

registrationId : kakao

시도14 카카오 콘솔에서 클라이언트 시크릿 비활성화

spring.security.oauth2.client.registration.kakao.client-secret를 주석 처리

 

그 외에도 정말 계속 수정해봤지만, OAuth2UserService와 SuccessHandler가 동작하지 않았다.

3일동안 내내 여기에 시간을 쏟았지만,,,우선 다른 기능부터 개발해야겠다.

 

나중에도 해결못하면 버전을 낮추거나,

Authorization code까지는 수신이 되는 걸 보아 Service단에서 Authentication을 갱신해줘야 할 것 같다.

 

+3/15 해결했다..

카카오 개발자 페이지에서 내 애플리케이션 > 제품 설정 > 카카오 로그인 >보안 탭으로 들어가서 "사용안함" 설정 후,  내 애플리케이션 application.properties 또는 yml 파일에 설정한

spring.security.oauth2.client.registration.kakao.client-secret

이것을 주석처리 해주니까 인증이 성공했다....

 

하지만 sercret key를 사용하고 성공하는 것이 원래 목표이기 때문에 더 알아봐야겠다.

 

https://devtalk.kakao.com/t/oauth-401/126415

 

OAuth 로그인 401 오류 발생합니다 (해결완료)

다음과 같이 application.yml 설정했습니다. 표시되는 오류입니다. [invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: 401 Unauthorized: [no body] ID는 831089 입니다. 2022-11-28T2

devtalk.kakao.com