SecurityConfig WebSecurityConfigurerAdapter 상속받지 않고 구현

Crow·2022년 6월 25일
1

Security

목록 보기
3/7

Spring security 5.7.X버전 부턴 SecurityConfig 클래스에
WebSecurityConfigurerAdapter 를 상속받아 Configure()로 사용하는게 불가능해짐

따라서 @Bean방식으로 사용해야함

    @Bean
    public InMemoryUserDetailsManager user() {
        UserDetails user = User.withUsername("user1")
                //비밀번호 1111 Encode함
                .password("$2a$10$yxmlE1fKRduWxvTqrThx4OByZeY9ZUxdTRoloNn262TkcfAbotyke")
                .roles("USER").build();

        return new InMemoryUserDetailsManager(user);
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/sample/all").permitAll()
                .antMatchers("/sample/member").hasRole("USER");

        http.formLogin();

        return http.build();
    }

IntellJ IDE에서
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {코드를 사용하면 (HttpSecurity http)에서 자동 주입을 할 수 없습니다. 'HttpSecurity' 타입의 bean을 찾을 수 없습니다. 라는 오류가 발생함


해결완료

package com.crow.oauthex.config;

import lombok.extern.log4j.Log4j2;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@Log4j2
@EnableWebSecurity
public class SecurityConfig {

/*    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        return (web) -> web.ignoring()
                .mvcMatchers("/node_modules/**")
                .requestMatchers(PathRequest.toStaticResources().atCommonLocations());
    }*/

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


/*    @Bean
    public InMemoryUserDetailsManager user() {
        UserDetails user = User.withUsername("user1")
                //비밀번호 1111 Encode함
                .password("$2a$10$yxmlE1fKRduWxvTqrThx4OByZeY9ZUxdTRoloNn262TkcfAbotyke")
                .roles("USER").build();

        return new InMemoryUserDetailsManager(user);
    }*/

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/sample/all").permitAll()
                .antMatchers("/sample/member").hasRole("USER");

        http.formLogin();
        http.csrf().disable();
        http.logout();

        return http.build();
    }


}

위 코드처럼 @EnableWebSecurity 어노테이션을 클래스에 선언해주면 'HttpSecurity' 타입의 bean을 찾을 수 없습니다. 오류 해결 가능함


2022 08 29 내용에 보완이 필요해서 추가

위의 내용은 그냥 spring.io를 보면 당연히 알수있는 내용이었다

중요한건 AuthenticationManager 이 인터페이스를 사용하는
인증 부분이다.

이 부분을

package com.github.studym.studymarathon.config;

import com.github.studym.studymarathon.config.security.filter.ApiCheckFilter;
import com.github.studym.studymarathon.config.security.filter.ApiLoginFilter;
import com.github.studym.studymarathon.config.security.handler.ApiLoginFailHandler;
import com.github.studym.studymarathon.config.security.handler.MemberLoginSuccessHandler;
import com.github.studym.studymarathon.config.security.service.AuthUserDetailsService;
import com.github.studym.studymarathon.config.security.util.JWTUtil;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@Log4j2
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig {


    @Autowired
    private AuthUserDetailsService userDetailsService;

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


    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
/*        http.authorizeRequests().antMatchers("/api/title").permitAll();
        http.authorizeRequests().antMatchers("/api/main").hasRole("USER");
        http.authorizeRequests().antMatchers("api/admin").hasRole("ADMIN");*/


        http.formLogin();
        http.csrf().disable();
        http.logout();
        http.oauth2Login().successHandler(successHandler());
        http.rememberMe().tokenValiditySeconds(60 * 10).userDetailsService(userDetailsService);//10분짜리 로그인 유지 토큰

        AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class);



        http.addFilterBefore(apiCheckFilter(), UsernamePasswordAuthenticationFilter.class);
        http.addFilterBefore(apiLoginFilter(authenticationManager), UsernamePasswordAuthenticationFilter.class);


        return http.build();
    }

    @Bean
    public MemberLoginSuccessHandler successHandler() {
        return new MemberLoginSuccessHandler(passwordEncoder());
    }


    @Bean
    public ApiLoginFilter apiLoginFilter(AuthenticationManager authenticationManager) throws Exception {

        ApiLoginFilter apiLoginFilter = new ApiLoginFilter("/api/login", jwtUtil());
        apiLoginFilter.setAuthenticationManager(authenticationManager);

        apiLoginFilter.setAuthenticationFailureHandler(new ApiLoginFailHandler());

        return apiLoginFilter;
    }

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


}

SecurityFilterChain() 메서드의 안에 선언하고
HttpSecurity를 이용해서 getSharedObject를 통해 얻어옴

http.getSharedObject(AuthenticationManager.class);

참조
https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter

https://cafe.naver.com/gugucoding?iframe_url_utf8=%2FArticleRead.nhn%253Fclubid%3D28363273%2526articleid%3D7820%2526commentFocus%3Dtrue

profile
어제보다 개발 더 잘하기 / 많이 듣고 핵심만 정리해서 말하기 / 도망가지 말기 / 깃허브 위키 내용 가져오기

0개의 댓글