인프런 커뮤니티 질문&답변

양동우님의 프로필 이미지

작성한 질문수

스프링과 JPA 기반 웹 애플리케이션 개발

회원 가입 컨트롤러

SecurityConfig의 WebSecurityConfigurerAdapter 가 deprecated 되어 아래와 같이 코드를 수정하였는데 괜찮을까요?

작성

·

922

0

 

안녕하세요 강의 잘 듣고 있습니다.

해당 수업을 들으면서 코드를 직접 작성을 하고 있었는데 SecurityConfig의 WebSecurityConfigurerAdapter 가 deprecated가 되어서 인식이 안됬습니다.

그래서 커뮤니티를 통해 어떤 오류가 났는지 다른 회원님의 글을 보고 알게 되어 해당 코드를 인용했음에도 오류가 발생하여 아래와 같이 코드를 수정을 했는데 괜찮을까요?

 

package com.studyolle.config;

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.web.SecurityFilterChain;
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;

@Configuration      //스프링 설정 클래스
@EnableWebSecurity  //웹 보안 활성화, 웹 보안 설정 재정의
public class SecurityConfig {

    @Bean
    SecurityFilterChain filterChain(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
        RequestMatcher[] matchers = {
                new MvcRequestMatcher(introspector, "/"),
                new MvcRequestMatcher(introspector, "/login"),
                new MvcRequestMatcher(introspector, "/sign-up"),
                new MvcRequestMatcher(introspector, "/check-email"),
                new MvcRequestMatcher(introspector, "/check-email-token"),
                new MvcRequestMatcher(introspector, "/email-login"),
                new MvcRequestMatcher(introspector, "/check-email-login"),
                new MvcRequestMatcher(introspector, "/login-link"),
                new MvcRequestMatcher(introspector, "/profile/*")
        };

        //보안 요청에 대한 권한 및 역활 설정
        http.authorizeRequests()
                //배열에 있는 경로들에 대한 모든 요청을 허용
                .requestMatchers(matchers).permitAll()
                //지저오딘 경로외의 모든 요청은 인증된 사용자만 접근할 수 있도록 함
                .anyRequest().authenticated();

        // POST에 대한 별도 조건을 설정하려면 추가 코드 필요

        return http.build();
    }
}

답변 2

0

WebSecurityConfigurerAdapter 가 deprecated가 되었습니다.

관련 문제는 아래와 같이 해결 하실 수 있습니다.

private final AuthenticationService authenticationService;
private final DataSource dataSource;

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests()
.mvcMatchers("/", "login", "/check-email", "/check-email-token", "/email-login", "/check-email-login",
"/login-link","/sign-up").permitAll()
.mvcMatchers(HttpMethod.GET, "/profile/*").permitAll()
.mvcMatchers("/css/**, /js/**, /images/**").permitAll()
.anyRequest().authenticated(); // 로그인 해야만 접근 가능

http.formLogin()
.loginPage("/login").permitAll()
.defaultSuccessUrl("/");
//.failureUrl("/login-error");

http.logout()
.logoutSuccessUrl("/");

http.rememberMe()
.userDetailsService(authenticationService)
.tokenRepository(tokenRepository());

return http.build();
}

@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().mvcMatchers("/images/**", "/favicon.ico","node_modules/**");
}

또한가지 AccountService와 SecurityConfig가 서로 의존성을 가지고 있기 때문에 순환 참조 문제가 발생할 수 있습니다.

이럴 경우 구조적으로 변경이 필요한데요

Lazy Initialzation 으로 해결할수도 있지만 구조적으로 변경하는게 가장 좋아 보입니다.

인증과관련된 로직을 별도의 클래스로 분리하여 사용하는 방법을 추천 드립니다.

 

@Component
@RequiredArgsConstructor
public class AuthenticationService implements UserDetailsService {

private final AccountRepository accountRepository;

@Override
public UserDetails loadUserByUsername(String emailOrNickname) throws UsernameNotFoundException {

Account account = accountRepository.findByEmail(emailOrNickname);
if (account == null) {
account = accountRepository.findByNickname(emailOrNickname);
}
if ( account == null ) {
throw new UsernameNotFoundException(emailOrNickname);
}

return new UserAccount(account);
}

}

도움이 되었으면 좋겠네요

 

양동우님의 프로필 이미지
양동우
질문자

앗 감사합니다!

혹시 gradle로 하셨나요? maven으로 하니까 AuthenticationService 이부분에서 에러가 나서요,.

0

백기선님의 프로필 이미지
백기선
지식공유자

글쎄요. 저 모든 요청을 permitAll로 허용하는게 맞는건지 모르겠네요. 하지만 사용하신 메서드는 맞는것 같습니다. 이전 설정을 거의 그대로 쓰고 싶다면

SecurityFilterChain securityFilterChain(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {

스프링 문서 (https://docs.spring.io/spring-security/reference/5.8/migration/servlet/config.html) 에서 이걸 쓰면 된가고 하니까요.

이전에 다른 질문에도 답을 드렸지만, 강의를 들으시는 중에는 일단 강의에서 사용했던 스프링 버전을 사용해 주시는게 좋겠습니다. 추후에 추가 수업으로 스프링 버전 올리는 방법에 대해 추가해 놓겠습니다.

감사합니다.