Spring Boot์ ๋ฒ์ ์ด 3.x๋ก ์ฌ๋ผ๊ฐ๋ฉด์ Spring Security + JWT๋ฅผ ์ฌ์ฉํ์ฌ ๋ก๊ทธ์ธ์ ๊ตฌํํ ๋ SecurityConfig
๋ฅผ ์์ฑํ๋ ๋ฐฉ์์ด ์กฐ๊ธ ๋ฌ๋ผ์ก๋ค!
๐ Spring Boot 3.x
securityConfig
์ ๋ํ ์์ธํ ๊ฐ๋ ๋ค์ ์๋ ํฌ์คํ ์ ์ฐธ๊ณ ํด์ฃผ์ธ์.
์๋ Spring Boot 2.x ๋ฒ์ ์์๋
JwtVerificationFilter
์ JwtAuthenticaitonFilter
๋๊ฐ๋ฅผ ๋ง๋ค์ด์ ํํฐ์ ์ถ๊ฐํด์ฃผ๊ธฐ ์ํด
AbstractHttpConfigurer
๋ฅผ ๊ตฌํํ CustomFilterConfigurer
๋ฅผ ๋ง๋ค์ด ๊ทธ ์์์ ๋ ํํฐ๋ฅผ ์ถ๊ฐํด์ค ํ,
securityFilterChain
์ http.apply(customFilterConfigurer)
๋ก ์ถ๊ฐํด์ฃผ์์๋ค.
ํ์ง๋ง ๋ฒ์ ์ด ์ฌ๋ผ๊ฐ๋ฉด์ apply()
๋ฉ์๋๋ deprecated๋์ด์ ๋ชป์ฐ๋ ์ํ๊ฐ ๋์ด ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ์ถ๊ฐํด์ฃผ์ด์ผ ํ๋ค.
๐ก deprecated๋ ๋ฉ์๋๋ค ์ฐธ๊ณ
์ฌ๋ฌ๊ฐ์ง ์ฐพ์๋ณด๋ configurer์ ๋น Customizer ๋ฉ์๋๋ฅผ ๋ฃ์ด๋๊ณ
.with() ๋ฉ์๋๋ก configurer, customizer ์ด๋ ๊ฒ ๋ฃ์ด์ฃผ๋ฉด ๋๋ค๋ ๊ธ์ด ์์ด์ ์๋์ ๊ฐ์ด ํด๋ณด์๋ค.
ํ์ง๋ง ๋์์ค๋ ๊ฒ์ ์๋ฌ
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'securityFilterChain' defined in class path resource [com/jp/backend/global/config/SecurityConfig.class]: Failed to instantiate [org.springframework.security.web.SecurityFilterChain]: Factory method 'securityFilterChain' threw exception with message: The Filter class com.jp.backend.auth.filter.JwtVerificationFilter does not have a registered order and cannot be added without a specified order. Consider using addFilterBefore or addFilterAfter instead.
์๋ฌ ๋ฉ์ธ์ง๋ ๋์ถฉ JwtVerificationFilter ํด๋์ค์ ๋ฑ๋ก๋ ์์๊ฐ ์์ผ๋ฉฐ, ๋ช ์์ ์ธ ์์ ์์ด๋ ํํฐ๋ฅผ ์ถ๊ฐํ ์ ์๋ค๊ณ ์ง์ ํ๊ณ ์์๋ค.
๊ทธ๋์ ์ด๋ป๊ฒ ํด์ผํ๋ ๊ณ ๋ฏผํ๋ค๊ฐ
๊ณต์ ๋ฌธ์์์๋ ์๋์ ๊ฐ์ ๋ฐฉ๋ฒ์ผ๋ก custom DSL์ ์ ์ฉํ๋ผ๊ณ ๋์์๋ค.
๊ธฐ๋ณธ๊ฐ์ ๋นํ์ฑํ ํ ๋ ค๋ฉด ์๋์ ๊ฐ์ด ํ๋ผ๊ณ ๋์ด์์๊ธฐ์
์ผ๋จ ๋๋ customizer ๊ฐ์ด ์๊ธฐ ๋๋ฌธ์ ์ ๊ณต์ ๋ฌธ์๋ฅผ ์ฐธ๊ณ ํ์ฌ ์๋์ ๊ฐ์ด ๊ตฌํํด๋ณด์๋ค.
์ด๋ ๊ฒ ํ๋๋ฐ ์ผ๋จ run์ ์ ๋์๊ฐ๊ณ ..!! ํ์ง๋ง ํํฐ ๋ก๊ทธ๋ฅผ ๋ณด๋
์๋๋ผ๋ฉด ์ ๋ก๊ทธ์์ ํํฐ ๋ค์
com.jp.backend.auth.filter.JwtAuthenticationFilter@2b86e36b
, com.jp.backend.auth.filter.JwtVerificationFilter@3973fe2b
๋ ํํฐ๊ฐ ๋ค์ด๊ฐ์ผํ๋๋ฐ ์๋ค์ด๊ฐ๋จ ๋ง์
๋๋ค์
INFO 25648 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@530e500c, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@1c3b4de1, org.springframework.security.web.context.SecurityContextHolderFilter@66e6e5e9, org.springframework.security.web.header.HeaderWriterFilter@c310aa3, org.springframework.web.filter.CorsFilter@1925b113, org.springframework.security.web.authentication.logout.LogoutFilter@7abc838a, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@654ab198, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@6b334a1, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@eaa901a, org.springframework.security.web.session.SessionManagementFilter@5536542e, org.springframework.security.web.access.ExceptionTranslationFilter@740ddb41, org.springframework.security.web.access.intercept.AuthorizationFilter@7afffc81]
์ฐ์์์์ฅใฑ
๊ทธ๋์ ๋ ์ด์ฐ์ ์ฐ ์ฐพ์๋ณด๋ค๊ฐ ์ด๋ฒ์๋ configuer ํด๋์ค๋ฅผ ๋ฐ๋ก ๋ง๋ค์ง ์๊ณ securityFilterChain ์ฝ๋ ์์ ๊ด๋ จ ๋ด์ฉ์ ๋ฃ์ด์ค ํ์
.addFilterBofore
๋ก ํํฐ๋ฅผ ์ถ๊ฐํด์ฃผ์๋จ
์ด๋ ๊ฒ ํ๊ณ run์ ํ๋๋ ์ผ๋จ ์ ๋์๊ฐ๊ธฐ๋ ํ๊ณ ํํฐ๋ ์๋์ ๊ฐ์ด ์ ์ถ๊ฐ๊ฐ ๋ ๋ชจ์ต์ด๋ค.
Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@7abc838a, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@2ee91bdf, org.springframework.security.web.context.SecurityContextHolderFilter@7d4bb16b, org.springframework.security.web.header.HeaderWriterFilter@56a7f57f, org.springframework.web.filter.CorsFilter@1a034bbc, org.springframework.security.web.authentication.logout.LogoutFilter@2179127d, com.jp.backend.auth.filter.JwtAuthenticationFilter@5453b15d, com.jp.backend.auth.filter.JwtVerificationFilter@4a6dd88e, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@79224636, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@35307365, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@2c3c05ff, org.springframework.security.web.session.SessionManagementFilter@636d4cdc, org.springframework.security.web.access.ExceptionTranslationFilter@6000ca67, org.springframework.security.web.access.intercept.AuthorizationFilter@dc72335]
ํ์ง๋ง ๋ก๊ทธ์ธ์ ํด๋ณด๋ ์๋์ ๊ฐ์ ์๋ฌ๊ฐ ๋ํ๋ฌ๋ค!
Cannot invoke "org.springframework.security.authentication.AuthenticationManager.authenticate(org.springframework.security.core.Authentication)" because "this.authenticationManager" is null
at com.jp.backend.auth.filter.JwtAuthenticationFilter.attemptAuthentication(JwtAuthenticationFilter.java:63) ~[main/:na]
http.getSharedObject(AuthenticationManager.class);
๋ฅผ ์คํํ์ ๋ AuthenticationManager ๊ฐ null ๊ฐ์ผ๋ก ๋์์ ๋์ค๋ ์๋ฌ์๋๋ฐ
์ฌ๋ฌ ๋ฐฉ๋ฒ์ ์ฐพ์๋ณด๊ณ AuthenticationManager๋ฅผ @Bean์ผ๋ก ๋ฑ๋กํด๋ด๋ ์ ์๋ผ์
๋ฉฐ์น ๊ฐ์ ์์น ๋์ ์์ด๋์ด๋ฅผ ์ป์ด์ ํด๋ณด์๋ค.
์์์ AuthenticationManager๊ฐ null๋ก ๋ค์ด์จ๋ค๊ณ ํ์ผ๋๊น
์์ filterChain์์ http.getSharedObject(AuthenticationManager.class);๋ฅผ ๋นผ๊ณ
AuthenticationManager Bean์ ์์ฑํ ํ์
์ธ์๋ก AuthenticationManager authenticationManager๋ฅผ ๋ฃ์ด์ฃผ๋ฉด ํด๊ฒฐ๋๋ ๋ฌธ์ ์๋ค !
์ด๋ ๊ฒ ํ๊ณ ๋๋ฆฌ๋ฉด ํํฐ์๋ ์ถ๊ฐ๊ฐ ๋๊ณ , ๋ก๊ทธ์ธ์ ํด๋ header์ AccessToken์ด ์ ์ถ๊ฐ๋๋ ๊ฒ์ ์ ์ ์๋ค !