โ Resource Owner
๐ ์น ๋ธ๋ผ์ฐ์ ์์ [Google ๋ก๊ทธ์ธ ๋งํฌ] ํด๋ฆญ
โก frontend ์ ํ๋ฆฌ์ผ์ด์
โ Backend ์ ํ๋ฆฌ์ผ์ด์
(OAuth Client)
๐ http://localhost:8080/oauth2/authorization/google
๋ก request ์ ์ก
( ์ด URI์ requet๋ OAuth2LoginAuthenticationFilter๊ฐ ์ฒ๋ฆฌ )
โข Backend ์ ํ๋ฆฌ์ผ์ด์
(OAuth Client) โ frontend ์ ํ๋ฆฌ์ผ์ด์
๐ Google์ ๋ก๊ทธ์ธ ํ๋ฉด์ ์์ฒญํ๋ URI๋ก ๋ฆฌ๋ค์ด๋ ํธ
๐ ์ด ๋, (์ฒ๋ฆฌ ๋ง์ง๋ง ๋จ๊ณ์์) Authorization Server๊ฐ Backend ์ ํ๋ฆฌ์ผ์ด์
์ชฝ์ผ๋ก Authorization Code๋ฅผ ์ ์กํ (Spring Security๊ฐ ๋ด๋ถ์ ์ผ๋ก ์ ๊ณตํ๋) Redirect URI(http://localhost:8080/login/oauth2/code/google
)๋ฅผ ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๋ก ํจ๊ป ์ ๋ฌ
โฃ Resource Owner
๐ Google ๋ก๊ทธ์ธ ํ๋ฉด์ ์คํ ํ, ์ธ์ฆ ์ ๋ณด ์
๋ ฅํ์ฌ ๋ก๊ทธ์ธ
( ๋ก๊ทธ์ธ ์ฑ๊ณต )
โค frontend ์ ํ๋ฆฌ์ผ์ด์
โ Authorization Server
๐ โข์์ ํจ๊ป ์ ๋ฌํ Backend Redirect URI(http://localhost:8080/login/oauth2/code/google
)๋ก Authorization Code ์์ฒญ
โฅ Authorization Server โ Backend ์ ํ๋ฆฌ์ผ์ด์
(OAuth Client)
๐ Authorization Code๋ฅผ ์๋ต์ผ๋ก ์ ์ก
โฆ Backend ์ ํ๋ฆฌ์ผ์ด์
(OAuth Client) โ Authorization Server
๐ Access Token ์์ฒญ
โ ์ฌ๊ธฐ์์ Access Token
โ Google Resource Server์๊ฒ Resource๋ฅผ ์์ฒญํ๋ ์ฉ๋
( OAuth2 ์ฌ์ฉํ๊ฒ ํด์ฃผ๋ Access Token )
โง Backend ์ ํ๋ฆฌ์ผ์ด์
(OAuth Client) โ Resource Server
๐ User Info ์์ฒญ
( User Info - Resource Owner์ ๋ํ ์ด๋ฉ์ผ ์ฃผ์, ํ๋กํ ์ ๋ณด ๋ฑ )
โจ Resource Server โ Backend ์ ํ๋ฆฌ์ผ์ด์
(OAuth Client)
๐ User Info ์๋ต์ผ๋ก ์ ์ก
โฉ Backend ์ ํ๋ฆฌ์ผ์ด์
(OAuth Client)
๐ JWT๋ก ๊ตฌ์ฑ๋ Access Token / Refresh Token ์์ฑ ํ,
Frondend ์ ํ๋ฆฌ์ผ์ด์
์๊ฒ JWT(Access Token๊ณผ Refresh Token) ์ ๋ฌํ๊ธฐ ์ํด
Frondend ์ ํ๋ฆฌ์ผ์ด์
(http://localhost?access_token={jwt-access-token}&refresh_token={jwt-refresh-token}
)์ผ๋ก Redirect
โ ์ฌ๊ธฐ์์ Access Token
โ ์ฐ๋ฆฌ ์ ํ๋ฆฌ์ผ์ด์ ์ธ์ฆํ๋ Access Token
โ Google ์ OAuth 2 ์ธ์ฆ ์์คํ ์ ์ด์ฉํด ์ฌ์ฉ์์ ์ธ์ฆ์ ์ฒ๋ฆฌํ ํ, ๋ณดํธ๋ HTML ํ์ด์ง๋ฅผ ์ ๊ณตํ๋ SSR(Server Side Rendering) ๋ฐฉ์์ ์ ํ๋ฆฌ์ผ์ด์
โ OAuth 2์
ํด๋ผ์ด์ธํธ ID
/ํด๋ผ์ด์ธํธ Secret
์ Google Cloud์์ ๋ฐ๊ธ ๋ฐ์
(์ ์ดํด๋์ค - Section4 - OAuth2 ์ธ์ฆ - OAuth2 ์ธ์ฆ์ ์ํ ์ฌ์ ์์
์ฐธ๊ณ )
build.gradle
์ ์์กด์ฑ ์ถ๊ฐ
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' // (1) implementation 'org.springframework.boot:spring-boot-starter-security' // (2) implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' // (3)
โ HTML ํ๋ฉด์ ๊ตฌ์ฑํ๊ธฐ ์ํ ํ ํ๋ฆฟ์ธ ํ์๋ฆฌํ(Thymeleaf) ์ถ๊ฐ
( ํ๋ก์ ํธ์์๋ ๊ตณ์ด ํ์ํ์ง ์์ ์ ์์ )
โ
โก Hello OAuth 2 ์ ํ๋ฆฌ์ผ์ด์ ์ Spring Security ๊ธฐ๋ฐ์ ์ ํ๋ฆฌ์ผ์ด์ ์ด๋ฏ๋ก ์ถ๊ฐ
โ
โข Hello OAuth 2 ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ๊ธ์ OAuth 2 ์์คํ ์ ์ด์ฉํ๋ OAuth 2 ํด๋ผ์ด์ธํธ์ด๋ฏ๋ก ํด๋ผ์ด์ธํธ๋ก์จ์ ์ญํ ์ ํ๊ธฐ ์ํด ์ถ๊ฐ
src/main/resources/templates
๊ฒฝ๋ก์ hello-oauth2.html
ํ์ผ ์ถ๊ฐ
HelloHomeControllerV1
ํด๋์ค ์ถ๊ฐ
( hello-oauth2 ํ๋ฉด์ ๋ํ ๋ทฐ๋ฅผ ๋ฆฌํด )
OAuth 2 ์ธ์ฆ์ ์ํ SecurityConfiguration ์ค์
4-1. SecurityConfigurationV1
ํด๋์ค ์ถ๊ฐ
( Spring Boot ์ ์๋ ๊ตฌ์ฑ ์ด์ฉ )
๐ ์ด ์ํ๋ก ์ ํ๋ฆฌ์ผ์ด์ ์ ๋๋ฆฌ๋ฉด ์๋ฌ ๋ฐ์ !
( ๋์ถฉ 'ClientRegistrationRepository ๋ผ๋ Bean ์ด ์์ผ๋ SecurityConfiguration ์ ์ถ๊ฐํ๋ผ' ๋ผ๋ ์๋ฌ )
โ
โ ์ฐ๋ฆฌ๊ฐ ์ด์ฉํด์ผ ํ OAuth 2 ์์คํ ์ ๋ํ client ID / client Secret ์ ์ค์ ํ์ง ์์๊ธฐ ๋๋ฌธ์ ๋ฐ์ํ๋ ์๋ฌ์
โ
โ ์๋ฌ ํด๊ฒฐ์ ์ํด ๊ตฌ๊ธ OAuth 2 ์์คํ ์ ์ด์ฉํ๊ธฐ ์ํด OAuth Client ID๋ฅผ ์์ฑํ๋ ๊ฒ์ ์ถ๊ฐํ ๊ฒ์
( ์ ์ดํด๋์ค์ 'Section4 - OAuth2 ์ธ์ฆ - OAuth2 ์ธ์ฆ์ ์ํ ์ฌ์ ์์ ' ์์ ํ์ธ ๊ฐ๋ฅ )
OAuth 2 ํด๋ผ์ด์ธํธ ๋ฑ๋ก ์ ๋ณด ์ถ๊ฐ
5-1. application.yml
ํ์ผ์ ์ฐ๋ฆฌ๊ฐ ์์ฑํ ๊ตฌ๊ธ OAuth 2 ํด๋ผ์ด์ธํธ ์ ๋ณด ์ถ๊ฐ
๐ ์ฌ๊ธฐ๊น์ง ํ ํ, localhost:8080 ์ผ๋ก ์ ์ํ๋ฉด google ๋ก๊ทธ์ธ ํ์ด์ง๊ฐ ๋์ฌ ๊ฒ !
Configuration ์ ํตํ OAuth 2 ์ธ์ฆ ์ค์
6-1. SecurityConfigurationV2
ํด๋์ค ์ถ๊ฐ
( client Id/Secret ์ ์ด์ฉํ OAuth 2 ์ธ์ฆ ์ค์ )
ClientRegistration ์ฐธ๊ณ
CommonOAuth2Provider ์ฐธ๊ณ 1
CommonOAuth2Provider ์ฐธ๊ณ 2
๐ ์ฌ๊ธฐ๊น์ง ํ ํ,
localhost:8080/hello-oauth2
์ผ๋ก ์ ์ํ๋ฉด ๊ตฌ๊ธ์ ๋ก๊ทธ์ธ ํ๋ฉด์ด ๋จ๊ณ
๋ก๊ทธ์ธ ์ธ์ฆ์ ์ฑ๊ณตํ๋ฉด Hello OAuth 2 ์ ํ๋ฆฌ์ผ์ด์ ์ home ํ๋ฉด์ด ์ ์์ ์ผ๋ก ๋ณด์ผ ๊ฒ !
โ
โ ๏ธlocalhost:8080/hello-oauth2
์ ์ ์ํ์ฌ Google ๋ก๊ทธ์ธํ ๋,
ํ ๋ฒ Google ๋ก๊ทธ์ธ์ผ๋ก ์ฐ๋์ ํด๋์ผ๋ฉด ์ดํ๋ก๋ ์ฐ๋์ด ๋์ด์ง์ง ์์ ์๋ฒ๋ฅผ ๋ซ๊ณ ๋ค์ ์ด์ด๋ ๋ฐ๋ก ๋ก๊ทธ์ธ ์ดํ ํ๋ฉด์ด ๋ํ๋๋ ๊ฒฝ์ฐ๊ฐ ๋ฐ์ํจ
โGoogle ํ๋ฉด ์ฐ์ธก ์ 9๊ฐ ์๋ ๊ฑฐ - Google ๊ณ์ - ๋ณด์ - Google ๊ณ์ ์ ํตํ ๋ก๊ทธ์ธ
์ ๋ค์ด๊ฐ์ ํด๋น ํ์ด์ง์ ์ก์ธ์ค ๊ถํ์ ์ญ์ ํ ํ,
๋ค์ ์ ์ํ๋ฉด Google ๋ก๊ทธ์ธํ๋ฉด ๋ธ !!
์ธ์ฆ๋ Authentication ์ ๋ณด ํ์ธ
7-1. SecurityContext ๋ฅผ ์ด์ฉํ๋ ๋ฐฉ๋ฒ
โ HelloHomeControllerV2
ํด๋์ค ์ถ๊ฐ
7-2. Authentication ๊ฐ์ฒด๋ฅผ ํธ๋ค๋ฌ ๋ฉ์๋ ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌ ๋ฐ๋ ๋ฐฉ๋ฒ
โ HelloHomeControllerV3
ํด๋์ค ์ถ๊ฐ
7-3. OAuth2User ๋ฅผ ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌ ๋ฐ๋ ๋ฐฉ๋ฒ
โ HelloHomeControllerV4
ํด๋์ค ์ถ๊ฐ
Authorization Server ๋ก๋ถํฐ ์ ๋ฌ ๋ฐ์ Access Token ํ์ธ
8-1. OAuth2AuthorizedClientService ๋ฅผ DI ๋ฐ๋ ๋ฐฉ๋ฒ
โ HelloHomeControllerV5
ํด๋์ค ์ถ๊ฐ
OAuth2AuthorizedClient ์ฐธ๊ณ 1
OAuth2AuthorizedClient ์ฐธ๊ณ 2
8-2. OAuth2AuthorizedClient ๋ฅผ ํธ๋ค๋ฌ ๋ฉ์๋์ ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌ ๋ฐ๋ ๋ฐฉ๋ฒ
โ HelloHomeControllerV6
ํด๋์ค ์ถ๊ฐ
โ 8-1 / 8-2 ์ ๋๊ฐ์ง ๋ฐฉ๋ฒ ์ค ์๋ฌด๊ฑฐ๋ ์จ๋ ์๊ด ์์ง๋ง,
ํ๋ ์ด์์ ํธ๋ค๋ฌ ๋ฉ์๋์์ OAuth2AuthorizedClient๋ฅผ ์ฌ์ฉํด์ผ ๋๋ค๋ฉด OAuth2AuthorizedClientService ๋ฅผ DI ๋ฐ์์ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ฐ๋์งํด ๋ณด์
โ CSR(Client Side Rendering) ๋ฐฉ์์ ์ ํ๋ฆฌ์ผ์ด์ ์ OAuth 2 ์ธ์ฆ ์์คํ ์ ํตํด ์ธ์ฆ์ ์ฑ๊ณตํ ์ฌ์ฉ์์ ๋ํ ์๊ฒฉ ์ฆ๋ช ์ ๋ณด๋ฅผ JWT ๋ก ์ ๊ณต
โ ์ด ํ์ต์ Apache๋ฅผ ์ฌ์ฉํด ๋ธ๋ผ์ฐ์ ์์ ํ์ธ์ ํด๋ดค์ผ๋ ์์ธํ ๊ฑด ์ ์ดํด๋์ค-OAuth2์ธ์ฆ-OAuth 2 + JWT ๋ฅผ ์ด์ฉํ ์ํ ์ ํ๋ฆฌ์ผ์ด์
๊ตฌํ
์์ ํ์ธํ๊ธฐ !
( ๋ด ์๋์ฐ์์ Apache ํ์ผ์ c:\httpd-2.4.54-win64-VS17\Apache24
์ ์์ )
Apache ์ฐธ๊ณ 1
OAuth2ClientAuthenticationProcessingFilter ์ฐธ๊ณ
build.gradle
์ jwt ์ฌ์ฉ์ ์ํ ์์กด์ฑ ์ถ๊ฐ
implementation 'io.jsonwebtoken:jjwt-api:0.11.5' runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'
JwtTokenizer
ํด๋์ค ์ถ๊ฐ
( ์๋ JWT ์ค์ต ์ฝ๋์ JwtTokenizer ํด๋์ค์ ๋์ผ )
application.yml
์ JWT ์ค์ ์ถ๊ฐ
โ JWT ์ OAuth2 ์ค์ ์ด ํฉ์ณ์ง ๋ชจ์ต
JwtVerificationFilter
ํด๋์ค ์ถ๊ฐ
( ์๋ JWT ์ค์ต ์ฝ๋์ JwtVerificationFilter ํด๋์ค์ ๋์ผ )
CustomAuthorityUtils
ํด๋์ค ์ถ๊ฐ
( ์๋ JWT ์ค์ต ์ฝ๋์ CustomAuthorityUtils ํด๋์ค์ ๋์ผ )
OAuth2MemberSuccessHandler
ํด๋์ค ์ถ๊ฐ
( OAuth2 ์ธ์ฆ์ด ์ฑ๊ณต์ ์ผ๋ก ์ํ๋๋ฉด ํธ์ถ๋๋ ํธ๋ค๋ฌ )
โ OAuth 2 ์ธ์ฆ ํ, Frontend ์ ํ๋ฆฌ์ผ์ด์
์ชฝ์ผ๋ก JWT ์ ์กํ๋ ํต์ฌ ์ญํ ๋ด๋น
SecurityConfigurationV1
or SecurityConfigurationV2
/ MemberAccessDeniedHandler
/ MemberAuthenticationEntryPoint
/ ErrorResponder
ํด๋์ค ์ถ๊ฐ
( ๋ชจ๋ JWT ๋ถ๋ถ์์ ํ์ตํ๋ ๋ด์ฉ ! / ์ฝ๋, ์ค๋ช
๋ชจ๋ ๊ฐ์ผ๋ JWT ํ๋ก์ ํธ ์ฐธ๊ณ )
MemberController
, MemberDto
, MemberService
, MemberMapper
, Member
ํด๋์ค ์ฝ๋ ์์
โ OAuth 2 ์ธ์ฆ ์์คํ
์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ํ์ ์ ๋ณด๋ฅผ ๋ฑ๋กํ๊ฑฐ๋ ์์ ํ ํ์๊ฐ ์์ด์ ์ฝ๋ ์์ / ์ผ๋ถ ์ญ์ ํจ
OAuth2 ์์
๋ก๊ทธ์ธ ๊ฐ์ด๋ ์ฐธ๊ณ
๋ค์ด๋ฒ ๋ก๊ทธ์ธ ์ฐ๋ ์ฐธ๊ณ
์นด์นด์ค ๋ก๊ทธ์ธ ์ฐ๋ ์ฐธ๊ณ 1
์นด์นด์ค ๋ก๊ทธ์ธ ์ฐ๋ ์ฐธ๊ณ 2
๊ทธ๋๋ jwt ํ์ต์ ํ๊ณ ๋๋ ์กฐ๊ธ ๋ ์์ํ๊ธด ํ๋ค !!
ํ์ง๋ง ์์ง jwt๋ ์ด๋ ค์์ ๋ ๊ณต๋ถํด์ผ๊ฒ ๋ค.
๋ค์์ ์๊ฐ ๋ ๋ OAuth2 ๋ง๊ณ ๋ค์ด๋ฒ๋ ์นด์นด์ค ๊บผ๋ ํด๋ด์ผ์ง