728x90
PasswordEncoder의 주요 개념과 기능
- 비밀번호 인코딩
비밀번호를 데이터베이스에 직접 저장하지않고 , 해시(Hash) 알고리즘을 통해 변환한 값을 저장하는 방식.
PasswordEncoder는 이를 위해 encode() 메서드를 제공
encode(): 평문 비밀번호를 해싱하여 변환
String rawPassword = "myPassword123";
String encodedPassword = passwordEncoder.encode(rawPassword);
- 비밀번호 매칭
로그인 시 입력한 비밀번호가 저장된 해시 값과 일치하는지 검증하기 위해 matches() 메서드를 사용
matches(): 입력한 비밀번호와 저장된 해시 값의 일치 여부를 확인
비밀번호가 일치하면 true, 그렇지 않으면 false를 반환
boolean isMatch = passwordEncoder.matches(rawPassword, encodedPassword);
주입방식에 따른 차이
1. 직접 생성방식
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
2. @Configuration 및 @Bean을 사용한 방식
@Configuration
public class DemoConfig {
@Bean
public PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
- new 키워드 방식은 간단하지만 객체 관리 측면에서 재사용이 어렵고, 코드 중복 및 관리 복잡성을 증가시킬 수 있다.
- @Bean 방식은 스프링 컨텍스트 내에서 싱글톤으로 관리되어 애플리케이션 전체에서 효율적으로 재사용할 수 있고, 의존성 주입으로 필요한 곳에 간편하게 주입할 수 있어 더 유지보수에 유리하다.
BCryptPasswordEncoder
스프링 시큐리티에서 가장 흔히 사용하는 PasswordEncoder 구현체는 BCryptPasswordEncoder입니다.
- BCrypt 알고리즘: 해시 함수로, 비밀번호 해싱에 매우 안전한 BCrypt 알고리즘을 사용합니다. 이 알고리즘은 속도를 조절할 수 있어 무차별 대입 공격(Brute Force Attack)에 강합니다.
- 솔트(Salt): BCrypt는 자동으로 솔트(Salt)를 생성하여 해시 값에 포함시킵니다. 솔트는 같은 비밀번호여도 항상 다른 해시 값이 생성되도록 하는 추가 데이터입니다.
- 강도 조절: 생성 시 강도를 설정하여 해싱에 걸리는 시간을 조정할 수 있습니다. 기본 강도는 10이며, 강도를 높일수록 해시 작업이 느려져서 공격에 더 강해집니다.
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(12); // 강도를 12로 설정
PasswordEncoder의 장점
- 안전한 비밀번호 저장
- 비밀번호가 직접 노출되지 않도록 보호하고 , 해시값으로 저장함으로 보안성을 높임
- 다양한 구현체 ( PasswordEncoder 인터페이스를 통해 다양한 해싱 알고리즘 사용)
- BCryptPasswordEncoder: 안전성 높은 BCrypt 알고리즘 기반.
- Pbkdf2PasswordEncoder: PBKDF2 알고리즘 기반.
- SCryptPasswordEncoder: 메모리 집약적인 Scrypt 알고리즘 기반.
로그인 passwordEncoder (matches() 사용)
@AllArgsConstructor
@Controller
@RequestMapping(value = "/member")
public class MemberController {
//@Autowired(required = false)
JoService joService;
MemberService service;
PasswordEncoder passwordEncoder;
//PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
//주입받기 위해 , 생성되어있어야 하는데 , java-Config (DemoConfig.java)파일을 이용한다.
DemoConfig.java에 Bean을 만들어 둠.
@RequestMapping(value = "/login", method = RequestMethod.POST)
public String mLogin(Model model, HttpServletRequest request, HttpSession session,MemberDTO dto, JoDTO jdto) {
//String id = request.getParameter("id");
// => 요청을 처리하는 매핑메서드의 인자로 ~DTO 등의 객체를 정의하면,
// Parameter 들의 name 과 일치하는 필드의 값들은 자동으로 담겨짐(setter 사용함)
String password = dto.getPassword();
String uri = "redirect:/home";
dto = service.selectOne(dto.getId());
if(dto !=null && passwordEncoder.matches(password, dto.getPassword())) {
session.setAttribute("loginID", dto.getId());
session.setAttribute("loginName", dto.getName());
session.setAttribute("loginJno", dto.getJno());
System.out.println("성공 !");
}else {
System.out.println("실패 !");
model.addAttribute("message", "로그인 다시 하세요.");
uri="member/loginForm";
}
return uri;
}
회원가입시 passwordEncoder(encode() 사용)
@RequestMapping(value = "/mjoin", method = RequestMethod.POST)
public String mjoin(Model model ,HttpServletRequest request , MemberDTO dto) throws IOException {
String uri = "member/loginForm";
//* passwordEncoder 적용
dto.setPassword(passwordEncoder.encode(dto.getPassword()));
//* 이미지 업로드처리 =====================================
...
...
// ========================================================
if(service.insert(dto)>0) {
model.addAttribute("message","회원가입 성공 ! 로그인 후 이용해주세요");
}else {
model.addAttribute("message","회원가입 실패 ! 다시 이용해주세요");
uri="member/joinForm";
}// 문자열로 , 경로를 보낼때는 폴더명부터 입력해줘야함.
return uri;
}
'Developer > Spring eGov4.0 (Java11, Tomcat9)' 카테고리의 다른 글
SpringBoot-MyBatis 데이터베이스를 연동하기 위한 설정 및 구조 (0) | 2024.10.28 |
---|---|
Spring , 영속 계층의 프레임 워크, myBatis와 JPA차이 , OMR이란 (2) | 2024.10.28 |
Spring , service 의 구현 (0) | 2024.10.27 |
Spring , log message (0) | 2024.10.27 |
Spring , 기본 mvc 패턴 제작형식 , 주요 애노테이션 (1) | 2024.09.27 |