[Spring Security] Multiple UserDetailsService

du·2022년 6월 7일
0

Spring

목록 보기
1/6

토이프로젝트를 만들면서 서로 다른 테이블의 사용자 권한 인증을 위한 Spring Security 를 적용에 대해 정리한 글이다.

DB 설계시 일반사용자(Member)와 서비스 제공자(Helper)에 필요한 필드가 각각 달라 따로 분리하여 설계했는데 Spring Security 를 적용하고 권한 인증시 문제가 발생하였다.
하나의 스프링 애플리케이션에서 여러개의 UserDetailsService 구현체를 Spring Security 에 등록해줘도 Spring Security 에서는 둘 중 하나만 인증 과정에 참여하고 나머지 하나는 무시된다고 한다.
하여 다음과 같이 해결했다.

  1. HelperUserDetailService 와 MemberUserDetailService 를 작성한다.
  2. HelperSecurityConfig 와 MemberSecurityConfig 를 각각 작성하고 위에서 작성한 UserDetailsService 구현체들을 주입하여 권한 인증을 진행한다.

예시

HelperSecurityConfig

@EnableWebSecurity
@RequiredArgsConstructor
@Order(Ordered.HIGHEST_PRECEDENCE)
public class HelperSecurityConfig extends WebSecurityConfigurerAdapter {

    private final HelperUserDetailService helperUserDetailService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .httpBasic()
                .and()
                .requestMatchers()
                .antMatchers("/helpers/**")
                .and()
                .authorizeRequests()
                .antMatchers("/helpers/login", "/helpers/logout", "/", "/helpers/authenticate").permitAll()
                .anyRequest().authenticated();
		...
    }
    
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(helperUserDetailService).passwordEncoder(passwordEncoder());
    }
}

MemberSecurityConfig

@EnableWebSecurity
@RequiredArgsConstructor
public class MemberSecurityConfig extends WebSecurityConfigurerAdapter {

    private final MemberUserDetailsService memberUserDetailsService;

    @Override
    public void configure(WebSecurity web) throws Exception {
   		...
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/login", "/logout", "/", "/authenticate").permitAll()
            .anyRequest().hasRole("USER");

		...
    }
    
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(memberUserDetailsService).passwordEncoder(passwordEncoder);
    }
}

/helpers 로 들어오는 모든 요청에 대해서는 HelperSecurityConfig 처리, 그 외의 모든 요청에 대해서는 MemberSecurityConfig 에서 처리 하기 위해 @Order(Ordered.HIGHEST_PRECEDENCE) 를 통해 작성한 security config 의 우선순위를 정해줬다.

참고 자료

0개의 댓글