본문 바로가기
스프링 부트3

스프링 부트 3의 Custom Authentication Provider

by 굿센스굿 2024. 12. 11.
반응형

 

1. 서론

스프링 부트 3는 높은 확장성과 유연성을 가진 인증 및 권한 부여 시스템을 제공합니다. 기본적으로 Spring Security의 AuthenticationProvider 인터페이스를 통해 커스텀 인증 로직을 구현할 수 있습니다. 이는 복잡한 인증 요구사항(예: 다중 인증, 외부 시스템 연동, 특수한 비즈니스 로직 등)에 대응할 수 있는 강력한 도구입니다. 이번 글에서는 Custom Authentication Provider의 기본 개념, 구현 방법, 그리고 실무에서 활용할 수 있는 예시를 살펴보겠습니다.


2. AuthenticationProvider란 무엇인가?

2.1 기본 개념

AuthenticationProvider는 스프링 시큐리티의 핵심 구성 요소 중 하나로, 특정 인증 메커니즘을 정의하는 데 사용됩니다. 이를 통해 사용자 인증을 커스터마이징하거나 기존 인증 흐름을 확장할 수 있습니다.

AuthenticationProvider는 다음의 두 가지 메서드를 제공합니다:

  • authenticate(Authentication authentication): 인증 로직을 처리하며, 성공 시 Authentication 객체를 반환합니다.
  • supports(Class<?> authentication): 이 AuthenticationProvider가 처리할 수 있는 Authentication 객체의 타입을 정의합니다.

2.2 기본 구조

public interface AuthenticationProvider {
    Authentication authenticate(Authentication authentication) throws AuthenticationException;
    boolean supports(Class<?> authentication);
}

3. Custom Authentication Provider 구현하기

3.1 구현 시나리오

예를 들어, 기존의 데이터베이스 기반 인증 외에 외부 API를 통한 인증이 필요하다고 가정해 봅시다. 이 경우, 커스텀 AuthenticationProvider를 통해 외부 API 호출과 사용자 인증을 처리할 수 있습니다.

3.2 코드 구현

3.2.1 CustomAuthenticationProvider 클래스

import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.authentication.BadCredentialsException;

public class CustomAuthenticationProvider implements AuthenticationProvider {

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String username = authentication.getName();
        String password = authentication.getCredentials().toString();

        // 외부 API 호출 예시
        boolean isAuthenticated = callExternalApi(username, password);

        if (!isAuthenticated) {
            throw new BadCredentialsException("Invalid username or password");
        }

        // 인증 성공 시 CustomAuthenticationToken 반환
        return new CustomAuthenticationToken(username, null, List.of(() -> "ROLE_USER"));
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return CustomAuthenticationToken.class.isAssignableFrom(authentication);
    }

    private boolean callExternalApi(String username, String password) {
        // 외부 API 호출 로직 (예: REST API, SOAP, gRPC 등)
        return "testUser".equals(username) && "testPass".equals(password);
    }
}

3.2.2 CustomAuthenticationToken 클래스

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;

public class CustomAuthenticationToken extends UsernamePasswordAuthenticationToken {
    public CustomAuthenticationToken(Object principal, Object credentials, Collection authorities) {
        super(principal, credentials, authorities);
    }
}

4. 실무 활용 예시

예시 1: LDAP 기반 인증

기존 데이터베이스 인증 외에 LDAP를 통해 사용자를 인증해야 하는 경우, CustomAuthenticationProvider를 사용하여 LDAP 서버에 연결하고 인증 결과를 처리할 수 있습니다.

private boolean authenticateWithLdap(String username, String password) {
    // LDAP 서버 연결 및 인증 로직
}

예시 2: 다단계 인증(MFA)

MFA(다중 인증)를 구현해야 할 때, 첫 번째 단계로 기본 인증을 수행하고 두 번째 단계에서 OTP 또는 SMS를 통해 인증하는 로직을 CustomAuthenticationProvider에 추가할 수 있습니다.

if (isMfaRequired(username)) {
    sendOtpToUser(username);
    throw new MfaAuthenticationPendingException("MFA required");
}

예시 3: 소셜 로그인 연동

소셜 로그인(Facebook, Google 등)을 사용하여 외부 OAuth2 공급자를 통해 인증한 결과를 커스텀 프로바이더로 처리할 수 있습니다.

private boolean authenticateWithOAuth2(String token) {
    // 외부 소셜 로그인 API 호출 및 결과 검증
}

5. Spring Security와 Custom Authentication Provider 통합

CustomAuthenticationProvider를 스프링 시큐리티 설정에 등록해야 합니다.

설정 코드

import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;

@Configuration
public class SecurityConfig {

    @Bean
    public AuthenticationProvider customAuthenticationProvider() {
        return new CustomAuthenticationProvider();
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception {
        return configuration.getAuthenticationManager();
    }

    protected void configure(HttpSecurity http) throws Exception {
        http.authenticationProvider(customAuthenticationProvider())
            .authorizeHttpRequests()
            .anyRequest().authenticated();
    }
}

6. 결론

스프링 부트 3의 Custom Authentication Provider는 고도화된 인증 요구사항을 충족하기 위한 강력한 도구입니다. 다양한 시나리오에 맞게 구현하여 애플리케이션의 보안 수준을 높일 수 있습니다. LDAP, MFA, 소셜 로그인과 같은 실무 사례를 통해 AuthenticationProvider를 유연하게 활용하는 방법을 익히고, 프로젝트 요구사항에 맞는 커스텀 인증을 설계해 보세요.

반응형