본문 바로가기

개발

OAuth 2.0과 OpenID Connect(OIDC)의 차이점과 활용법

OAuth 2.0은 사용자의 자격 증명을 직접 노출하지 않고,

타사 서비스가 사용자 데이터를 안전하게 액세스할 수 있도록 설계된 인증 및 권한 위임 프로토콜입니다.

이를 통해 사용자는 내 비밀번호를 직접 제공하지 않고도 Google, Facebook, GitHub 등의 계정을

사용하여 다른 서비스에 로그인하거나, 특정 API 권한을 위임할 수 있습니다.

AI에서 Agent들의 인증 인가를 위해서 개념을 다시한번 정리 한다. 


🔹 1. OAuth 2.0의 주요 개념

https://cloud.google.com/apigee/docs/api-platform/security/oauth/oauth-introduction?hl=ko

 

1) 클라이언트(Client)

  • OAuth를 사용하는 애플리케이션 (예: 쿠팡이 네이버 로그인 기능을 사용할 때, 쿠팡이 클라이언트)
  • 사용자 데이터를 직접 저장하지 않으며, 액세스 토큰을 통해 권한을 부여받음

2) 리소스 소유자(Resource Owner)

  • OAuth 인증을 진행하는 사용자 (예: 네이버 로그인 시, 네이버 계정을 가진 사용자)
  • 자신의 데이터를 타사 애플리케이션이 접근하도록 승인할 수 있음

3) 리소스 서버(Resource Server)

  • 보호된 리소스를 제공하는 서버 (예: Google Drive, Facebook API, GitHub API)
  • 클라이언트가 액세스 토큰을 제공하면 해당 데이터를 반환

4) 권한 서버(Authorization Server)

  • 액세스 토큰을 발급하는 서버 (예: Google OAuth Server, Facebook OAuth Server)
  • 클라이언트의 인증 요청을 받아 토큰을 생성하고, 사용자 권한을 검증함

5) 액세스 토큰(Access Token)

  • 클라이언트가 리소스 서버에 접근할 때 사용하는 토큰
  • 일반적으로 JWT(JSON Web Token) 형식으로 발급됨
  • 특정 유효 기간이 있으며, 만료되면 새로 갱신해야 함

6) 리프레시 토큰(Refresh Token)

  • 액세스 토큰이 만료되었을 때, 사용자의 재승인 없이 새로운 액세스 토큰을 요청하는 데 사용됨
  • 리프레시 토큰은 일반적으로 장기간 유효함

🚀 리소스 서버(Resource Server) vs 권한 서버(Authorization Server) 차이점

📌 요약:

  • 리소스 서버 = "데이터 제공 (Access Token 필요)"
  • 권한 서버 = "사용자 인증 & Access Token 발급"
  • 권한서버에서는 토큰을 발급
  • 리소스 서버는 토큰을 검증

 

🔹 리소스 서버 토큰 검증 방식

리소스 서버가 Access Token을 검증

✅ 1) 권한 서버에 검증 요청 (Remote Introspection)

✅ 2) 토큰을 직접 검증 (Local JWT Validation)

  • 위 두가지 방법으로 토큰을 검증하는데 보통 리소스 서버에서 토큰을 직접 검증하는 방법을 쓴다 
  • 권한 서버는 Access Token을 JWT 형식으로 발급한다 
  • 리소스 서버는 권한 서버의 해석하여 유효성 검증한다 

🔹 Google Drive + Notion OAuth 2.0 예제

📌 시나리오:

👉 내가 Notion에서 Google Drive 파일을 연동하려고 함

👉 Notion이 내 Google Drive 파일에 접근할 수 있도록 허용(OAuth 2.0 권한 위임)

📌 OAuth 2.0 역할 정리

역할 예제

클라이언트(Client) Notion (Google Drive 파일을 접근하려는 서비스)
리소스 소유자(Resource Owner) 나 (Google Drive 파일의 주인, 권한을 위임하는 사람)
사용자(User) 나 (Notion을 사용하는 사용자, 로그인하는 주체)
리소스 서버(Resource Server) Google Drive API (보호된 리소스, 즉 내 파일을 제공하는 서버)
권한 서버(Authorization Server) Google OAuth Server (Access Token을 발급하는 서버)

🚀 OIDC (OpenID Connect)는 OAuth 2.0과 어떤 차이가 있을까?

OAuth 2.0은 "권한 위임(Authorization)"을 위한 프로토콜이지만,

OIDC(OpenID Connect)는 "사용자 인증(Authentication)"을 위한 프로토콜

📌 문제점 (OAuth 2.0만 사용할 때 발생하는 문제)

✅ OAuth 2.0의 Access Token에는 "사용자가 누구인지"에 대한 정보가 없음

✅ 클라이언트가 Access Token만 가지고 있으면, 사용자의 프로필 정보를 확인할 방법이 없음

✅ Access Token은 "특정 API 접근 권한"만 부여할 뿐, 사용자 인증을 보장하지 않음

📌 Access Token을 jwt로 발급할때 사용자 정보를 넣으면 리소스 서버가 jwt를 검증 하면 사용자가 누군지 알수있지 않나?  OIDC가 필요 없는 거 아니야?"

🔹 1. Access Token에 사용자 정보를 포함하는 것의 문제점
👉 OAuth 2.0에서 Access Token을 JWT로 발급할 때 사용자 정보를 넣을 수 있지만,
이 방식은 몇 가지 보안 및 설계상 문제를 일으킬 수 있음

문제 1: 사용자 정보가 토큰에 있으면 변경이 불가능함

  • JWT는 한 번 발급되면 내용이 변경되지 않음 (Immutable)
  • 만약 사용자가 이름, 이메일을 변경하면?
    • 기존 Access Token을 가진 클라이언트(예: Notion)는 여전히 변경 전 정보를 사용하게 됨

📌 예제

1️⃣ 사용자가 Google 계정에서 이름을 "John Doe" → "Jack Doe"로 변경

2️⃣ 기존 Access Token은 "John Doe"로 저장된 상태

3️⃣ Notion이 Google Drive API를 호출하면 여전히 "John Doe"로 보임

OIDC에서는 ID Token을 사용하고, 추가로 /userinfo API를 호출하면 최신 사용자 정보를 받을 수 있음


문제 2: 보안 위험 (토큰 노출 시 개인 정보 유출)

  • Access Token이 JWT로 발급되면서 email, name 같은 사용자 정보가 포함되면, 토큰이 유출될 경우 개인 정보도 함께 노출됨
  • JWT는 디코딩(Base64 Decode)이 가능하기 때문에 토큰을 가로채면 누구의 데이터인지 쉽게 확인 가능

📌 예제 (JWT Access Token 디코딩)


{
  "sub": "user_12345",
  "name": "John Doe",
  "email": "johndoe@example.com",
  "scope": "read write"
}
  • JWT는 Base64로 인코딩된 문자열이므로, 누구나 쉽게 디코딩하여 사용자 정보를 볼 수 있음
  • Access Token은 주로 브라우저나 모바일 앱에서 저장되므로, 노출 위험이 있음

해결 방법:

  • Access Token에는 최소한의 정보(sub, scope)만 포함하고, 사용자 정보는 별도로 /userinfo API에서 가져오는 방식 사용
  • 이 방식이 OIDC에서 일반적으로 사용됨

🔹 2. OIDC에서는 어떻게 해결할까?

OIDC에서는 Access Token이 아니라 ID Token을 사용하여 "사용자가 누구인지"를 확인합니다.

✔ OAuth 2.0에서는 사용자별로 승인한 scope(권한)가 다를 수 있기 때문에, 클라이언트가 /userinfo API를 호출해서 실제 사용자 정보를 가져와야 함

✔ Access Token만 보고는 어떤 사용자 정보를 가져올 수 있는지 알 수 없기 때문에, /userinfo API를 호출해야 함

OAuth 2.0만 사용할 때 (문제 발생)

1️⃣ 사용자가 Google 로그인 버튼 클릭

2️⃣ Google OAuth 서버가 로그인 처리 후 Access Token 발급

3️⃣ 클라이언트가 Google API(/userinfo)를 호출해서 사용자 정보 가져오기

4️⃣ (문제점) Access Token이 만료되거나 유출될 경우, 보안 문제 발생

4️⃣ (문제점) Access Token이 만료되거나 유출될 경우, 보안 문제 발생

[1] 사용자 → 클라이언트 (Google 로그인 버튼 클릭)
[2] 클라이언트 → Google OAuth Server (Access Token 요청)
[3] Google OAuth Server → 클라이언트 (Access Token 발급)
[4] 클라이언트 → Google API (/userinfo 요청)
[5] Google API → 클라이언트 (사용자 프로필 정보 반환)

문제점:

  • 매번 /userinfo API를 호출해야 최신 사용자 정보를 가져올 수 있음
  • Access Token이 유출되면 사용자 정보가 노출될 위험이 있음

OIDC를 사용한 경우 (해결 방법)

1️⃣ 사용자가 Google 로그인 버튼 클릭

2️⃣ Google OAuth 서버가 로그인 처리 후 ID Token + Access Token 발급

3️⃣ 클라이언트가 ID Token을 검증하여 로그인 완료

4️⃣ 최신 사용자 정보가 필요하면 /userinfo API 호출

[1] 사용자 → 클라이언트 (Google 로그인 버튼 클릭)
[2] 클라이언트 → Google OAuth Server (ID Token + Access Token 요청)
[3] Google OAuth Server → 클라이언트 (ID Token + Access Token 발급)
[4] 클라이언트 → ID Token 검증 후 로그인 완료
[5] (필요할 경우) 클라이언트 → Google API (/userinfo 요청)

OIDC의 장점:

  • ID Token을 활용하여 "사용자가 누구인지" 바로 확인 가능
  • Access Token에는 최소한의 정보만 포함하여 보안 강화
  • 최신 사용자 정보가 필요할 때만 /userinfo API 호출

Access Token은 탈취될 위험이 있는데, ID Token은 안전한가?

👉 OIDC 방식(ID Token 사용)이 보안적으로 더 안전한 이유는 "ID Token이 클라이언트에서만 사용되고, 서버 API 요청에 사용되지 않기 때문"

📌Access Token은 API 요청마다 서버로 전송되므로 탈취 위험이 높음!

📌ID Token은 서버에서 클라이언트로 한 번만 전달되므로, 네트워크에서 노출될 가능성이 낮음!

📌 ID Token이 탈취되면?

  • 해커가 ID Token을 가로채더라도, API 요청에는 사용할 수 없음 (Access Token이 필요하기 때문)

🔹 1. OIDC를 사용해도 Access Token이 유출되면 어떻게 되나?

Access Token이 탈취되면, 해커는 리소스 서버(API)에 요청을 보낼 수 있음

Access Token만 있으면 사용자의 데이터를 불법적으로 접근 가능

✅ OIDC가 있든 없든 Access Token 유출 자체는 큰 보안 위협!

🔹 2. OIDC가 OAuth 2.0보다 보안적으로 더 나은 이유

💡 "Access Token이 유출되면 API를 사용할 수 있는 건 똑같은데, 왜 OIDC가 더 안전하다고 하나?"

OIDC는 OAuth 2.0의 인증(Authentication) 기능을 강화하여 보안성을 높입니다.

즉, OIDC가 Access Token 자체를 보호하는 건 아니지만, 보안 강화를 위한 추가적인 보호 기능을 제공합니다.

🔹 3. OIDC를 사용하면 Access Token 유출을 어떻게 방지할 수 있나?

OIDC는 Access Token 유출을 방지하기 위해 추가적인 보안 조치를 제공합니다.

1) ID Token을 활용하여 Access Token 탈취 탐지

💡 "Access Token이 탈취되었는지 확인할 방법이 있을까?"

OIDC에서는 ID Token을 사용하여 클라이언트에서 Access Token이 정상적으로 사용되고 있는지 확인 가능합니다.

📌 Access Token을 요청하는 클라이언트의 정보(azp, aud)를 검증하여 이상 탐지 가능

aud (Audience, 대상)

  • Access Token을 사용할 수 있는 대상(리소스 서버, API)을 지정
  • 리소스 서버(API)는 Access Token의 aud 값을 확인하여, 자신을 위한 토큰인지 검증
  • 예를 들어, Google Drive API에서 사용해야 하는 Access Token이면 aud 값이 Google Drive의 Client ID가 됨

azp (Authorized Party, 인증된 클라이언트)

  • Access Token을 발급받은 클라이언트(Client)의 ID
  • 보통 OAuth 2.0에서 클라이언트가 여러 개일 경우, 특정 클라이언트만 사용할 수 있도록 제한하는 역할
  • 예를 들어, Notion이 Google Drive에 접근하려고 하면, azp 값은 Notion의 Client ID가 됨

azp 값이 변경된 경우 → Access Token 탈취 가능성!

  • Access Token은 **Notion(Client A)**에서 발급받았는데,
  • 다른 클라이언트(Client B)가 API 요청 시 사용하고 있다면?
  • Access Token이 탈취되었을 가능성이 있음! 🚨

aud 값이 변경된 경우 → Access Token이 다른 API에서 사용됨!

  • Access Token은 Google Drive API에서 사용하려고 발급받았는데,
  • 다른 API(Gmail API)에서 사용하려고 하면?
  • Access Token이 유출되어 다른 API에서 사용될 가능성이 있음! 🚨

📌 Access Token이 유출되었다면, 다른 클라이언트에서 요청이 오므로 탐지 가능

2) Access Token을 주기적으로 갱신하여 유출된 토큰을 무효화 (Refresh Token Rotation)

💡 "Access Token이 탈취되었을 때, 이를 막을 방법이 있을까?"

OIDC는 Refresh Token Rotation을 사용하여 Access Token을 주기적으로 갱신할 수 있습니다.

📌 방식

1️⃣ 클라이언트는 Access Token과 함께 Refresh Token을 받음

2️⃣ Access Token이 만료되면, Refresh Token을 이용하여 새 Access Token을 발급

3️⃣ 기존 Refresh Token은 무효화됨 → 해커가 탈취한 Access Token은 더 이상 사용 불가!

✅ Refresh Token을 한 번 사용하면 즉시 폐기하고, 새로운 Refresh Token을 발급 ✅ 탈취된 Refresh Token이 사용될 경우, 비정상적인 요청으로 감지하여 세션 종료

 

해커가 사용되지 않은 Refresh Token을 탈취하면 기존 사용자는 어떻게 되나?

💡 "해커가 내 Refresh Token을 먼저 사용하면, 내 세션은 어떻게 되는 거야?"

✅ 해커가 Refresh Token을 먼저 사용하면,기존 사용자의 Refresh Token은 즉시 폐기됨

✅ 기존 사용자가 Access Token을 갱신하려 하면,"Refresh Token이 유효하지 않음" 오류 발생

✅ 따라서 기존 사용자는새로운 로그인을 해야 함

 

📌 이상 탐지 시스템이 작동하여 기존 사용자에게 경고

👉 권한 서버는 Refresh Token을 사용할 때 'IP, 디바이스 정보, 위치'를 기록하여 이상 요청을 탐지

📌 정상적인 경우

- 기존 사용자 IP: 192.168.1.10
- Refresh Token 사용 IP: 192.168.1.10