1 분 소요

  • 스프링 시큐리티를 이용해 OAth를 구현하던 도중 java.lang.NullPointerException을 만났다. 정확히는 로그인이 제대로 되었는지 확인하기 위해 Login후 생성된 세션의 Authentication에 Principal 객체를 호출해 사용자의 이름이 뜨느지 체크하기 위해서 였다.
  • 분명 DB에는 사용자가 등록이되고 로그인도 되었지만 말이다.

  • 결국 이 문제의 원인은
    http
      .sessionManagement()
      .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
    

    SecurityConfig의 이 코드 때문이었다. 즉 시큐리티의 세션정책을 잘못 설정하여 세션이 저장되지 않았고 따라서 Authentication 객체도 서버에 남아있지 않았던 것.

  • 전에 JWT 실습을 하다가 작성해 놀고 제대로 이해하지 않아 이런 불상사가 벌어졌기에 이번에는 완벽히 숙지하고 넘어가자

스프링시큐리티 세션정책

  • 시큐리티에서는 세션을 어떻게 관리하고 이용할 것인지에 대해 4가지 타입으로 나누어 설정을 할 수 있다.
  1. SessionCreationPolicy.Always: 스프링 시큐리티가 항상 세션 생성
  2. SessionCreationPolicy.If_Required: 스프링 시큐리티가 필요 시 생성(기본값)
  3. SessionCreationPolicy.Never: 스프링 시큐리티가 생성하지 않지만 이미 존재하면 사용
  4. SessionCreationPolicy.tateless: 스프링 시큐리티가 생성하지 않고 존재해도 사용하지 않음
    • 각 설정의 의미는 다음과 같다. 여기서 내가 잘못 설정한 4번을 살펴보며 이해를 해보자

SessionCreationPolicy.STATELESS의 의미

  • SessionCreationPolicy.STATELESS는 더이상 인증처리를 위해서 시큐리티가 세션 및 쿠키 방식의 인증 메커니즘을 사용하지 않도록 설정한다는 의미이다.
  • 시큐리티 필터체인에서 인증 작업을 위해서 초반에 UsernamePasswordAuthenticationFilter가 사용되고 그 결과로 Authentication객체가 SecurityContext에 담기게 된다.
  • 이 Authentication에는 [Principal, Credentials, Athorities]가 담겨있다.

  • 그런데 4번으로 세션 정책을 실시하면 Authentication이고 뭐고간에 애초에 Session을 통한 인증방식을 시작조차하지 않겠다는 의미이다. 즉 사용자가 가입을 해도 Session이 없고 따라서 Authentication도 없는 것이다.
  • 이러한 이유로 JWT를 통해 사용자 인증을 하고자 할 때 4번 정책을 설정하는 것이다.
  • JWT가 토큰을 통해 인증 할 때마다 서버에 전달하고 Header, PayLoad,Signature 중 Signature를 통해 사용자를 확인한다.

※ http.csrf().disable();의 의미

  • CSRF는 사용자의 해킹방법 중 하나이다.(자세히는 따로 정리할 예정)
  • CSRF를 예방하기 위해 토큰방식을 이용한다.
  • HTTP 메서드 중 POST, PUT, DELETE 와 같은 요청이 들어오면 서버는 CsrfFilter 필터 클래스가 동작해 사용자에게 이전에 발급한 CSRF 토큰을 요청한다.
    public void saveToken(CsrfToken token, HttpServletRequest request, HttpServletResponse response) {
      if(token == null){      HttpSession session = request.getSession(false);   
       if (session != null) {         session.removeAttribute(this.sessionAttributeName);      
      }   
    }   
      else {      HttpSession session = request.getSession();
       session.setAttribute(this.sessionAttributeName, token);   
       }
     }
    
  • csrf토큰을 통해 사용자 검증이 완료되면 그때 세션을 생성하고 해당 세션에 토큰을 저장한다.
  • 만약 이러한 http.csrf().disable();처럼 해당 필터를 비활성화한다면 세션 또한 만들어지지 않게 된다.

  • 이를 세션 정책과 연결지어 정리하면 이렇게 설명할 수 있다. SessionCreationPolicy.STATELESS는 인증과 관련된 세션 기능을 비활성화 한다는 의미로 서버에서 세션자체를 사용하지 않는 다는 것은 아님을 기억해야 한다.

출처: https://www.inflearn.com/questions/34886

댓글남기기