이 강의에서는
로그인 작업에서
BCryptPasswordEncoder를 사용하겠습니다
그 전에 BCryptPasswordEncoder에 대해
더 자세히 보여드리겠습니다
앞에서 저의 BCrypt 해시 텍스트가 따르는
패턴이 있다고 말씀드렸습니다
여기를 보시면 텍스트가
따라야 할 패턴은 $2가 가장 첫 번째
철자들이어야 한다는 것입니다
그 다음에는 y나 b를 가질 수 있습니다
이 BCryptPasswordEncoder에서
여기 BCryptVersion 열거를 통해
이 인코더가 지원하는 버전을 확인해보면
$2a 버전, $2y 버전, $2b 버전이 있습니다
그러니 기본적으로
여러분의 Spring Security는 이 버전을 사용합니다
필요하다면 이 기본 설정을 BCrypt 버전으로 바꿀 수 있습니다
어떻게 BCrypt 버전으로 바꿀수 있을까요?
ProjectSecurityConfig 안에서
현재 우리는 BCryptPasswordEncoder의 빈 생성자를
호출하고 있는데
이는 BCrypt 알고리즘이
고려해야 할 버전도 작업량 변수나
라운드 수도 입력하지 않았다는 뜻입니다
그러니 이 값들은 기본 생성자입니다
이 빈 생성자에서
-1 값으로 this를 호출합니다
이것은 하나의 정수를 받는 this 생성자를
내부적으로 호출합니다
그리고 여기서 우리는 다시
this(strength,null)을 호출합니다
이것을 클릭하면 여길 보시면
이 생성자에서는 또 다시
버전, 강도, SecureRandom 값을 받는
생성자를 호출합니다
이걸 클릭하면
또 다른 생성자로 가고
이것이 전송할 기본 버전은
$2a인 것을 볼 수 있습니다
strength 값이 -1로 일치한다면
기본 설정으로 10을 고려하는 것인데
이것은 해싱 과정에서 사용해야 하는
로그 라운드 수나 작업량 변수입니다
또한 strength 값의 최소값은 4이고
최대값은 31입니다
이것이 MIN_LOG_ROUNDS와
MAX_LOG_ROUNDS 상수들에서 볼 수 있는 것입니다
그러니 반드시 4와 31 사이의
값을 전송해주십시오
버전 강도 SecureRandom 값을 전달함으로써 여러분의
BCrypt 해싱 알고리즘을 커스터마이즈할 수 있습니다
SecureRandom 값의 목적은
우리가 솔트라고도 부르는
무작위로 생성된 값을
더하도록 해주는 것입니다
우리가 요리할 때 더 맛을 내기 위해
소금을 더하는 것처럼
아주 유사하게 해싱 과정이나
암호화 과정에서 무작위로 생성된 솔트값을 더해 해싱
알고리즘을 더 안전하게 만듭니다
이렇게 하면 제가 사용한
SecureRandom 값과 일반 테스트
비밀번호가 무엇인지 해커가 알아내기 위해
오랜 시간을 써야 하기 때문에
그의 삶을 아주 어렵게 만들 수 있습니다
이건 이 해커에게서 많은 시간과
연산 능력을 빼앗을 겁니다
그래서 여러분이 원한다면
언제든 무작위로 보안된 값을 생성할 수 있고
이를 여러분의 해싱 작업에 사용할 수 있으며
여러분의 BCrypt 해싱 알고리즘은
이 무작위 보안 값을 여러분의 해시 문자열
자체에 저장할 것입니다
BCryptPasswordEncoder에 대해
말씀드린 모든 세부사항을
명확히 이해하셨으면 좋겠습니다
이제 로그인 작업으로 돌아와서
우리가 수정해야 할 사항들이 뭔지 살펴보겠습니다
로그인 작업은 저에 의하면
우리는 아무런 코드 수정도 할 필요 없습니다
여러분이 우리 프로젝트를 확인해보면
EasyBankUserDetails가 있기 때문입니다
이 클래스에서 우리는 유저 네임의 도움을 받아
유저 정보를 불러오는데
비밀번호들의 실질적인 비교는 저의
DaoAuthenticationProvider에서 일어날 것입니다
DaoAuthenticationProvider를 열어보면
additionalAuthenticationChecks라는 메소드가 있습니다
여기에 중단점을 계속 두고
어떻게 되는지 보겠습니다
보안 API에 접근해서
우리 애플리케이션에 로그인하겠습니다
여기서 우리에게 있는 myAccount REST API에
접근하고 있습니다
우리가 등록한 이메일은
john@example.com이고 비밀번호는 12345입니다
로그인 버튼을 클릭해보겠습니다
이는 저의 additionalAuthenticationChecks
메소드의 실행을 중단합니다
이 메소드를 한 줄씩 디버그해보면
저의 인증 객체에 자격 증명이
있는지 체크할 겁니다
자격 증명이 있고 엔드 유저가 제공한
자격 증명은 12345입니다
이 12345는
데이터베이스로부터 얻은 비밀번호와 함께
PasswordEncoder 안에 있는
matches 메소드에 전송됩니다
여기서 우리가 사용하고 있는 PasswordEncoder는 무엇일까요?
BCryptPasswordEncoder입니다
presentedPassword를 보시면
최초 비밀번호인 12345가 있습니다
이 두 개의 문자열은 matches 메소드로 전송됩니다
이 메소드에 들어가서 디버그해보겠습니다
이 matches를 열고 있습니다
여기서 우리 비밀번호가 12345이고 암호화된 비밀번호는
이것이 우리 데이터베이스에
저장된 비밀번호라는 걸 볼 수 있습니다
여기 BCryptPasswordEncoder의
matches 메소드에서는 BCrypt 라이브러리에 있는
checkpw를 호출합니다
여기서는 또한 최초 비밀번호와
인코딩된 비밀번호를 받고 있습니다
이 메소드에서
먼저 최초 비밀번호는 동일한 버전
동일한 강도로 해싱되고
최초 비밀번호에 대해 해시값이 생성되면
메소드는 두 해시 문자열의
해시값이 같은지 확인합니다
해시값이 같다면
로그인 작업은 성공입니다
이 중단점을 해제해보겠습니다
제가 로그인하고 저의 API에 접근할 수 있는 게 보이십니까?
우리가 등록 절차에서
BCryptPasswordEncoder을
활용하지 않은
엔드 유저 자격 증명을 사용하려 하는
시나리오를 생각해보겠습니다
무슨 일이 일어나는지 봅시다
john@example.com을 사용할 거고
비밀번호가 무엇인지 확인하겠습니다
데이터베이스 내부의 비밀번호는 54321입니다
비밀번호가 54321이라고 하는 것이고
로그인을 클릭하고 중단점을 모두 해제했습니다
우리 로그 내부를 보면 인코딩된 비밀번호가
BCrypt처럼 보이지 않는다는 로그가 있습니다
데이터베이스에서 불러온 값이
Bcrypt 해시값의 패턴이
아니라고 하는 겁니다
그래서 우리의 로그인 작업은 실패입니다
잘못된 자격 증명 오류가 뜬 것이 보이십니까?
이제는 PasswordEncoder에 대해
아주 아주 명확하게 이해하셨으면 좋겠습니다
이 섹션에서 우리는 BCryptPasswordEncoder를
적용하기 위해 몇 가지 사항을 수정했습니다
첫 번째 수정 사항은
ProjectSecurityConfig 클래스 내부에
BCryptPasswordEncoder 유형 bean을 생성했고
두 번째 수정 사항은
로그인 작업에서
일반 텍스트 비밀번호를 해싱하기 위해
BCryptPasswordEncoder의 encode 메소드를 활용한 것입니다
하지만 저의 Spring Security 프레임워크가
비밀번호들이 일치하는지 확인하기 위해 BCryptPasswordEncoder를
활용할 것이기 때문에 로그인 작업에서
우리는 아무것도 하지 않습니다
이 섹션을 끝내기 전에
몇 가지 추가적인 세부사항을 강조하겠습니다
제가 공유하고 싶은 첫 번째 정보는
이 모든 PasswordEncoder들
또는 다른 비밀번호 관련 클래스들은
org.springframework.security.crypto
패키지에서 찾으실 수 있다는 것입니다
Spring Security 프레임워크 안에는
크립토 패키지가 있는데
이 크립토 패키지 자체에서
argon2, bcrypt와 같은 모든 나머지 PasswordEncoder를
볼 수 있습니다
스크립트도 있고 여러분이 보시는
나머지 PasswordEncoder들과 같은
많은 유틸리티 클래스가 있습니다
Spring Security에서 PasswordEncoder 관련
의문이 있을 때 여러분이
언제든 참고할 수 있는 패키지입니다
물론 여러분이 원한다면
PasswordEncoder 인터페이스를 구현해 여러분만의
PasswordEncoder를 정의할 수도 있습니다
하지만 이걸 추천하진 않습니다
Spring Security 프레임워크에서
제공하는 PasswordEncoder는
이미 충분히 괜찮기 때문입니다
그리고 이미 업계 표준을 준수하고 있습니다
이런 이유로 여러분만의 PasswordEncoder를
개발하는 것은 추천하지 않습니다
왜냐하면 여러분이 해싱 알고리즘으로
새로운 PasswordEncoder를 개발하려고 하면
많은 유스케이스를 놓칠 수 있기 때문입니다
제가 공유하려는 다음 정보는
GitHub 리포지터리 관련입니다
여기 섹션 4에서 수정한 모든 사항들은
이 section4/springsecsection4 폴더에서
찾으실 수 있습니다
모든 필수 수정 사항이 있는 Maven 프로젝트입니다
'PasswordEncoder를 활용한 비밀번호 관리'와 같이
이 Maven 프로젝트에
주석을 달아 놓았습니다
이로써 여러분이 PasswordEncoder에 대해 아주 명확히
이해했다고 생각합니다
앞으로 우리 웹 애플리케이션은
가장 최신 해싱 알고리즘은 Bcrypt를
사용할 것입니다
Spring Security 내부 흐름에서 PasswordEncoder의
역할에 대해 이해하셨으면 좋겠습니다
PasswordEncoder들은 새로운 비밀번호 등록
또는 비밀번호 변경
또는 로그인 작업에서
개발자들을 도와줄 수 있는 많은 구현 클래스들을
가지고 있습니다
이 PasswordEncoder가 없다면 개발자들이 이러한
PasswordEncoder 주변의 모든 생태계를
구축하고자 들여야 할 노력을 상상하실 수 있을 겁니다
이로써 이 섹션을 마무리하고
좀 쉬도록 하겠습니다
커피시간 가지시고
휴식 후에 돌아와서
다음 섹션에서 우리 이야기를 계속하겠습니다
감사합니다