AuthenticationProvider
What is?
- 인증을 처리하는 방법을 정의한 API
- UserDetailsService를 사용하여 사용자 상세 정보를 불러온 후, 이 정보로 추가적인 인증 로직을 수행가능
- 기본적으로 제공 하지만 사용자 맞춤이 필요할 때 구현해서 사용
- UserDetailsService는 사용자 정보를 불러온는 역할
- 이메일 인증등의 새로운 로직을 사용할 때 사용자 AuthenticationProvider을 구현한다.
Use UserRepository
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
public CustomAuthenticationProvider(UserRepository userRepository, PasswordEncoder passwordEncoder) {
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
}
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String pwd = authentication.getCredentials().toString();
Optional<SiteUser> _siteUser = this.userRepository.findByusername(username);
if(_siteUser.isPresent()) {
SiteUser siteUser = _siteUser.get();
if(passwordEncoder.matches(pwd, siteUser.getPassword())) {
List<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority(siteUser.getRole()));
return new UsernamePasswordAuthenticationToken(username, pwd, authorities);
}else {
throw new BadCredentialsException("Invalid password");
}
}else {
throw new BadCredentialsException("User not found");
}
}
@Override
public boolean supports(Class<?> authentication) {
return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
}
}
- 다음 두 함수를 반드시 구현해야한다!(Authentication authenticate(), boolean supports())
- UsernamePasswordAuthenticationToken을 반환 한다.
- BadCredentialsException은 인증 오류이다.
- 다음과 같이 구현하면 UserDetailService가 없어도 인증이 가능하다.
Use UserDetailService
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
private final UserSecurityService userSecurityService;
private final PasswordEncoder passwordEncoder;
public CustomAuthenticationProvider(UserSecurityService userSecurityService, PasswordEncoder passwordEncoder) {
this.userSecurityService = userSecurityService;
this.passwordEncoder = passwordEncoder;
}
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String pwd = authentication.getCredentials().toString();
UserDetails userDetails = userSecurityService.loadUserByUsername(username);
if(passwordEncoder.matches(pwd, userDetails.getPassword())) {
return new UsernamePasswordAuthenticationToken(username, pwd, userDetails.getAuthorities());
}else {
throw new BadCredentialsException("Invalid password");
}
}
@Override
public boolean supports(Class<?> authentication) {
return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
}
}
- 다음과 같이 내부적으로 UserDetailsService을 사용하여 사용자 정보를 조회하고 인증 로직을 구현할 수 있다.