:Spring Security에서 지원하는 PasswordEncoder 구현 객체를 생성해주는 컴포넌트
:DelegatingPasswordEncoder를 통해 애플리케이션에서 사용할 PasswordEncoder를 결정하고, 결정된 PasswordEncoder로 사용자가 입력한 패스워드를 단방향으로 암호화해줌
Spring Security 5.0 이전 버전에서는 평전 텍스트Plain text 패스워드를 그대로 사용하는 NoOpPasswordEncoder가 디폴트 PasswordEncoder로 고정되어 있었으나 아래 문제를 해결하기 위해 DelegatingPasswordEncoder를 도입해서 조금 더 유연한 구조로 PasswordEncoder를 사용할 수 있게 됨
문제1) 패스워드 인코딩 방식을 마이그레이션하기 쉽지 않은 오래된 방식을 사용하고 있는 경우
-패스워드 단방향 암호화에 사용되는 hash 알고리즘은 시간이 지나면서 보다 더 안전한 hash 알고리즘이 지속적으로 고안되고 있기 때문에 항상 고정된 암호화 방식을 사용하는 것은 바람직한 방식이 아님
-보안에 취약한 오래된 암호화 방식을 고수하는 애플리케이션은 해커의 아주 좋은 타겟이 될 수 있음
문제2) 스프링 시큐리티는 프레임워크이기 때문에 하위 호환성을 보장하지 않는 업데이트를 자주 할 수 없음
-오래된 하위 버전의 기술이 언젠가 Deprecated되는 것처럼 보안에 취약한 오래된 방식의 암호화 알고리즘 역시 언제까지 관리 대상이 되지는 않음
장점1) DelegatingPasswordEncoder를 사용해 다양한 방식의 암호화 알고리즘을 적용할 수 있음. 사용하고자 하는 암호화 알고리즘을 특별히 지정하지 않는다면 Spring Security에서 권장하는 최신 암호화 알고리즘을 사용하여 패스워드를 암호화할 수 있도록 해줌
장점2) 패스워드 검증에 있어서도 레거시 방식의 암호화 알고리즘으로 암호화된 패스워드의 검증을 지원<노이해중>
장점3) Delegating이라는 표현에서 DelegatingPasswordEncoder의 특징이 잘 드러나도록 나중에 암호화 형식을 변경하고 싶다면 언제든지 암호화 방식을 변경할 수 있음
단, 이 경우 기종에 암호화되어 저장되니 패스워드에 대한 마이그레이션 작업이 진행되어야 함
(Delegate:위임하다 뽑다 선정하다)
코드는 다음과 같음
// PasswordEncoderFactories로 만들 수 있습니다.
PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
:PasswordEncoderFactories 클래스를 이용한 PasswordEncoder 인스턴스 생성
:PasswordEncoderFactories.createDelegatingPasswordEncoder();를 통해 DelegatingPasswordEncoder의 객체를 생성하고
내부적으로 DelegatingPasswordEncoder가 다시 적절한 PasswordEncoder 객체 생성<노이해중>
:Spring Security에서 지원하는 PasswordEncoderFactories 클래스를 이용하면 기본적으로 Spring Security에서 권장하는 PasswordEncoder를 사용할 수 있지만
필요한 경우, DelegatingPasswordEncoder로 직접 PasswordEncoder를 지정해서 Custom DelegatingPasswordEncoder를 직접 사용할 수 있음
String idForEncode = "bcrypt";
Map encoders = new HashMap<>();
encoders.put(idForEncode, new BCryptPasswordEncoder());
encoders.put("noop", NoOpPasswordEncoder.getInstance());
encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
encoders.put("scrypt", new SCryptPasswordEncoder());
encoders.put("sha256", new StandardPasswordEncoder());
PasswordEncoder passwordEncoder = new DelegatingPasswordEncoder(idForEncode, encoders);
:Custom DelegatingPasswordEncoder 사용
:Map encoders에 원하는 유형의 PasswordEncoder를 추가해
Delegatingpassword의 생성자로 넘겨주면
디폴트로 지정(idForEncode)한 PasswordEncoder를 사용할 수 있음<노이해중>
Spring Security 5에서는 패스워드를 암호화할 때 암호화 알고리즘 유형을 prefix로 추가함
암호화된 패스워드의 포맷은 다음과 같음
{id}encoderPassword
아래는 바로 위 코드에서 생성한 Custom DelegatingPasswordEncoder에서 지원하는 단방향 암호화 알고리즘 유형에 따른 암호화된 패스워드 예임
1)BCryptPasswordEncoder
로 암호화할 경우
결과물 : {bcrypt}$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG
PasswordEncoder id = bcrypt
endcoderPassword = 2a$10dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG
2)Pbkdf2PasswordEncoder
로 암호화할 경우
결과물 : {pbkdf2}5d923b44a6d129f3ddf3e3c8d29412723dcbde72445e8ef6bf3b508fbf17fa4ed4d6b99ca763d8dc
PasswordEncoder id = pbkdf2
endcoderPassword = 5d923b44a6d129f3ddf3e3c8d29412723dcbde72445e8ef6bf3b508fbf17fa4ed4d6b99ca763d8dc
3)SCryptPasswordEncoder
로 암호화할 경우
결과물 : {scrypt}$e0801$8bWJaSu2IKSn9Z9kM+TPXfOc/9bdYSrN1oD9qfVThWEwdRTnO7re7Ei+fUZRJ68k9lTyuTeUp4of4g24hHnazw==$OAOec05+bXxvuu/1qZ6NUR+xQYvYv7BeL1QxwRpY5Pc=
PasswordEncoder id = scrypt
endcoderPassword = e0801$8bWJaSu2IKSn9Z9kM+TPXfOc/9bdYSrN1oD9qfVThWEwdRTnO7re7Ei+fUZRJ68k9lTyuTeUp4of4g24hHnazw==OAOec05+bXxvuu/1qZ6NUR+xQYvYv7BeL1QxwRpY5Pc=
4)StandardPasswordEncoder
로 암호화할 경우
결과물 : {sha256}97cde38028ad898ebc02e690819fa220e88c62e0699403e94fff291cfffaf8410849f27605abcbc0
PasswordEncoder id = sha256
endcoderPassword = 97cde38028ad898ebc02e690819fa220e88c62e0699403e94fff291cfffaf8410849f27605abcbc0
핵심