[Spring boot] Spring boot Security๋ฅผ ์ด์ฉํ OAuth2 ์ธ์ฆ ๊ตฌํ 1 - Google ๊ณ์ ์ธ์ฆ
์ง๋ ํฌ์คํธ์ ์ด์ด์, ์ค๋์ ์๋ก์ด ํ๋ก์ ํธ๋ฅผ ์์ฑํ์ฌ Spring boot Security ๋ํ๋์๋ฅผ ์ด์ฉํด OAuth2 ์ธ์ฆ์ ๊ตฌํํ๋ ์๊ฐ์ ๊ฐ์ ธ๋ณด๊ณ ์ ํฉ๋๋ค.
์ง๋ ํฌ์คํธ์์ OAuth2 ์ธ์ฆ์ ๊ตฌํํ๊ธฐ ์ํด ์ธ์ฆ ํ ํฐ๊ณผ ์ก์ธ์ค ๊ถํ์ ์ป๋ ๋ฐฉ๋ฒ์ ๋ํด ์์๋ดค์ต๋๋ค. ํด๋ผ์ด์ธํธ์์ ๊ถํ ์๋ฒ๋ฅผ ํตํด ๊ถํ์ ํ์ธํ๊ณ , ๋ถ์ฌ ๋ฐ์ ID์ Secret๋ฅผ ์ด์ฉํ์ฌ ํ ํฐ์ ๋ฐ๋ ๋ฐฉ์์ด์์ฃ .
์ด๋ฅผ ํ ๋๋ก Spring boot security๋ฅผ ์ด์ฉํ์ฌ ํ์ ๊ฐ์ ๊ณผ ์ธ์ฆ์ ๋์์ ์ด๋ป๊ฒ ๊ตฌํํ ์ ์๋์ง ์ง๊ธ๋ถํฐ ์ดํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. ์ด ํฌ์คํธ๋ ๊ธฐ๋ณธ ์ ํ๋ฆฌ์ผ์ด์ ์ผ๋ก ํ์ฌ๊ธ, OAuth2 ๋ก๊ทธ์ธ๋ถํฐ User Entity ์ฐ๋๊น์ง ๋ค๋ฃฐ ๊ฒ์ด๋ฉฐ ์ด๋ฒ์ ๋ค๋ฃฐ ๊ฒ์ ๊ธฐ๋ณธ์ ์ธ Spring boot security ์ค์ ๋ฐฉ๋ฒ๊ณผ ๊ฐ๋จํ OAuth2 ์ธ์ฆ๋ง์ ๋ค๋ฃฐ ๊ฒ์ ๋๋ค.
์๋ก์ด ํ๋ก์ ํธ ์์ฑ
๋จผ์ ์๋ก์ด ํ๋ก์ ํธ๋ฅผ ์์ฑํด๋ณด๊ฒ ์ต๋๋ค. ์ด๋ฒ ํฌ์คํธ์์๋ Spring boot rest๊ฐ ์๋ Spring MVC๋ก ์งํํด๋ณด๊ณ ์ ํฉ๋๋ค. ๋ฐ๋ผ์ View๋ฅผ ์ง์ํด์ค ํ ํ๋ฆฟ์ธ thymeleaf์ OAuth2 client๋ฅผ Spring boot ๊ธฐ๋ณธ ๋ํ๋์์ ํจ๊ป ์ถ๊ฐํด์ฃผ๋๋ก ํฉ์๋ค.
์ด๋ฒ ํฌ์คํธ์์๋ H2 Database๋ฅผ ์ด์ฉํด์ ์ฌ์ฉ์ ์ธ์ฆ์ ๋ค๋ฃฐ ๊ฒ์ ๋๋ค. ๋ฐ๋ผ์ ์ ์ด๋ฏธ์ง์ H2 Database๋ฅผ ๊ฐ์ด ๋๋ฌ์ฃผ๋๋ก ํฉ์๋ค.
Spring boot Security 2.x and OAuth2 Client
์คํ๋ง ์ํ๋ฆฌํฐ๋ฅผ ๋ค๋ฃจ๊ธฐ ์ ์ ๋จผ์ ์คํ๋ง ๋ถํธ ์ํ๋ฆฌํฐ 2.0์ ๋ํด์ ์ ์ ์ค๋ช ์ ๋๋ฆฌ๊ณ ์ ํฉ๋๋ค. ๋ณธ๋ ์ฌ์ฉํ๋ ์คํ๋ง ๋ถํธ ์ํ๋ฆฌํฐ 1.x ๋ฒ์ ์์๋ OAuth2 ๊ตฌํ์ ์ํด์ Filter, Handling ๋ฑ์ ๋ชจ๋ ์๋์ผ๋ก ์ค์ ํ๊ณ , ์ด๋ฅผ NestedProperties ๋ฑ์ ํ์ฉํ์ฌ ์์ฑํด์ผ ํ์ต๋๋ค.
๊ทธ๋ฌ๋ Spring boot security 2.0์์๋ ๊ธฐ๋ณธ์ ์ผ๋ก Google๊ณผ Facebook์ OAuth2 ์ธ์ฆ์ด ๊ตฌํ๋์ด ์์ต๋๋ค. ์ฐ๋ฆฌ๋ ์ด๋ฅผ ์ด์ฉํ๋ฉด Google๊ณผ Facebook์ ๋ํด์๋ ์ฝ๊ฒ OAuth2 ์ธ์ฆ์ ๊ตฌํํ ์ ์์ต๋๋ค.
๊ทธ๋ผ ์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก ์ฝ๋๋ฅผ ๋ค๋ค๋ณด๋๋ก ํ์ฃ .
Spring boot Security Configuration
๋จผ์ ํด์ผํ ๊ฒ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ณด์์ ์ ์ฉํ๋ ๊ฒ์ ๋๋ค. Spring boot security๊ฐ ์๋ค๋ฉด, ๊ฐ API ํฌ์ธํธ๋ณ๋ก Filter ํน์ Intercepter๋ฅผ ์ด์ฉํ์ฌ API ์์ฒญ ์ ํ๋ก AOP๋ฅผ ์ ์ฉํด ์ธ์ฆ ๋จ๊ณ๋ฅผ ๊ฒํ ํด์ผ ํ ๊ฒ์ ๋๋ค.
๊ทธ๋ฌ๋ Spring boot Security๋ฅผ ์ด์ฉํ๋ฉด ์ด๋ ธํ ์ด์ ํ๋๋ฅผ ์ด์ฉํด์ ๊ฐ ์๋ํฌ์ธํธ์ ์ ๊ทผ์ ์ ํํ ์ ์์ต๋๋ค.
Configuration ์ด๋ ธํ ์ด์ ์ Spring boot์ ๋ง์ฐฌ๊ฐ์ง๋ก ์ ํ๋ฆฌ์ผ์ด์ ์คํ์, ๋ก๋๋๋ฉฐ ์ฌ๊ธฐ์ EnableWebSecurity๋ฅผ ์ฌ์ฉํ๋ฉด ๋ชจ๋ ์๋ํฌ์ธํธ์ ์ ๊ทผ ์ ํ์ด ๊ฑธ๋ฆฌ๊ฒ ๋ฉ๋๋ค. ์ด ๋๋ถํฐ ๋ชจ๋ ์๋ํฌ์ธํธ๋ ์๋์ WebSecurityConfigurerAdapter ํด๋์ค์ configure ์ฝ๋ฐฑ ํจ์์ ์ ์๋ ๋๋ก ๋์ํ๊ฒ ๋ฉ๋๋ค.
permitAll ๋ฉ์๋๋ฅผ ์ด์ฉํ๊ฒ ๋๋ฉด, ์์ ๋งค์นญ๋ ์๋ํฌ์ธํธ๋ค์ ๋ณ๋ค๋ฅธ ๊ถํ ์์ด Anonymous๋ก ์ ๊ทผํ ์ ์๋๋ก ํ๊ฒ ๋ฉ๋๋ค. ์ฆ, ๋ชจ๋ ์ฌ์ฉ์๊ฐ ์ ๊ทผํ ์ ์๋๋ก ํ๋ ๊ฒ์ด์ฃ . ๊ธฐ๋ณธ์ ์ผ๋ก MVC์์ ์ฃผ๋ก ์ฌ์ฉ๋๋ ์ด๋ฏธ์ง๋ ์คํ์ผ์ํธ, ํ๋น์ฝ, ์๋ฐ์คํฌ๋ฆฝํธ ๋ฑ์ด ์ด์ ํด๋น๋๋ฉฐ, ์ ๊ทผ ๊ถํ์ ๋ฐ์ ์ ์๋ Login ํ์ด์ง๋ ์ฌ๊ธฐ์ ํฌํจ๋์ด์ผ๊ฒ ์ฃ ?
๋๋จธ์ง EndPoint์ ๋ํด์๋ ์ธ์ฆ๋์ด์ผ๋ง ์ฌ์ฉํ ์ ์๋๋ก authenticated ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ฃผ๊ณ , Spring security์์ ์ ๊ณตํ๋ oauth2Login ๋ฉ์๋๋ฅผ ์ด์ฉํ์ฌ ๋ก๊ทธ์ธ ์ฝ๋๋ฅผ ๊ฐ์ ธ์ค๋๋ก ํฉ๋๋ค. ๋ง์ง๋ง์ผ๋ก ์ธ์ฆ์ด ์งํ๋์ง ์์ ์ํ์์ ํ์ด์ง์ ์ ๊ทผํ ๊ฒฝ์ฐ, ์๋์ผ๋ก login ํ์ด์ง๋ก ๋ฆฌ๋ค์ด๋ ํธ ๋๋๋ก authenticationEntryPoint ๋ฉ์๋์ URL์ /login์ผ๋ก ๋ง์ถฐ์ค๋๋ค.
์ด๊ฒ์ผ๋ก Security ๊ด๋ จ ์ค์ ์ ๋ชจ๋ ๋๋ฌ์ต๋๋ค. ์ ์์ง, Client ID๋ Secret์ ์ฃผ์ง ์์๋๋ฐ์. ๊ทธ๋ฆฌ๊ณ ๊ถํ ์๋ฒ๋ ํ ํฐ ์๋ฒ๋ ์ฐ๊ฒฐ๋ ์์ผ์ผ ํ๋๋ฐ, ์ด๋ฐ ๋ถ๋ถ์ ๊ตฌํํ์ง ์๋๊ตฐ์.
๋ณธ๋๋ ๊ตฌํํด์ผ ํ๋ ๊ฒ์ด ๋ง์ง๋ง Spring boot security์ ์ ๋ถ๋ถ์ด ์ ๋ถ ๊ตฌํ๋ ์ํ์ด๊ณ ์ฐ๋ฆฌ๋ ์ด์ Client ID์ Client Secret๋ง์ ๋ฃ์ด์ฃผ๋ฉด ๋ฉ๋๋ค.
Generate Google Client
Google OAuth2 ์ธ์ฆ์ ์ฌ์ฉํ๊ธฐ ์ํ Client ID์ Secret์ Google Cloud Platform Console ์ฌ์ดํธ์์ ๋ฐ์ ์ ์์ต๋๋ค.
https://console.cloud.google.com/
์ ์ฌ์ดํธ๋ฅผ ํด๋ฆญํ์ฌ ์งํํ ์ ์์ต๋๋ค.
๋ง์ฝ ๊ธฐ์กด ํ๋ก์ ํธ๊ฐ ์๋ค๋ฉด, ํ๋ก์ ํธ๋ฅผ ์๋ก ์์ฑํด์ผ ํ๋๋ฐ, ์ ๋นํ ํ๋ก์ ํธ ์ด๋ฆ์ ์ ๋ ฅํ ํ, ๋ง๋ค๊ธฐ๋ฅผ ๋๋ฌ์ ์งํํ๋ฉด ๋ฉ๋๋ค.
ํ์ด์ง ์๋จ์์ OAuth client ID ๋ง๋ค๊ธฐ๋ฅผ ๋๋ฅธ ํ, Client ID ๋ง๋ค๊ธฐ๋ฅผ ์งํํฉ๋๋ค.
์ ํ๋ฆฌ์ผ์ด์ ํ์ ์ Web Application์ผ๋ก ์ ํํ๊ณ , ์ฑ ์ด๋ฆ์ ์ ํด์ค๋๋ค. ๊ทธ๋ฆฌ๊ณ , Spring boot ๋ด์ ์๋ Embedded Tomcat์ ๊ธฐ๋ณธ ํฌํธ ์ฃผ์์ ํจ๊ป URL์ ์ ๋ ฅํด์ค๋๋ค.
๋ง์ง๋ง์ผ๋ก Redirect URI๊ฐ ์๋๋ฐ, ์ด ์ฃผ์๋ ์ ํ๋ฆฌ์ผ์ด์ ์์ Google ๋ก๊ทธ์ธ์ผ๋ก ๋ฆฌ๋ค์ด๋ ํธ ๋๋๋ก ์ค์ ๋ URL์ ์ ๋ ฅํ๋ ๋์ ๋๋ค. Spring boot security์์ ์ ๊ณตํ๋ OAuth2 Login ์ฃผ์๋ oauth2/** ๋ก ์์ํ๋ฉฐ ์ด ๋ค์ code์ google์ ๋ถ์ฌ์ฃผ๋ฉด Google ๋ก๊ทธ์ธ์ผ๋ก ๋ฆฌ๋ค์ด๋ ํธ ๋ฉ๋๋ค.
์ฌ๊ธฐ๊น์ง ๋๋ฌ๋ค๋ฉด Client ID์ Client Secret์ ๋ฐ์ ์ ์์ต๋๋ค. ์ด์ ์ ํ๋ฆฌ์ผ์ด์ ์ ID์ Secret์ ์ฃผ์ ํ๋ฉด ๋ฉ๋๋ค.
Spring boot Security์์ Google OAuth2๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด ์์ ๊ฐ์ด spring.security.oauth2.client.registration.google ํ์์์ ID์ Secret์ ์ ํด์ฃผ๋ฉด ๋์ ๋๋ค.
Thymeleaf๋ฅผ ์ด์ฉํ ํ์ด์ง ๊ตฌํ
์ด์ ํ์ด์ง๋ฅผ ๊ตฌํํ ์ฐจ๋ก์ ๋๋ค. ํ์ด์ง๋ ๊ฐ๋จํ๊ฒ ๋ฉ์ธ ํ์ด์ง(HOME)๊ณผ ๋ก๊ทธ์ธ ํ์ด์ง(LOGIN) ๊ทธ๋ฆฌ๊ณ , ๋ก๊ทธ์ธ์ด ํ๊ณ ๋ค์ด๊ฐ ์ ์๋ board ํ์ด์ง ํ๋๋ฅผ ์์๋ก ๋ง๋ค์ด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
Spring boot์์๋ ์ฌ๋ฌ๊ฐ์ง View๋ฅผ ์ฌ์ฉํ ์ ์๋๋ฐ, ๋ํ์ ์ธ ๊ฒ์ด JSP/JSTL, Thymeleaf, Velocity ๋ฑ์ด ์์ต๋๋ค. ์ฌ๊ธฐ์ ์ฐ๋ฆฌ๋ Thymeleaf๋ฅผ ์ฌ์ฉํ ๊ฒ์ด๋ฉฐ Spring boot starter์์ ์ ๊ณตํ๋ ViewResolver์ ์๊ฑฐ Thymeleaf๋ resources/templates ๋ฐ์ HTML ํ์ด์ง๋ฅผ ์ฝ๊ฒ ๋ฉ๋๋ค. ๋๋จธ์ง image, css ๋ฑ์ static ํด๋๋ก ๊ฐ๋ฉด ๋ฉ๋๋ค.
Home, Login, Board ์ด๋ ๊ฒ 3๊ฐ์ง๋ฅผ ๋ง๋ค์์ผ๋ฉฐ, ์ฒ์์๋ Home์ ์๋ค๊ฐ, ๊ฒ์ํ์ ๋๋ ์ ๋, ์ธ์ฆ ์ ๋ณด๊ฐ ์์ผ๋ฉด ๋ก๊ทธ์ธ์ ํด์ผํ๊ณ , ๋ก๊ทธ์ธ์ด ๋๋ฉด ๊ฒ์ํ์ผ๋ก ์ด๋ํ ์ ์๋๋ก ๊ตฌํํฉ๋๋ค.
Controller ๊ตฌํ
Spring boot์์ REST API๋ฅผ ๊ตฌํํ์ ๋๋ RestController๋ฅผ ์ด์ฉํ์ต๋๋ค. ๊ทธ๋ฌ๋ View๋ฅผ ๊ตฌํํ ๋๋ Controller ์ด๋ ธํ ์ด์ ์ ์ด์ฉํฉ๋๋ค.
ํ์ด์ง๋ฅผ ๋ฐํํ ๋๋ html ํ์ผ ์ด๋ฆ์ ๋ฌธ์์ด๋ก ๋ฐํํ๋ฉด ๋ฉ๋๋ค.
Test
์๋ฒ๋ฅผ ์คํํ ํ, ๋ฉ์ธ ํ์ด์ง์ ์ ์ํด๋ด ๋๋ค.
์ ์ํ์์ Board๋ฅผ ๋ค์ด๊ฐ๊ฒ ๋๋ฉด, ๋ก๊ทธ์ธ ํ์ด์ง๊ฐ ๋์ค๊ฒ ๋ฉ๋๋ค.
Google ๋ก๊ทธ์ธ์ ์ฒ์ ์งํํ๋ฉด, ๋ค์ Home์ผ๋ก ๋์๊ฐ๊ฒ ๋๊ณ , ๊ธฐ์กด์ ์งํํ ์ด๋ ฅ์ด ์๋ค๋ฉด ๋ฐ๋ก ๊ฒ์ํ์ด ๋์ค๊ฒ ๋ฉ๋๋ค.
๋ง์น๋ฉฐ...
๊ธฐ์กด์ User Entity ์์ด Google ๊ณ์ ๋ง์ ๋ค๋ค๋ดค์ต๋๋ค. Spring Security์์ ์ ๊ณตํ๋ Provider ๋๋ถ์ OAuth2 ์ธ์ฆ ๋จ๊ณ์์ ๊ถํ ์๋ฒ์ ํ ํฐ ์๋ฒ์ ID์ Secret์ ์๋์ผ๋ก HTTP API๋ฅผ ์์ฒญํ๋ ์ฝ๋๋ฅผ ๊ตฌํํ์ง ์์๋ ๋๋ค๋ ์ ์ ๊ต์ฅํ ํธํ ๋ถ๋ถ์ด๋ค์.
๋ค์ ํฌ์คํธ์์๋ User Entity์ ์ฐ๋ํ์ฌ ๋ก๊ทธ์ธ์ ๊ตฌํํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.