• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

최신 스프링 시큐리티 - Ajax 로그인 시도 시 쿠키가 오지 않을 때 삽질 기록

23.10.31 17:44 작성 23.10.31 17:58 수정 조회수 441

5

증상

### 로그인(일반 회원)
POST http://localhost:8080/api/login
Content-Type: application/json
X-Requested-With: XMLHttpRequest

{
  "username": "user",
  "password": "1111"
}

### 로그인(매니저)
POST http://localhost:8080/api/login
Content-Type: application/json
X-Requested-With: XMLHttpRequest

{
  "username": "manager",
  "password": "1111"
}

### messages 요청
GET http://localhost:8080/api/messages
Content-Type: application/json
X-Requested-With: XMLHttpRequest
  • http 파일을 작성하고 로그인 요청에 성공했음에도 성공 응답 및 사용자 정보 dto가 오도록 했는데, 쿠키가 오지 않는 문제가 있었습니다.

원인

  • 원인은 AbstractAuthenticationProcessingFilter 의 기본 SecurityContextRepository가 RequestAttributeSecurityContextRepository이기 때문입니다.

  • 그동안 폼 인증에서 우리가 세션을 통해 인증을 할 수 있었던 것은 스프링시큐리티가 기본적으로 등록해준 UsernamePassowordAuthenticationFilter가 저 SecurityContextRepository 구현체로 DelegatingSecurityContextRepository(HttpSessionSecurityContextRepository(), RequestAttributeSecurityContextRepository()) 를 넣어줬기 때문입니다.

  • 또 우리가 AuthenticationSuccessHandler, AuthenticationFailureHandler를 커스텀하게 만들었다면 이를 수동으로 등록하는 코드를 작성해줘야하는 이유도 이와 같습니다. 기본 구현체가 위와 같기 때문입니다.

    @Bean
    fun ajaxLoginProcessingFilter(): AjaxLoginProcessingFilter {
        val filter = AjaxLoginProcessingFilter(objectMapper, authenticationManager())
        filter.setSecurityContextRepository(securityContextRepository())
        filter.setAuthenticationSuccessHandler(ajaxAuthenticationSuccessHandler())
        filter.setAuthenticationFailureHandler(ajaxAuthenticationFailureHandler())
        return filter
    }

    @Bean
    fun securityContextRepository(): SecurityContextRepository = DelegatingSecurityContextRepository(HttpSessionSecurityContextRepository(), RequestAttributeSecurityContextRepository())


    @Bean
    fun ajaxAuthenticationProvider() = AjaxAuthenticationProvider(userDetailsService, passwordEncoder())

    @Bean
    fun ajaxAuthenticationSuccessHandler() = AjaxAuthenticationSuccessHandler(objectMapper)

    @Bean
    fun ajaxAuthenticationFailureHandler() = AjaxAuthenticationFailureHandler(handlerExceptionResolver)

    @Bean
    fun ajaxAuthenticationEntryPoint() = AjaxAuthenticationEntryPoint(objectMapper)

    @Bean
    fun ajaxAccessDeniedHandler() = AjaxAccessDeniedHandler(objectMapper)
  • 혹시 저처럼 최신 스프링 시큐리티 환경에서 실습하시면서http 요청 실습에서 로그인 시 쿠키가 전송 안 되시는 분들은 이 작업을 해보시길 바랍니다.

  • SecurityContextRepository 구현체를 생성하여, 등록해보시는 것을 추천드립니다.

     

답변 3

·

답변을 작성해보세요.

0

김용환님의 프로필

김용환

2024.05.06

감사합니다. 덕분에 문제를 해결하였습니다.

저 같은 경우에도 AjaxLoginProcessingFilter의 SecurityContextRepository를 주입하지 않아서 일반 사용자로 로그인한 후 "/api/messages" 요청시 ExceptionTranslationFilter 부분에서 계속 익명사용자로 판단되어 401 에러로 응답되는 문제가 있었습니다. SecurityContext에 사용자의 인증 정보가 저장되지 않아서라는 것은 판단하였는데 폼방식에서 Ajax 방식으로 진행하면서 SecurityContextRepository를 주입하지 않은 것을 놓쳤네요.

0

kyoungik lee님의 프로필

kyoungik lee

2024.01.29

도움이 많이 되었습니다. 감사합니다.

 

0

철이와미애님의 프로필

철이와미애

2023.11.23

감사합니다 덕분에 많은 도움되었습니다!!!🙇‍♂