Spring Security 6 - 컴포넌트 빈 정의

AuthenticationManager

내부적으로 AuthenticationProvider를 사용해 인증하고 인증된 Authentication 인스턴스를 반환합니다.

AuthenticationProvider에서 던져진 예외에 대한 처리도 담당합니다.

구현체로는 ProviderManager가 있습니다. 단순히 정상적인 Authentication이 반환되거나 예외가 던져질 때까지 주입된 AuthenticationProvider들을 순차 실행합니다.

AuthenticationProvider

내부로직을 통해 인증된 Authentication 객체를 생성합니다.
(isAuthenticated=true, 일반로그인 섹션 UsernamePasswordAuthenticationFilter에서 추가설명 예정)

기본 주입 빈으로는 DaoAuthenticationProvider가 있습니다.
UserDetailsService 빈과 PasswordEncoder 빈을 주입받습니다.
내부적으로 일반로그인 섹션 UsernamePasswordAuthenticationFilter에서 생성되는 UsernamePasswordAuthenticationToken으로 로직을 수행합니다. 자세한 과정은 해당 포스팅에서 설명하겠습니다.

UserDetailsService

기본 구현체는 inMemoryUserDetailsManager 입니다.

Using generated security password: 1da815e7-d706-4428-be19-485e304a8780

This generated password is for development use only. Your security configuration must be updated before running your application in production.

위 처럼 기본 어드민 계정이 생성되며 내부적으로 HashMap으로 관리됩니다.

JdbcUserDetailsManager 구현체도 제공하지만 직접 쿼리를 작성해야하고 디비 의존도가 높아지기 때문에 권장드리지 않습니다.

username을 기반으로 사용자 정보를 가져오는 인터페이스입니다.

ProviderManagerDaoAuthenticationProvider에서 해당 컴포넌트를 사용합니다.

해당 인터페이스에서 반환된 UserDetailsAuthenticationProvider에서 Authentication 인스턴스를 생성합니다.

자바 이전 버전에서는 가독성을 위해 익명 클래스 정의보다는 UserDetailsService의 구현체를 정의해주어야할 필요성이 있었지만
람다 표현식이 가능해지면서 다음과 같은 방식으로 작성이 가능해졌습니다.

    @Bean
    public UserDetailsService userDetailsService() {
        return username -> {
            UserEntity userEntity = userRepository.findByUsername(username)
                .orElseThrow(() -> new RuntimeException("로그인 정보가 존재하지 않습니다."));
            return new UserWithPassword(userEntity.getUsername(), userEntity.getPassword(),
                userEntity.getRoles());
        };
    }

PasswordEncoder

로그인 시 비밀번호를 암호화 후 대조하기 위해 사용하는 인터페이스 입니다.

비밀번호 단방향 암호화를 목적으로 개발된 BCryptPasswordEncoder구현체를 제공합니다.

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

커밋 링크

 

1. Spring Security 컴포넌트 · jsween5723/spring-security-tistory@d18eae9

jsween5723 committed Aug 29, 2024

github.com

 

 

커밋링크처럼 PasswordEncoder와 UserDetailsService Bean이 등록돼있으면

DaoAuthenticationProvider Bean을 생성할 수 있어 정상적으로 스프링 시큐리티가 동작하는 것을 확인할 수 있습니다.

 

아래 글을 참고하여 빈은 필터체인과 분리해 정의하는 편이 좋습니다.

 

 

* 빈 생성 필터체인 Configuration과 분리

개요간혹 필터체인에서 참조하는 컴포넌트에서 PasswordEncoder 등 필터체인이 정의된 Configuration에 정의된 Bean을 사용해야해 문제가 발생하는 경우가 있다. 바로 하위가 아니더라도 UserService라던지.

sween.tistory.com

 

참고:

https://docs.spring.io/spring-security/reference/servlet/authentication/architecture.html

 

Servlet Authentication Architecture :: Spring Security

ProviderManager is the most commonly used implementation of AuthenticationManager. ProviderManager delegates to a List of AuthenticationProvider instances. Each AuthenticationProvider has an opportunity to indicate that authentication should be successful,

docs.spring.io

 

반응형
LIST