반응형
이 포스트는 데어 프로그래밍님의 유튜브 강의를 듣고 나서 정리한 글입니다.
UsernamePasswordAuthenticationFilter에 대해서는 아래 포스팅을 참조하시길 바랍니다.
UsernamePasswordAuthenticationFilter 동작 방식에 대해서
SpringSecurity Filterchain 에는 여러 종류에 필터가 존재하지만, 이번 시간에는 로그인 인증을 처리하는 UsernamePasswordAuthenticationFilter에 대해서 알아보겠습니다. Login 인증 로직 flow POST "/login"..
iseunghan.tistory.com
로그인 요청을 처리하기 위해서는 SpringSecurityFilterChain 중에 로그인 인증을 처리하는 필터인 UsernamePasswordAuthenticationFilter를 상속해야 한다.
attemptAuthentication
- POST "/login"
- 로그인 요청이 오면, UsernamePassword..Filter가 가로채서 attemptAuthentication 메소드를 호출합니다.
- 우리는 해당 메소드를 오버라이딩 하여 로그인 인증 로직을 구현해보겠습니다.
커스텀 Filter 생성
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private AuthenticationManager authenticationManager;
public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
// Form 방식으로만 getParameter로 뽑아낼 수 있음. JSON은 안됨!
String username = request.getParameter("username");
String password = request.getParameter("password");
// username, password를 담아서 UsernamePasswordAuthenticationToken을 생성한다.
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);
// 생성한 토큰을 담아서 authenticationManager.authenticate를 호출하면, UserDetailsService의 loadUserByUsername()이 호출됨
return this.authenticationManager.authenticate(token);
}
}
- username과 password를 뽑아서, UsernamePassword..Token을 생성해줍니다. *(아직 인증이 완료되지 않은 상태)
- 해당 토큰을 authenticationManager에게 넘겨 인증 권한을 위임합니다.
여기서 인증이 완료되면 -> successfulAuthentication
여기서 인증이 실패하면 -> unsuccessfulAuthentication
successfulAuthentication
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
// UserDetails 구현체 받아오기
AccountAdapter account = (AccountAdapter) authResult.getPrincipal();
// JWT 토큰 생성
String jwtToken = JWT.create()
.withSubject(account.getUsername())
.withClaim("exp", Instant.now().getEpochSecond() + 600)
.withClaim("id", account.getAccount().getId())
.withClaim("username", account.getUsername())
.sign(Algorithm.HMAC256("secret"));
// Authorization 헤더 값에 Bearer 토큰 담아서 응답
response.addHeader("Authorization", "Bearer " + jwtToken);
}
- 응답 헤더에 JWT 토큰 담아서 응답!
클라이언트가 요청을 했을 때, 서버에서 JWT 토큰을 서버에서 응답을 해줬으면, 클라이언트가 요청할 때마다 JWT 토큰을 들고 요청 할것입니다.
(우리는 이제 해당 JWT 토큰이 올바른 토큰인지 확인해주면 된다!)
다음 시간에 JWT 토큰을 검증하는 필터를 생성해서 해당 JWT이 올바른 토큰인지 검증해보도록 하겠습니다.
감사합니다.
반응형