현재로서 우리의 웹 애프리케이션 안에는
JWT 토큰의 생성을 담당하는
필터가 있습니다
하지만 이게 충분하지 않다면
클라이언트 애플리케이션으로부터 받은
JWT 토큰의 유효성을 검증할 수 있는 로직도 있어야 합니다
이는 성공적인 인증 이후에
클라이언트 애플리케이션이 수행할 모든 후속 요청에 해당됩니다
따라서 새로운 필터를 생성하겠습니다
같은 과정을 반복해보겠습니다
여기 filter 패키지 안에서
오른쪽 클릭 후 New → Java Class 순서대로 클릭하겠습니다
여기서 선택하고 싶은 클래스 이름은
이미 알고 계실 수도 있겠지만, JWTTokenValidatorFilter입니다
따라서 이 필터로는 어떤 클래스를 extend할 것인지 볼텐데
OncePerRequestFilter를 extend해야 합니다
따라서 이 필터를 확장하고자 할 때는
이 필터가 가진 추상 메소드를
재정의 해야 합니다
해당 방법을 사용해보겠습니다
메소드의 이름은 doFilterInternal입니다
여기에 있는 throws 명령을 다음 줄로 내려보겠습니다
현재로서는 보시다시피 메소드가 비어있습니다
여기에 코드 몇 줄을 작성하여면
클라이언트 애플리케이션에서 받을
JWT 토큰의 유효성을 검증할 것입니다
doFilterInternal 메소드 속에
여기 보시다시피 코드를 몇 줄 적어놓았습니다
이제 이 코드를 한줄씩 이해해 보도록 합시다
첫번째 줄에는
헤더 메소드를 사용하여
인가 헤더 값을 가져오려 시도하고 있습니다
그리고 이 메소드에는
인가라는 같은 헤더 이름을 보내고 있습니다
그리고 이 getHeader 메소드로
클라이언트 애플리케이션이
요청 속에 보내는 JWT 토큰을 가져오려 하고 있습니다
이것이 request.getHeader를 쓰는 이유입니다
이 JWT 토큰을 갖고 난 후
Keys.hmacShaKeyFor 이라는 같은 메소드를 이용하여
비밀 키를 다시 생성하려 합니다
그리고 해당 메소드를 위해서는 백엔드 애플리케이션 내에 있는
같은 JWT 비밀 키를 보냅니다
JWT 토큰을 생성할 때
사용한 키와 같은 키입니다
따라서 검증 과정 중에
같은 비밀 키를 다시 사용하고 있는지 확인해야 하는 것입니다
따라서 이 키 값을 가진 후
해당 Jwts 클래스를 이용하여
parserBuilder라는 메소드를 호출합니다
이 메소드 안에 Signing Secret Key를 호출하는데
Signing Secret Key가 무엇이냐면
이 key 값입니다
같은 값을 보내는 것입니다
그 다음에 build 메소드를 호출해야 합니다
마지막으로 parseClaimsJws 메소드를 호출하고
받은 JWT 토큰을 보내야 합니다
그리고 이러한 전송이 완료된 후
이제 바디 값을 읽는 데 집중해야 합니다
특정 값을 나타내는 value 토큰이라면
헤더 부분에서 서명 부분을 읽고 싶지 않은 것입니다
따라서 이러한 getBody 메소드를 사용해 줍니다
그리고 이 getBody 메소드에서 claims를 가져오게 됩니다
Claims를 사용하여
엔드 유저의 ID와 권한을 가져올 수 있습니다
이렇게 ID와 권한이 있다면
UsernamePasswordAuthenticationToken 종류의
인증 객체를 생성할 수 있습니다
여기 username이 있고
비밀번호는 null이고 Authority를 볼 수 있습니다
이걸로 Spring Security 프레임워크에게
해당 JWT 토큰을 유효화 했고
별다른 문제가 없다고 알리는 것입니다
이것이 직접 인증 객체를 생성하는 이유입니다
이것으로 Spring Security는 인증 과정이 성공적이었다고 추정할 것입니다
따라서 이는
해당 인증 객체를
SecurityContextHolder.getContext().setAuthentication 메소드를 호출하여
SecurityContextHolder 안에
넣어두어야 하는 이유입니다
어떤 이유에선지 JWT 라이브러리가
제가 전달한 비밀 키를 기반으로 JWT 토큰을 전달하려고 할 때
내부적으로 해시 값을 계산하여
일치 여부를 확인합니다
일치하지 않는다면
여기 있는 예외들을 throw할 것입니다
예를 들어 만료 되었다면 ExpiredJWTException
UnsupportedJWTException
MalformedJwtException, SignatureException 등등
다양한 상황에 따른
예외를 갖게 되는 것입니다
따라서 이러한 예외 중 하나를 갖게 된다면
해당 예외를 catch할 수 있고
BadCredentialsException이라고 작성하여
예외를 throw 할 수 있습니다
그리고 해당 로직 이후에는 이 줄에 있는 코드를 이용하여
filterChain 속에 다음 필터를 호출할 것입니다
다음으로 우리가 봐야할 메소드는
shouldNotFilter입니다
이번에는 요구 사항이 이 validation 필터가
로그인 작업 중을 제외한 모든 API 호출에 대해 실행되는 것입니다
따라서 로그인 경로가 /user인 경우에는
해당 validation 필터가 실행되서는 안됩니다
이를 제외하고는 해당 필터가 항상 실행됩니다
따라서 이는 해당 shouldNotFilter안에
작성해야 하는 로직입니다
물론 여기서 제가 가르쳐드리는 로직에 전혀 결점이 없다는 것이 아니고
모든 실제 애플리케이션에서 작동할 거라 보장하는 것도 아닙니다
여기서 배운 내용을 가지고
본인의 프로젝트와
비즈니스 로직에 대해 생각해보고
그에 따른 비즈니스 로직을 써야하는 것입니다
때때로 학생들에게 연락이 와서
"이것이 제 프로젝트 시나리오이고
이러한 셋업을 그대로 얻고 싶습니다"와 같은 말을 합니다
이런 질문을 받을 때마다
조금 슬퍼집니다
왜냐하면 여기서 우리의 목표는 늘 해당 이론을 배우는 것에 있어야하기 때문입니다
이론을 배우게 되면
더욱 깊이 파고들어서
프로젝트에 가장 적합한 것이 무엇일지 달성하도록 노력해야 합니다
여러분도 우선 이론을 이해하고
처한 상황이 어떤지에 따라
해당 이론에 대해 고찰한
이 유의미한 해결법을 찾는 길을 선택하시기 바랍니다
해당 교육에서는 EasyBank 애플리케이션에서는
완벽히 실행될 수 있는 내용을 가르치고 있습니다
하지만 이는 본인이 사용하는 애플리케이션에
100프로 알맞는 해결책이 아닐 수도 있습니다
따라서 강의의 내용에 주의를 기울여주시면 감사하겠습니다
항상 이론을 조심히 배우는 데에
목적과 중점을 두시기 바랍니다
그러면 이만 연설을 마치고
다시 수업을 진행하겠습니다
여기 보시다시피 validation 필터가 있습니다
이 필터는 Spring Security 프레임워크에서
인증을 시도하기 전에
실행되어야 합니다
이와 같이
생성된 필터를 이 ProjectSecurityConfig 내에서
올바르게 구성하고 있는지 확인해야 합니다
밑으로 스크롤 하겠습니다
여기에 addFilterBefore라는 메소드를 호출하겠습니다
그리고 여기에 JWTTokenValidatorFilter라는
새로운 객체를 넣어야 합니다 그 다음에
Spring Security 내부의 필터인
BasicAuthenticationFilter를 쓰겠습니다
이러한 구성 요소를 가지고
Spring Security 프레임워크에게 전달하고자 하는 바는
커스텀 필터인 JWTTokenValidatorFilter가
BasicAuthenticationFilter 이전에 실행되어야 한다는 것입니다
이는 커스텀 필터가
Spring Security 프레임워크의 실제 인증 유효성 검사 이전에
실행 된다는 것입니다
이로써 필요한 백엔드 변경 사항을 마쳤습니다
이 두 변경 사항으로 우리는
최초 로그인 과정 중
JWTTokenValidationFilter의 도움으로
JWT 토큰을 생성할 때
같은 JWT 토큰을 가지고 UI 애플리케이션에서 보내오는
후속 요청들을 전부 검증할 수 있도록 하는 것입니다
전체 플로우를 테스트하기에
해당 변경 사항만으로 충분하다고 생각하십니까?
당연히 아닐 것입니다 왜냐하면 우리는
백엔드에만 변경 사항을 적용했기 때문입니다
우리는 UI 애플리케이션에도 변경 사항을 적용하여
로그인 과정 중 응답 속 인가 헤더를
수락할 수 있게 해야 합니다
그리고 해당 헤더를 사용하여 Angular UI 애플리케이션은
JWT 토큰을 읽고
해당 JWT 토큰을 최초 로그인 과정 이후
모든 후속 요청중에 의해 보내야 합니다
따라서 다음 수업에서는 이러한 JWT 토큰에 대하여
Angular UI 애플리케이션에 필요한 변동 사항을
살펴보도록 합시다
가르치고자 하는 바가 명확히 전달 되었길 바라며
수업 중에 계속 함께해 주셨길 바랍니다
그리고 JWT 토큰에 대한 수업과
전반적으로 여기서 진행되고 있는 내용에 흥미를 갖고 계실 거라 생각하겠습니다
그럼 다음 강의에서 뵙겠습니다 감사합니다