본문 바로가기
SpringBoot/SpringSecurity

[이슈] AuthenticationProvider 인터페이스 구현 후 적용되지 않는 상황 처리

by se0nghyun2 2023. 10. 19.

SpringSecurityConfig 파일

@Configuration
@RequiredArgsConstructor
@EnableWebSecurity
public class SpringSecurityConfig {

    private final MemberService memberService;
    private final PasswordEncoder bCryptPasswordEncoder;
    private final CustomJwtProvider customJwtProvider;
    private final AuthenticationConfiguration authenticationConfiguration;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
         http
                .httpBasic().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) //JWT토큰 사용하므로 세션사용 X
                .and()
                .csrf(csrf -> csrf.disable())
                .cors(cors -> cors.disable())
                .headers(headers -> headers.frameOptions().disable())
                .authorizeHttpRequests(authorize -> authorize
                        .requestMatchers(new AntPathRequestMatcher("/lib/admin/**")).hasAnyAuthority(Role.ADMIN.getRoleValue())    //인가권한이 ADMIN인 경우만 가능
                        .requestMatchers(new AntPathRequestMatcher("/lib/member/signup")).permitAll()                              //회원가입 요청은 익명 사용자 가능
                        .requestMatchers(new AntPathRequestMatcher("/lib/member/**")).hasAnyAuthority(Role.MEMBER.getRoleValue())  //그 외 기능은 인간권한 MEMBER인 경우만 가능
                        .anyRequest().authenticated() //어떠한 요청이든 인증 필요
                )
                .authenticationProvider(authenticationProvider()) //커스터마이징한 provider세팅
                .addFilterBefore(new JwtAuthenticationFilter(authenticationManager(), customJwtProvider), UsernamePasswordAuthenticationFilter.class)
                .addFilterBefore(new JwtAuthorizationFilter(authenticationManager(), customJwtProvider, memberService), BasicAuthenticationFilter.class)
                .formLogin(login -> login.disable())
                .exceptionHandling(authenticationManger -> authenticationManger
                        .authenticationEntryPoint(new CustomAuthenticationEntryPoint()) //인증Exception 처리
                        .accessDeniedHandler(new CustomAccessDeniedHandler()) //AccessDeniedException 처리
                )
                 ;
                return http.build();
    }


    @Bean
    public AuthenticationProvider authenticationProvider(){
        return new CustomAuthenticationProvider(memberService,bCryptPasswordEncoder);
    }


    @Bean
    public AuthenticationManager authenticationManager() throws Exception { //AuthenticationManager Bean등록
        return this.authenticationConfiguration.getAuthenticationManager();
    }
}

 

 

AuthenticationProvider 구현체

@Slf4j
@Component
@RequiredArgsConstructor
public class CustomAuthenticationProvider implements AuthenticationProvider {

    private final MemberService memberService;
    private final PasswordEncoder bCryptPasswordEncoder;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        log.info("CustomAuthenticationProvider.authenticate start");

        String id = authentication.getPrincipal().toString();
        String pwd = authentication.getCredentials().toString();

        UserDetails ud= memberService.loadUserByUsername(id);

        //비밀번호 일치 여부 확인
        checkPassword(pwd,ud.getPassword());

        Collection<? extends GrantedAuthority> authorities = ud.getAuthorities();

        return new UsernamePasswordAuthenticationToken(ud,pwd,authorities);
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return true;
    }

    private void checkPassword(String inputPwd, String dbPwd){
            if ( !bCryptPasswordEncoder.matches(inputPwd,dbPwd) ){
                throw new PassWordMisMatchException(RESULTCODE.RESULT_PASSWORDMISMATCH);
            }
    }
}

 

 

위와 같이 세팅하였으나 커스터마이징한 구현체의 메소드가 실행되지 않았다...

 

 


개선

AuthenticationProvider 구현체

@Slf4j
//@Component
@RequiredArgsConstructor
public class CustomAuthenticationProvider implements AuthenticationProvider {

    private final MemberService memberService;
    private final PasswordEncoder bCryptPasswordEncoder;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        log.info("CustomAuthenticationProvider.authenticate start");

        String id = authentication.getPrincipal().toString();
        String pwd = authentication.getCredentials().toString();

        UserDetails ud= memberService.loadUserByUsername(id);

        //비밀번호 일치 여부 확인
        checkPassword(pwd,ud.getPassword());

        Collection<? extends GrantedAuthority> authorities = ud.getAuthorities();

        return new UsernamePasswordAuthenticationToken(ud,pwd,authorities);
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return true;
    }

    private void checkPassword(String inputPwd, String dbPwd){
            if ( !bCryptPasswordEncoder.matches(inputPwd,dbPwd) ){
                throw new PassWordMisMatchException(RESULTCODE.RESULT_PASSWORDMISMATCH);
            }
    }
}

@Component 제거하니 구현체의 메소드들이 실행된다.


왜???

 

아직 못 찾음.. 일단 넘어가고 추후 확인해볼 예정