WebAuthenticationDetails란 username과 password외에 추가적인 정보를 담을 경우 필요한 class로 이를 구현하면 추가 정보를 통해 인증에 활용할 수 있다.
아래는 secret-key를 이용하여 구현하는 방법이다.
public class CustomWebAuthenticationDetails extends WebAuthenticationDetails {
private final String secretKey;
public CustomWebAuthenticationDetails(HttpServletRequest request) {
super(request);
this.secretKey = request.getParameter("secretKey");
}
public String getSecretKey() {
return secretKey;
}
}
public class CustomAuthenticationDetailsSource implements AuthenticationDetailsSource<HttpServletRequest, CustomWebAuthenticationDetails> {
@Override
public CustomWebAuthenticationDetails buildDetails(HttpServletRequest request) {
return new CustomWebAuthenticationDetails(request);
}
}
public class CustomAuthenticationProvider implements AuthenticationProvider {
private final CustomUserDetailsService userDetailsService;
private final PasswordEncoder passwordEncoder;
public CustomAuthenticationProvider(CustomUserDetailsService userDetailsService, PasswordEncoder passwordEncoder) {
this.userDetailsService = userDetailsService;
this.passwordEncoder = passwordEncoder;
}
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String password = authentication.getCredentials().toString();
CustomUserDetails userDetails = userDetailsService.loadUserByUsername(username);
if (!passwordEncoder.matches(password, userDetails.getPassword())) {
throw new BadCredentialsException("Invalid password");
}
CustomWebAuthenticationDetails details = (CustomWebAuthenticationDetails) authentication.getDetails();
String secretKey = details.getSecretKey();
if (secretKey == null || !secretKey.equals("mySecretKey")) {
throw new BadCredentialsException("Invalid secret key");
}
return new UsernamePasswordAuthenticationToken(userDetails, password, userDetails.getAuthorities());
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
코드가 길어 보이지만 간단하다 위의 두 코드는 세부정보를 저장하는 코드이고 저장시에 authentiaction의 details에 담기게 된다. 이후 authentication.getdetails()를 이용하여 추가 정보를 가져올 수 있다. 3번째 코드는 provider로 객체의 정보를 인증 처리하고 secret-key를 가져와 다시 한번 더 확인하는 코드이다.