Spring Security
                
              WebAuthenticationDetails 와 AuthenticationDetailsSource
                채마스
                 2022. 2. 28. 20:34
              
                          
            개요
- 사용자가 인증을 요청할때, username, password 이외에 다른 값까지 같이 인증에 포함 시키고 싶은 경우가 있다.
- 그럴때 WebAuthenticationDetails 를 직접 구현해서 사용한다.
WebAuthenticationDetails, AuthenticationDetailsSource

- 위와 같이 WebAuthenticationDetails 는 인증 과정 중 전달된 데이터를 저장한다. -> Authentication 의 details 속성에 저장한다.
- WebAuthenticationDetails 는 기본적으로 remoteAddress 와 SessionId 는 가지고 있다.
- AuthenticationDetailsSource 는 WebAuthenticationDetails 객체를 사용한다.
코드
- FormWebAuthenticationDetails 클래스 구현
public class FormWebAuthenticationDetails extends WebAuthenticationDetails {
    private  String secretKey;
    public FormWebAuthenticationDetails(HttpServletRequest request) {
        super(request);
        secretKey = request.getParameter("secret_key");
    }
    public String getSecretKey() {
        return secretKey;
    }
}- 위와 같이 secret_key 를 파라미터로 넘기고 있다.
- FormWebAuthenticationDetailsSource 클래스 구현
@Component
public class FormWebAuthenticationDetailsSource implements AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> {
    @Override
    public WebAuthenticationDetails buildDetails(HttpServletRequest request) {
        return new FormWebAuthenticationDetails(request);
    }
}- 반환 값으로 FormWebAuthenticationDetails 객체를 넘겨준다.
- FormWebAuthenticationDetails 의 생성자로 secret_key 를 넘겨준다.
- CustomAuthenticationProvider 에서 추가로 넘어온 secret_key 사용
public class CustomAuthenticationProvider implements AuthenticationProvider {
    // ... 생략
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        // ... 생략
        String secretKey = ((FormWebAuthenticationDetails) authentication.getDetails()).getSecretKey();
        if (secretKey == null || !secretKey.equals("secret")) {
           throw new InsufficientAuthenticationException("Invalid Secret");
        }
        // ... 생략
    }
   // ... 생략
}- username, password 외에 넘긴 secret_key 를 사용할 수 있다.
SecurityConfig 에 formWebAuthenticationDetailsSource 등록
private final FormWebAuthenticationDetailsSource formWebAuthenticationDetailsSource;
@Override
protected void configure(final HttpSecurity http) throws Exception {
    http
            // ... 생략
    .and()
            // ... 생략
            .authenticationDetailsSource(formWebAuthenticationDetailsSource)
}- 위와 같이 formWebAuthenticationDetailsSource 를 등록해서 사용할 수 있다.
REFERENCES
- 정수원님의 스프링 시큐리티