OAuth 2.0 ์ด์ ์๋ ์ 3์ ์ฑ์ด ์ฌ์ฉ์์ ๋ฆฌ์์ค์ ์ ๊ทผํ๊ธฐ ์ํ ํ์ค ์์ ํ๋กํ ์ฝ์ด ์์์ต๋๋ค. 2006~2007๋ ๊ฒฝ Twitter API๋ฅผ ์ฐ๋ํ๋ ์๋ํํฐ ํด๋ผ์ด์ธํธ๋ค์ ์ฌ์ฉ์์ Twitter ์์ด๋์ ๋น๋ฐ๋ฒํธ๋ฅผ ์ง์ ์ ๋ ฅ๋ฐ์ ์ ์ฅํ๋ ๋ฐฉ์์ผ๋ก ๋์ํ๊ณ , Flickr, Google, Yahoo! ๋ฑ๋ ๊ฐ์ ๋ ์์ ์ธ ์ธ์ฆ ์์ ๋ฐฉ์(FlickrAuth, AuthSub, BBAuth ๋ฑ)์ ์ด์ํ์ต๋๋ค.
๋น๋ฐ๋ฒํธ๋ฅผ ์ง์ ๊ณต์ ํ๋ ํจํด์ ๊ตฌ์กฐ์ ์ผ๋ก ๋ค์๊ณผ ๊ฐ์ ๋ฌธ์ ๋ฅผ ๊ฐ์ง๋๋ค.
์ด ๋ฌธ์ ๋ค์ ๋จ์ํ ๋ถํธํจ์ด ์๋๋ผ, ์๋น์ค ์ํ๊ณ๊ฐ ํ์ฅ๋ ์๋ก ๋ณด์ ์ฌ๊ณ ์ ๊ท๋ชจ์ ๋น๋๊ฐ ์ฆ๊ฐํ๋ ๊ตฌ์กฐ์ ๊ฒฐํจ์ ๋๋ค. OAuth 2.0(RFC 6749)์ ๋ฆฌ์์ค ์์ ์์ ํด๋ผ์ด์ธํธ ์ฌ์ด์ ์ธ๊ฐ ๊ณ์ธต(authorization layer)์ ๋์ ํ์ฌ, ๋น๋ฐ๋ฒํธ ์ง์ ๊ณต์ ๋ฅผ ์ ๊ฑฐํ๊ณ ๋ฒ์์ ์๋ช ์ด ์ ํ๋ ์์ ์๊ฒฉ ์ฆ๋ช (Access Token)์ผ๋ก ๋์ฒดํฉ๋๋ค.
OAuth์ ํต์ฌ์ ์ง์ ์๊ฒฉ ์ฆ๋ช ๊ณต์ ๋ฅผ ๊ฐ์ ์์์ผ๋ก ๋์ฒดํ๋ ๊ฒ์ ๋๋ค. ๊ตฌ์ฒด์ ์ธ ์์๋ก ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
[Before] ๋น๋ฐ๋ฒํธ ์ง์ ๊ณต์
์ฌ์ฉ์ โโ(ID/PW ์ ๋ฌ)โโโ ์ 3์ ์ฑ โโ(ID/PW๋ก ๋ก๊ทธ์ธ)โโโ ์๋น์ค API
โ ๋น๋ฐ๋ฒํธ ์ ์ฅ โ ์ฌ์ฉ์ ๋ณธ์ธ๊ณผ ๊ตฌ๋ถ ๋ถ๊ฐ
[After] OAuth ์์
์ฌ์ฉ์ โโ(์๋น์ค์ ์ง์ ๋ก๊ทธ์ธ)โโโ Authorization Server โโ(scope ์ ํ๋ ํ ํฐ ๋ฐ๊ธ)โโโ ์ 3์ ์ฑ
โ
Access Token์ผ๋ก API ํธ์ถ (์ ํ๋ ๊ถํ, ์ ํจ๊ธฐ๊ฐ ์์)
๋น๋ฐ๋ฒํธ ๊ณต์ ๋ชจ๋ธ์์ ์ฌ์ฉ์์ ์๊ฒฉ ์ฆ๋ช ์ ์ 3์ ์ฑ์ ๊ฒฝ์ ํฉ๋๋ค. OAuth ๋ชจ๋ธ์์ ์ฌ์ฉ์๋ ์ ๋ขฐํ ์ ์๋ Authorization Server์ ์ง์ ์ธ์ฆํ๊ณ , ์ 3์ ์ฑ์๋ ๋ฒ์์ ์๋ช ์ด ํ์ ๋ ํ ํฐ๋ง ์ ๋ฌ๋ฉ๋๋ค. ์ 3์ ์ฑ์ ์ฌ์ฉ์์ ๋น๋ฐ๋ฒํธ๋ฅผ ์ ์๋ ์๊ณ , ์ ํ์๋ ์์ต๋๋ค.
OAuth 2.0 ํ๋กํ ์ฝ์๋ 4๊ฐ์ง ์ญํ ์ด ์ฐธ์ฌํฉ๋๋ค.
| ์ญํ | ์ค๋ช | ์์ |
|---|---|---|
| Resource Owner | ๋ณดํธ๋ ๋ฆฌ์์ค์ ๋ํ ์ ๊ทผ ๊ถํ์ ๋ถ์ฌํ ์ ์๋ ์ฃผ์ฒด. ๋ณดํต ์ต์ข ์ฌ์ฉ์ | ๊ตฌ๊ธ ๋๋ผ์ด๋ธ์ ํ์ผ์ ๊ฐ์ง ์ฌ์ฉ์ |
| Resource Server | ๋ณดํธ๋ ๋ฆฌ์์ค๋ฅผ ํธ์คํ ํ๊ณ , Access Token์ ๊ฒ์ฆํ์ฌ ์์ฒญ์ ์ฒ๋ฆฌํ๋ ์๋ฒ | ๊ตฌ๊ธ ๋๋ผ์ด๋ธ API ์๋ฒ |
| Client | Resource Owner๋ฅผ ๋์ ํ์ฌ ๋ณดํธ๋ ๋ฆฌ์์ค์ ์ ๊ทผํ๋ ์ ํ๋ฆฌ์ผ์ด์ | ๊ตฌ๊ธ ๋๋ผ์ด๋ธ ์ฐ๋ ๊ธฐ๋ฅ์ด ์๋ ๋ฉ๋ชจ ์ฑ |
| Authorization Server | Resource Owner๋ฅผ ์ธ์ฆํ๊ณ , ์ธ๊ฐ๋ฅผ ๋ฐ์ ํ Access Token์ ๋ฐ๊ธํ๋ ์๋ฒ | ๊ตฌ๊ธ OAuth ์๋ฒ (accounts.google.com) |
๋ณดํธ๋ ๋ฆฌ์์ค์ ์ ๊ทผํ๊ธฐ ์ํ ์๊ฒฉ ์ฆ๋ช ๋ฌธ์์ด์ ๋๋ค. ํน์ ๋ฒ์(Scope)์ ์ ํจ ๊ธฐ๊ฐ(Lifetime)์ ๊ฐ์ง๋๋ค. Resource Owner์ ๋น๋ฐ๋ฒํธ ๋์ ์ด ํ ํฐ์ผ๋ก ๋ฆฌ์์ค์ ์ ๊ทผํฉ๋๋ค.
Access Token์ด ๋ง๋ฃ๋์์ ๋, ์ฌ์ฉ์์๊ฒ ๋ค์ ๋ก๊ทธ์ธ์ ์๊ตฌํ์ง ์๊ณ ์ Access Token์ ๋ฐ๊ธ๋ฐ๊ธฐ ์ํด ์ฌ์ฉํฉ๋๋ค. Refresh Token์ Authorization Server์๋ง ์ ๋ฌ๋๋ฉฐ, Resource Server์๋ ์ ๋ฌ๋์ง ์์ต๋๋ค.
Client๊ฐ ์ ๊ทผํ ์ ์๋ ๋ฆฌ์์ค์ ๋ฒ์๋ฅผ ์ ํํ๋ ๋ฉ์ปค๋์ฆ์
๋๋ค. ๊ตฌ๊ธ OAuth์์ drive.readonly scope๋ฅผ ์์ฒญํ๋ฉด, ํด๋น ์ฑ์ ๋๋ผ์ด๋ธ๋ฅผ ์ฝ๊ธฐ๋ง ํ ์ ์๊ณ ์์ ์ ํ ์ ์์ต๋๋ค.
Access Token ๋ฐ๊ธ ์์ฒญ ์์:
scope=drive.readonly+calendar.events
โ ๋๋ผ์ด๋ธ ์ฝ๊ธฐ + ์บ๋ฆฐ๋ ์ด๋ฒคํธ ์ ๊ทผ๋ง ํ์ฉ
โ ๋๋ผ์ด๋ธ ์ฐ๊ธฐ, ๋ฉ์ผ ์ ๊ทผ ๋ฑ์ ๋ถ๊ฐ
RFC 6749๋ 4๊ฐ์ง ๊ธฐ๋ณธ Grant Type(Authorization Code, Implicit, Resource Owner Password Credentials, Client Credentials)์ ์ ์ํฉ๋๋ค. ์ด ์ค Implicit๊ณผ ROPC๋ ๋ณด์ ๋ฌธ์ ๋ก ํ์ฌ ๋น๊ถ์ฅ๋๋ฉฐ, ์ดํ RFC 8628์ด Device Authorization Grant๋ฅผ ์ถ๊ฐ๋ก ์ ์ํ์ต๋๋ค. ์๋์์๋ ํ์ฌ ๊ถ์ฅ๋๋ ๋ฐฉ์์ ์ค์ฌ์ผ๋ก ์ค๋ช ํฉ๋๋ค.
๊ฐ์ฅ ๋๋ฆฌ ์ฌ์ฉ๋๋ฉฐ, ๋ณด์์ฑ์ด ๊ฐ์ฅ ๋์ ๋ฐฉ์์ ๋๋ค. ์๋ฒ ์ฌ์ด๋ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ํฉํฉ๋๋ค.
[์ฌ์ฉ์] โ [Client ์ฑ] โ [Authorization Server ๋ก๊ทธ์ธ ํ๋ฉด์ผ๋ก ๋ฆฌ๋ค์ด๋ ํธ]
โ
์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธ & ๋์
โ
Authorization Code๋ฅผ Client์๊ฒ ์ ๋ฌ (redirect)
โ
Client๊ฐ Authorization Code๋ฅผ ์๋ฒ ๊ฐ ํต์ ์ผ๋ก Access Token๊ณผ ๊ตํ
ํต์ฌ์ Access Token์ด ์ฌ์ฉ์์ ๋ธ๋ผ์ฐ์ ๋ฅผ ๊ฑฐ์น์ง ์๋๋ค๋ ์ ์ ๋๋ค.
/authorize ์๋ํฌ์ธํธ๋ก ๋ฆฌ๋ค์ด๋ ํธํฉ๋๋ค.redirect_uri๋ก ๋ฆฌ๋ค์ด๋ ํธํ๋ฉด์ Authorization Code๋ฅผ ์ ๋ฌํฉ๋๋ค./token ์๋ํฌ์ธํธ๋ก ๋ณด๋ด์ Access Token์ผ๋ก ๊ตํํฉ๋๋ค (์๋ฒ ๊ฐ ๋ฐฑ์ฑ๋ ํต์ ).Authorization Code ์์ฒด๋ ์ผํ์ฑ์ด๋ฉฐ ์งง์ ์ ํจ๊ธฐ๊ฐ์ ๊ฐ์ง๋๋ค.
์ฌ์ฉ์ ๊ฐ์ ์์ด, ์ ํ๋ฆฌ์ผ์ด์ ์์ฒด์ ์๊ฒฉ ์ฆ๋ช ์ผ๋ก Access Token์ ๋ฐ๊ธ๋ฐ๋ ๋ฐฉ์์ ๋๋ค. ์๋ฒ ๊ฐ(M2M, Machine-to-Machine) ํต์ ์ ์ฌ์ฉ๋ฉ๋๋ค.
[Client] โโ(client_id + client_secret)โโโ [Authorization Server]
[Client] โโโโโโโโโ(Access Token)โโโโโโโโ [Authorization Server]
์ฌ์ฉ์๋ผ๋ ๊ฐ๋ ์ด ์์ผ๋ฏ๋ก, Client ์์ฒด๊ฐ ๋ฆฌ์์ค์ ์์ ์์ด๊ฑฐ๋ ์ฌ์ ์ ์ ๊ทผ ๊ถํ์ด ๋ฐฐ์น๋ ๊ฒฝ์ฐ์๋ง ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค. ๋ฐ๋์ Confidential Client(๋น๋ฐํค๋ฅผ ์์ ํ๊ฒ ๋ณด๊ดํ ์ ์๋ ์๋ฒ ์ฑ)์์๋ง ์ฌ์ฉํด์ผ ํฉ๋๋ค.
TV, IoT ๊ธฐ๊ธฐ, CLI ๋๊ตฌ ๋ฑ ๋ธ๋ผ์ฐ์ ๊ฐ ์๊ฑฐ๋ ์ ๋ ฅ์ด ์ ํ๋ ๋๋ฐ์ด์ค์์ ์ฌ์ฉํ๋ ๋ฐฉ์์ ๋๋ค. RFC 8628์ ์ ์๋์ด ์์ต๋๋ค.
[๋๋ฐ์ด์ค] โ Authorization Server์ Device Code ์์ฒญ
โ
ํ๋ฉด์ URL๊ณผ ์ฝ๋๋ฅผ ํ์
(์: "https://example.com/device ์์ ์ฝ๋ ABCD-1234๋ฅผ ์
๋ ฅํ์ธ์")
โ
[์ฌ์ฉ์๊ฐ ๋ค๋ฅธ ๊ธฐ๊ธฐ(ํฐ/PC)์์ ํด๋น URL์ ์ ์ํ์ฌ ์ฝ๋๋ฅผ ์
๋ ฅํ๊ณ ๋ก๊ทธ์ธ]
โ
[๋๋ฐ์ด์ค๊ฐ ์ฃผ๊ธฐ์ ์ผ๋ก Authorization Server์ ํด๋งํ์ฌ Access Token ์์ ]
| Grant Type | ์ค๋ช | ๋น๊ถ์ฅ ์ฌ์ |
|---|---|---|
| Implicit Grant | ํ ํฐ์ ๋ธ๋ผ์ฐ์ URL ํ๋๊ทธ๋จผํธ๋ก ์ง์ ๋ฐํ | Access Token์ด ๋ธ๋ผ์ฐ์ ํ์คํ ๋ฆฌ, ๋ก๊ทธ ๋ฑ์ ๋ ธ์ถ. RFC 9700์์ SHOULD NOT (์ฌ์ฉ ๋น๊ถ์ฅ) |
| Resource Owner Password Credentials | ์ฌ์ฉ์์ ID/PW๋ฅผ Client๊ฐ ์ง์ ๋ฐ์ ํ ํฐ ์์ฒญ | OAuth๊ฐ ํด๊ฒฐํ๋ ค๋ ๊ทผ๋ณธ ๋ฌธ์ (๋น๋ฐ๋ฒํธ ์ง์ ๊ณต์ )๋ฅผ ๋ค์ ๋ง๋ฆ. RFC 9700์์ MUST NOT (์ฌ์ฉ ๊ธ์ง) |
Authorization Code Grant์๋ ์ทจ์ฝ์ ์ด ํ๋ ์์ต๋๋ค. ๋ชจ๋ฐ์ผ ํ๊ฒฝ์์ ์ ์ฑ ์ฑ์ด ์ปค์คํ URL ์คํด์ ๊ฐ๋ก์ฑ์ Authorization Code๋ฅผ ํ์ทจํ ์ ์์ต๋๋ค. Authorization Server ์ ์ฅ์์๋ ์ฝ๋๋ฅผ ์์ฒญํ ์ ๋นํ ์ฑ๊ณผ ๊ฐ๋ก์ฑ ์ ์ฑ ์ฑ์ ๊ตฌ๋ถํ ์ ์์ต๋๋ค.
PKCE(๋ฐ์: "ํฝ์")๋ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํฉ๋๋ค. RFC 7636์ ์ ์๋์ด ์์ผ๋ฉฐ, ์๋๋ Public Client๋ฅผ ์ํด ์ค๊ณ๋์์ง๋ง ํ์ฌ๋ ๋ชจ๋ Client ์ ํ์ ๊ถ์ฅ๋ฉ๋๋ค. OAuth 2.1 ์ด์์์๋ ํ์ ์ฌํญ์ ๋๋ค.
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 1. Client๊ฐ code_verifier ์์ฑ (43~128์ ๋๋ค ๋ฌธ์์ด) โ
โ โ
โ 2. code_verifier โ SHA-256 ํด์ โ Base64URL ์ธ์ฝ๋ฉ โ
โ = code_challenge โ
โ โ
โ 3. /authorize ์์ฒญ ์ code_challenge ์ ์ก โ
โ Authorization Server๊ฐ code_challenge ์ ์ฅ โ
โ โ
โ 4. /token ์์ฒญ ์ ์๋ณธ code_verifier ์ ์ก โ
โ Authorization Server๊ฐ code_verifier๋ฅผ ํด์ํ์ฌ โ
โ ์ ์ฅํด๋ code_challenge์ ๋น๊ต โ
โ โ
โ 5. ์ผ์น โ Access Token ๋ฐ๊ธ โ
โ ๋ถ์ผ์น โ ๊ฑฐ๋ถ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
์
์ฑ ์ฑ์ด Authorization Code๋ฅผ ๊ฐ๋ก์ฑ๋๋ผ๋ code_verifier๋ฅผ ๋ชจ๋ฅด๊ธฐ ๋๋ฌธ์ ํ ํฐ ๊ตํ์ ์คํจํฉ๋๋ค. SHA-256์ ๋จ๋ฐฉํฅ ํด์์ด๋ฏ๋ก code_challenge์์ code_verifier๋ฅผ ์ญ์ฐํ ์๋ ์์ต๋๋ค.
RFC 7636์ code_challenge_method๋ก S256(SHA-256)๊ณผ plain(ํด์ ์์ด code_verifier๋ฅผ ๊ทธ๋๋ก ์ฌ์ฉ) ๋ ๊ฐ์ง๋ฅผ ์ ์ํฉ๋๋ค. S256์ MTI(Mandatory To Implement)์ด๋ฉฐ, plain์ ๊ธฐ์ ์ ์ผ๋ก SHA-256์ ์ง์ํ ์ ์๋ ํ๊ฒฝ์์๋ง ์ฌ์ฉํด์ผ ํฉ๋๋ค. plain์ code_verifier๊ฐ ์ ์ก ์ค ๋
ธ์ถ๋๋ฉด ๋ณดํธ ํจ๊ณผ๊ฐ ์์ผ๋ฏ๋ก, ํน๋ณํ ์ ์ฝ์ด ์๋ ํ ๋ฐ๋์ S256์ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
RFC 6749๋ Client๋ฅผ ์ธ์ฆ ์๊ฒฉ ์ฆ๋ช ์ ๋ณด์ ์์ค์ ๋ฐ๋ผ ๋ ๊ฐ์ง๋ก ๋ถ๋ฅํฉ๋๋ค.
| ์ ํ | ์ค๋ช | ์์ |
|---|---|---|
| Confidential Client | Client Secret์ ์์ ํ๊ฒ ๋ณด๊ดํ ์ ์๋ ํด๋ผ์ด์ธํธ. ์๋ฒ ํ๊ฒฝ์์ ์คํ | ์๋ฒ ์ฌ์ด๋ ์น ์ฑ, ๋ฐฑ์๋ ์๋น์ค |
| Public Client | Client Secret์ ์์ ํ๊ฒ ๋ณด๊ดํ ์ ์๋ ํด๋ผ์ด์ธํธ. ์์ค ์ฝ๋๊ฐ ์ฌ์ฉ์์๊ฒ ๋ ธ์ถ | SPA, ๋ชจ๋ฐ์ผ ์ฑ, ๋ฐ์คํฌํฑ ์ฑ |
Public Client๋ Client Secret ์์ด ๋์ํด์ผ ํ๋ฏ๋ก, ๋ฐ๋์ PKCE๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
| ํญ๋ชฉ | OAuth 2.0 (RFC 6749) | OAuth 2.1 (์ด์) | OpenID Connect |
|---|---|---|---|
| ๋ชฉ์ | ์ธ๊ฐ(Authorization) | ์ธ๊ฐ(Authorization) | ์ธ์ฆ(Authentication) + ์ธ๊ฐ |
| PKCE | ์ ํ | ํ์ | ์ ํ/๊ถ์ฅ |
| Implicit Grant | ํ์ฉ | ์ญ์ | ํ์ฉ(๋น๊ถ์ฅ) |
| Password Grant | ํ์ฉ | ์ญ์ | ํด๋น ์์ |
| ํต์ฌ ํ ํฐ | Access Token | Access Token | Access Token + ID Token |
OAuth 2.0์ด "์ด ์ฑ์ด ๋ด ๋ฐ์ดํฐ์ ์ ๊ทผํด๋ ๋๋๊ฐ?"๋ผ๋ ์ธ๊ฐ ์ง๋ฌธ์ ๋ตํ๋ค๋ฉด, OIDC๋ "์ด ์ฌ์ฉ์๊ฐ ๋๊ตฌ์ธ๊ฐ?"๋ผ๋ ์ธ์ฆ ์ง๋ฌธ์ ๋ตํฉ๋๋ค. OIDC๋ ID Token(JWT ํ์)์ ํตํด ์ฌ์ฉ์์ ์ ์ ์ ๋ณด๋ฅผ ์ ๊ณตํฉ๋๋ค.
OAuth 2.0 ์ํ๊ณ๋ ํต์ฌ ํ๋ ์์ํฌ ์์ ๋ค์ํ ๋ณด์กฐ ์คํ๋ค๋ก ๊ตฌ์ฑ๋ฉ๋๋ค.
| RFC/์คํ | ์ด๋ฆ | ์ญํ |
|---|---|---|
| RFC 6749 | OAuth 2.0 Framework | ํต์ฌ ํ๋ ์์ํฌ |
| RFC 6750 | Bearer Token Usage | Access Token์ HTTP ์์ฒญ์ ํฌํจํ๋ ๋ฐฉ๋ฒ |
| RFC 7636 | PKCE | Authorization Code ๊ฐ๋ก์ฑ๊ธฐ ๋ฐฉ์ด |
| RFC 7009 | Token Revocation | ํ ํฐ ๋ฌดํจํ ์๋ํฌ์ธํธ |
| RFC 7662 | Token Introspection | ํ ํฐ ์ ํจ์ฑ๊ณผ ๋ฉํ์ ๋ณด ์กฐํ |
| RFC 8414 | Authorization Server Metadata | OAuth ์๋ํฌ์ธํธ ์๋ ๊ฒ์ |
| RFC 8628 | Device Authorization Grant | ๋ธ๋ผ์ฐ์ ์๋ ๋๋ฐ์ด์ค์ฉ ์ธ๊ฐ |
| RFC 9068 | JWT Profile for Access Tokens | Access Token์ JWT๋ก ๊ตฌ์กฐํ |
| RFC 9700 | Security Best Current Practice | ๋ณด์ ๋ชจ๋ฒ ์ฌ๋ก (Implicit/Password ๊ธ์ง ๋ฑ) |
RFC 9700 (OAuth 2.0 Security Best Current Practice)์์ ๊ถ๊ณ ํ๋ ํต์ฌ ์ฌํญ์ ๋๋ค.