AuthenticationProvider는 Spring Security에서 사용자 인증 로직을 처리하는 인터페이스입니다. 사용자 인증에 필요한 로직을 직접 정의하여, 사용자의 신원을 검증하고 인증된 사용자 정보를 반환하는 역할을 합니다. Spring Security는 기본적으로 다양한 인증 방식을 제공하지만, AuthenticationProvider를 구현하면 특정 요구사항에 맞는 맞춤형 인증 방식을 사용할 수 있습니다.

AuthenticationProvider의 역할

  1. 인증 처리: AuthenticationProvider는 사용자가 제공한 인증 정보(ID, 비밀번호 등)를 검증하여 인증 여부를 결정합니다.
  2. 맞춤형 인증 방식 구현: 기본적으로 제공되는 UserDetailsService를 사용하지 않고, 데이터베이스 이외의 시스템(예: LDAP, 외부 API)이나 커스텀 인증 방식을 사용할 때 유용합니다.
  3. 다중 인증 지원: 여러 AuthenticationProvider를 설정하여 다양한 인증 방식을 지원할 수 있습니다.

AuthenticationProvider의 주요 메서드

  1. authenticate(Authentication authentication):

    • 사용자의 인증 정보를 기반으로 인증을 수행하는 메서드입니다.
    • 성공적으로 인증되면 Authentication 객체를 반환하고, 실패하면 예외를 던집니다.
  2. supports(Class<?> authentication):

    • 특정 Authentication 타입을 지원하는지 여부를 결정하는 메서드입니다.
    • 이 메서드를 통해 여러 인증 제공자 중 현재 AuthenticationProvider가 처리할 수 있는 인증 타입인지 확인합니다.

AuthenticationProvider 구현 예제

아래는 사용자 ID와 비밀번호를 확인하는 간단한 AuthenticationProvider 구현 예제입니다.

import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

public class CustomAuthenticationProvider implements AuthenticationProvider {

    private final UserDetailsService userDetailsService;

    public CustomAuthenticationProvider(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String username = authentication.getName(); // 사용자 ID
        String password = authentication.getCredentials().toString(); // 사용자 비밀번호

        // UserDetailsService를 통해 사용자 정보 조회
        UserDetails userDetails;
        try {
            userDetails = userDetailsService.loadUserByUsername(username);
        } catch (UsernameNotFoundException e) {
            throw new AuthenticationException("User not found") {};
        }

        // 사용자 비밀번호 검증
        if (!password.equals(userDetails.getPassword())) {
            throw new AuthenticationException("Invalid password") {};
        }

        // 인증 성공 시 UsernamePasswordAuthenticationToken 반환
        return new UsernamePasswordAuthenticationToken(
                userDetails.getUsername(),
                userDetails.getPassword(),
                userDetails.getAuthorities()
        );
    }

    @Override
    public boolean supports(Class<?> authentication) {
        // UsernamePasswordAuthenticationToken 타입의 인증 요청을 지원
        return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
    }
}

코드 설명

  • authenticate 메서드: 사용자의 usernamepassword를 받아 UserDetailsService에서 사용자 정보를 조회합니다. 사용자의 비밀번호가 일치하면 인증이 성공된 Authentication 객체를 반환하고, 일치하지 않으면 예외를 던집니다.
  • supports 메서드: 이 AuthenticationProviderUsernamePasswordAuthenticationToken 타입의 인증 요청을 처리할 수 있음을 나타냅니다.

AuthenticationProvider 등록하기

Spring Security 설정 클래스에서 AuthenticationProvider를 등록하여 사용할 수 있습니다.

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    private final CustomAuthenticationProvider customAuthenticationProvider;

    public SecurityConfig(CustomAuthenticationProvider customAuthenticationProvider) {
        this.customAuthenticationProvider = customAuthenticationProvider;
    }

    protected void configure(AuthenticationManagerBuilder auth) {
        // CustomAuthenticationProvider 등록
        auth.authenticationProvider(customAuthenticationProvider);
    }

    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()
            .and()
            .formLogin();
    }
}

요약

  • AuthenticationProvider사용자 인증 로직을 커스터마이징하기 위해 사용됩니다.
  • authenticate 메서드에서 사용자 인증 로직을 구현하고, supports 메서드로 처리할 수 있는 인증 타입을 지정합니다.
  • Spring Security 설정에서 AuthenticationProvider를 등록하여 애플리케이션의 인증 절차에 적용할 수 있습니다.

+ Recent posts