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

msun0215님의 프로필 이미지

작성한 질문수

스프링부트 시큐리티 & JWT 강의

Spring Boot 최신 버전(3.1.5)에 대하여..

작성

·

2.8K

·

수정됨

15

질문은 아니지만 최근에 이 강의를 들으시는 분들에게 조금이나마 팁이 될까 적어봅니다.

강사님께서 강의하신 3년전에는 2.3.* 버전이고,

강의자료 github version 3에서도 2.7.* 버전이라 최신 버전인 3.1.*에는 안맞는 것들이 조금은 많았습니다.

대부분 Spring Boot 3.*대로 업데이트 되면서 많은게 바뀌었더라고요.

 

그래서 작업하면서 최신 버전에서는 이렇게 하면 오류가 해결되는구나에 대해서 기억나는대로 설명해드리고자 합니다.


<강사님 github Version3 SecurityConfig.java에서 filterChain 발췌>

@Bean
	SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		return http
				.csrf().disable()
				.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
				.and()
				.formLogin().disable()
				.httpBasic().disable()
				.apply(new MyCustomDsl()) // 커스텀 필터 등록
				.and()
				.authorizeRequests()
				.antMatchers("/api/v1/user/**")
				.access("hasRole('USER') or hasRole('MANAGER') or hasRole('ADMIN')")
				.antMatchers("/api/v1/manager/**")
				.access("hasRole('MANAGER') or hasRole('ADMIN')")
				.antMatchers("/api/v1/admin/**")
				.access("hasRole('ADMIN')")
				.anyRequest().permitAll()
				.and().build();
	}

 


  1. 람다 표현식 사용 권장

    httpServlet 오브젝트에 처음 적용시키는 csrf부터 빨간줄이 떴습니다.

     

    설명줄을 확인해보니 스프링 시큐리티 6.1 버전부터 deprecated되었다고 하네요.

    자동완성을 확인해보니 밑에 있던 기존 csrf는 밑줄이 그어져있고 대신 안에 파라미터를 넣어줘야 한다고 되어있네요. 이런식으로 파라미터를 요구하는 식에는 모두 람다식 표현을 사용했습니다.

     

    http.csrf(cs-> cs.disable())     .sessionManagement(s->s.sessionCreationPolicy(SessionCreationPolicy.STATELESS))         .formLogin(f->f.disable())             .httpBasic(h->h.disable())                 .apply(new MyCustomDs1())

    람다식 표현은 매개변수->{매개변수 표현식} 으로 표현할 수가 있습니다. 자세한 내용은 구글링 하시면 잘 나오실 겁니다.

 


 

  1. .and() Method 삭제
    http의 csrf, sessionManagement, formLogin, httpBasic을 disable로 하고 .and()로 한번 끊고 나서 다음 설정을 하는 구문입니다.

    자동완성을 확인해보니 and() 메소드는 완전히 삭제가 된 모양이군요.
    and()의 역할은 다중 보안 설정 시에 사용하는 메소드입니다. SecurityConfig.java 파일에서는 처음으로 보안 설정을 한 후에 권한 설정을 하는 방식으로 진행되었습니다. 이에 따라 and() 구문으로 보안설정과 권한설정을 나누었으나, and() 메소드가 삭제됨에 따라 나누는 방법에 대해서 많은 고민을 했던 것 같습니다.

     



    <수정 내용>
    인프런 AI 인턴으로부터 받은 답변의 내용을 살펴보면



    apply() 메소드 뒤에 메소드 체이닝으로 붙여서 람다 표현식으로 하면 권한이 생성된다고 되어있습니다.


    한 번 해보시죠.

    빨간색 줄을 보면 authorizeHttpRequests 메소드가 'MyCustomDs1' 이라는 커스텀 필터 클래스의 메소드라고 인식하고, MyCustomDs1 필터 내에 authorizeHttpRequests라는 메소드가 존재하지 않음으로 오류를 띄워주는 것이라고 할 수 있겠습니다.

     


    이에 대해, 제 방식이 정답인지는 모르겠으나 이런식으로 해결했습니다.

        http.csrf(cs-> cs.disable())    // 보안 설정
            .sessionManagement(s->s.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                 .formLogin(f->f.disable())
                     .httpBasic(h->h.disable())
                         .apply(new MyCustomDs1());
    
            http.authorizeHttpRequests(authorize-> {     // 권한 부여
                        // authorizeRequests가 deprecated됨에 따라 authorizeHttpRequests 사용 권장
    ...
                       
            // /user, /manager, /admin으로 들어가도 /loginForm으로 접근하도록
            return http.build();

    ① 보안 설정에 대한 내용을 HttpServlet 오브젝트인 http에 한번 추가를 시키고,
    ② 메소드 체이닝을 끊어낸 다음,
    ③ 권한 부여에 대한 내용을 추가했습니다.




  2. 권한 부여 방식
    ① authorizeRequests deprecated
    authorizeRequests 메소드도 설명란을 보면 어노테이션으로 Deprecated가 걸린 것을 볼 수 있습니다.
    자동완성으로 확인을 해보자면
    스크린샷 2023-11-17 172520.png
    authorizeHttpRequests() 메소드를 람다식 표현으로 쓰라고 되어 있네요.

    ② antMatchers deprecated
    antMatchers는 흔적도 없이 사라졌나 봅니다..

    requestMatchers() 메소드를 사용하시면 되겠습니다.

    ③ hasAnyRole() 내의 parameter format 변경
    기존에는 hasAnyRole() 파라미터로 ROLE_USER, ROLE_ADMIN 이런식으로 앞에 ROLE_을 붙여서 권한을 부여했지만, Spring Security가 업데이트 되면서 hasAnyRole 메소드에서 권한을 부여할 때 각 role마다 앞에 자동으로 'ROLE_'을 붙여줍니다. 즉, 기존 방식대로 사용하다 보면 httpServlet 입장에서는 'ROLE_ROLE_USER', 'ROLE_ROLE_ADMIN' 이런식으로 인식하게 되어서 권한을 부여받지 못하는 부분이 있었습니다.

 

 

대략 이렇게 정리를 마치겠습니다.
Spring같은 Framework의 큰 장점이자 단점은 업데이트가 수시로 된다는 점인데요.
업데이트가 되면서 사용하는 데에 조금 더 편안해지겠지만, 이에 대해 인지하지 못한다면 사용할 수 없다는 점이 아닐까 생각됩니다.
긴 글 읽어주셔서 감사하고, 저와 이 글을 읽으신 모든 분들의 코딩 실력이 한 발자국 더 앞설 수 있기를 기도하겠습니다.

제가 작업한 프로젝트도 github에 올려놨으니 확인이 필요하시다면 한번씩 방문해주세요~
http://github.com/msun0215/jwt.git

 

오늘의 결론

① Spring 공식 홈페이지 업데이트 될때마다 찾아가서 확인해보자

② 영어 공부 열심히 하자

 

답변 5

0

존경합니다

0

개추

0

사랑합니다

0

글 잘읽었습니다.

0

hasAnyRole()에 ROLE 붙는걸 몰라서 엄청 해맸네요 덕분에 잘 해결했습니다 진짜 감사합니다!!

msun0215님의 프로필 이미지

작성한 질문수

질문하기