보안하면 생각나는 대표적인 기능 "로그인"에 대해 알아보자
시큐리티에서 로그인을 진행 할때는 FormLogin 을 통해서 조작한다. 코드 또한 물론 볼것이지만 우선 로그인의 순서부터 생각해보자
- 사용자는 GET방식을 통해 어떠한 로그인(인증)이 필요한 화면에 접근하게 된다.
- 그러면 시큐리티는 해당 사용자가 인증된 사용자인지 확인을 한다
- 만약 로그인을 하지 않은 사용자라면 해당 사용자를 로그인 페이지로 보낼것이다.
- 그렇다면 사용자는 이제 POST 방식을 통해 ID와 PW가 담긴 내용을 서버에게 전송한다
- 서버는 사용자가 입력한 정보를 기반으로 session 및 인증 토큰을 생성 / 저장한다. 물론 회원정보가 서버의 정보가 일치한다는 전재하에 말이다.
- 인증 객체를 생성한다 (Authentication)
- 객체가 인증된다면 Context 에 저장한다.
- 이후 사용자가 또 다시 인증이 필요한 정보를 요청하게 되면 서버는 또 다시 세션에 저장된 인증 토큰으로 접근 / 인증을 유지하게 될 것이다.
바로 코드를 보자 ( 물론 코드를 보면 바로 어떤 일을 하는지 알 수 있지만 다시 적어서 알아보자)
- defaultSuccessUrl = 로그인을 성공하면 이동할 페이지
- failureUrl = 로그인을 실패하면 갈 페이지
- usernameParameter = html 양식의 아이디를 입력할 곳의 parameter 의 이름을 지정한다
- passwordParameter = html 양식의 비밀번호를 입력할 곳의 parameter 의 이름을 지정한다
- loginProcessingUrl = 로그인 FormAction Url 이다. 즉 ,버튼을 누르면 여기로 정보를 보내겠다! 이런뜻이다.
- successHandler = 로그인 성공한 후의 핸들러를 잡는데 여긴 메소드를 만들어서 넣어줄수 있다. 그렇게 성공후의 데이터 작업을 본인이 마음대로 만들수 있다.
- failureHandler = 마찬가지로 실패한후의 Handler이며 이또한 메소드를 통해 마음대로 바꾸며 작업하는것이 좋다.
그러면 이제 인증 처리 과정을 함께 알아보자
- 사용자는 Post 형태로 login이란 요청을 했다고 가정해보자
- 그렇다면 필터를 지나가는 도중 UsernamePasswordAuthenticationFilter라는 곳에 걸리면서 AntPathRequestMatcher라는 클래스에서 URL을 확인한다
- 만약 맞다면 Authentication 이라는 객체를 생성하고 아직 인증이 되지 않은 아이디와 비밀번호의 정보를 담는다
- 이런 Authentication 객체는 AuthenticationManager 라는 인증 관리자에게 가게 되고 Manager는 실제 인증을 진행하는 클래스 AuthenticationProvider 에서 인증을 진행하게 된다.
- 인증 실패 -> AuthenticationException 예외 처리를 받아 다시 필터로 돌아가고 그 후 작업은 필터가 진행한다
- 인증 성공 -> 인증이 성공하면 UsernamePasswordAuthenticationToken에 저장된다.
- 인증을 성공한 Authentication객체 안의 UsernamePasswordAuthenticationToken은 SecurityContext에 저장되면서 로그인을 마무리한다
번외) SecurityContextHolder 는 전역으로 생성되어 있기 때문에 혹시 다른곳에서 불러오고 싶다면
SecurityContextHolder.getContext().getAuthentication()
을 사용하면 사용자의 정보를 불러올수있다.
정리
JWT 토큰을 사용한 나는 기존의 로그인 방식을 사용할 수 없었고 필터를 등록하는 수 밖에 없었다. 로그인을 완성하는 과정과 후 작업 처리는 굉장히 비슷하지만 성공을 한 후 토큰을 발급하는 과정에 있어 JWT 토큰을 발급하며 커스텀이 필요했다.
일반적인 시큐리티의 경우 로그인이 완료되면 Context에 저장되고 JSESSION을 발급해서 서버에서는 메모리에 저장하여 사용하는 방식을 택했기때문에 다음에 따로 오로지 시큐리티 방식만을 이용해 만들게 된다면 꼭 오로지 시큐리티의 기본 기능만을 이용한 프로젝트를 진행해 봐야겠다.