🌱 Infra/KeyCloak

[keycloak 맛보기 #4] Keycloak의 애플리케이션 보안

mini_world 2024. 12. 9. 00:26
목차 접기

웹 애플리케이션 보호 

 

1️⃣ 개요

웹 애플리케이션은 기본적으로 인가코드흐름(Authorization Code Flow)를 사용해야하며,
PKCE(Proof key for Code Exchange)를 함께 사용하는것이 좋다.

인가코드 흐름(Authorization Code Flow)는 아래와 같은 인증 흐름을 가진다.

# [초기 로그인 흐름]
Browser                     App Server                  Keycloak
   |                            |                          |
   |----(1) 접근 시도------------>|                          |
   |                            |                          |
   |<---(2) 로그인 페이지 리다이렉트--|                          |
   |                            |                          |
   |----(3) 로그인 요청-------------------------------------->|
   |                            |                          |
   |<---(4) 인가 코드 전달------------------------------------|
   |                            |                          |
   |----(5) 인가 코드 전달-------->|                          |
   |                            |----(6) 토큰 교환---------->|
   |                            |<---(7) 토큰 응답-----------|
   |                            |                          |
   |                            |---(8) 토큰 저장            |
   |<--(9) 세션 쿠키 발급----------|                          |
   |                            |                          |

# [이후 API 요청 흐름]
Browser                     App Server                  Resource Server
   |                            |                          |
   |----(1) API 요청------------>|                          |
   |   (세션 쿠키 포함)            |                          |
   |                            |----(2) API 요청---------->|
   |                            |  (저장된 토큰 사용)          |
   |                            |<---(3) API 응답-----------|
   |<---(4) 결과 전달-------------|                          |

또한 고려해야할 부분은 어떤 아키텍쳐의 웹 어플리케이션을 운영하는지에 따라 고려해야할 보안옵션이 달라진다.
특히 보안수준의 차이, 토큰 관리방식의 차이가 아키텍쳐마다 상이하므로, 각각의 사용사례와 요구사항에 따라 적잘한 보안설정을 하는것이 중요하다.

웹 어플리케이션 아키텍쳐 구분 간단 설명 
Server Side  • Access Type: confidential
• Client Authentication: 필수 (Client Secret 사용)
• Standard Flow: 활성화
• PKCE: 권장
• Token Storage: 서버 측 안전한 저장소

특징: 가장 안전한 구성, 토큰을 서버에서 완전히 제어
SPA with dedicated Rest API • Access Type: public
• Client Authentication: 불가능
• Standard Flow: 활성화
• PKCE: 필수
• Token Storage: 브라우저 (메모리 권장)

추가 고려사항:
• BFF(Backend For Frontend) 패턴 고려
• 토큰 갱신 로직 프론트엔드 구현
SPA with intermediary API • Access Type: public (프론트엔드)
• Client Authentication: confidential (중개 서버)
• Standard Flow: 활성화
• PKCE: 필수
• Token Storage:
- 프론트엔드: 메모리
- 중개 서버: 안전한 저장소

추가 고려사항:
• 중개 서버에서 토큰 관리
• 프론트엔드는 세션 쿠키만 사용
SPA with external API • Access Type: public
• Client Authentication: 불가능
• Standard Flow: 활성화
• PKCE: 필수
• Token Storage: 브라우저 (메모리 권장)

추가 고려사항:
• CORS 설정 필수
• 외부 API의 인증 요구사항 준수
• 토큰 갱신 전략 수립

 

 

2️⃣ 공통적으로 적용해야하는 보안 설정

  1. 인가코드흐름(Authorization Code Flow) 사용 (= Standard Flow)
    • 인가코드흐름(Authorization Code Flow)은 OAuth 2.0의 권장되는 흐름히다.
    • 클라이언트가 인가코드를 통해 토큰을 얻는 방식이다.
    • 액세스 토큰이 브라우저를 통하지 않고 백엔드 서버에서 직접 교환되는 방식으로 보안성이 가장 높은 인증방식이다.
    • 주의사항: 클라이언트 시크릿이 노출되지 않도록 주의 해야한다.
  2. PKCE(Proof key for Code Exchange) 사용
    • 인가코드(Authorization Code)를 인터셉트 공격으로부터 방지하기 위한 기술
    • Keycloak에서는 Client > Advanced 탭 > Advanced settings > Proof Key for Code Exchange Code Challenge Method 에서 활성화 한다. (S256 권장) 
  3. Keycloak 로그인 페이지 활용
    • keycloak에서 제공하는 로그인 페이지를 이용하는것이 좋다. 
    • 기존 로그인 페이지 유지 (Resource Owner Password Credential) ❌사용하지 않는것이 좋다.❌
      단일 앱 보안 침해로 전체 시스템이 위험해질 수 있다.
    • iframe 내 Keycloak 로그인 ❌사용하지 않는것이 좋다.❌
      클릭재킹, 피싱공격(출처확인어려움)에 취약하며, 
      브라우저의 서드파티 쿠키 차단으로인한 오류가 발생할 수 있다.
  4. Valid Redirect URIs 제한
    • 인증 후 Redirect 가능한 URI목록을 정의하는 부분이며, 정확한 URI로 Redirect되도록 설정해야한다. 
    • 예) https://your-app.com/callback/*
    • 적절하지 않은 설정을 사용할 경우 OpenRedirect 취약점이 생긴다.
  5. Web Origins 설정
    • CORS 요청을 허용할 오리진을 설정하는 부분이며, 클라이언트의 도메인을 제한한다.
    • 허가되지 않은 도메인에서의 요청을 차단한다.
  6. 토큰 라이프타임 설정
    • 액세스 토큰과 리프레시 토큰의 유효기간을 설정하여 세션 지속 시간을 제어한다.
    • Refresh Token은 재사용 하지 않도록 설정해야한다.
    • 토큰 탈취 시 피해를 최소화 할 수 있다.
      • Access Token: 5-15분
      • Refresh Token: 8-24시간
      • SSO Session: 8-10시간
  7. Implicit Flow 비활성화
    • 토큰을 URL 파라메터로 전달하는 방식이며, 보안 이슈로 사용하지 않는것이 좋다.

 

3️⃣ Server Side 보안설정

서버 사이드 웹 애플리케이션은 가장 전통적인 방식의 웹 애플리케이션으로, 
서버 애플리케이션과 Keycloak 사이에서만 Token이 교환된다. 
서버 애플리케이션 내에 Token이 저장되며, 브라우저는 Session Cookie를 가지고 리소스에 접근한다.

# 아키텍쳐
[브라우저]
    ↕ (세션 쿠키)
[서버 애플리케이션] ←→ [Keycloak]
    ↕                
[리소스/DB]              
                        
# 인증 플로우             
1. 브라우저 → 서버: 로그인 요청
2. 서버 → Keycloak: Authorization Code 요청
3. 사용자 → Keycloak: 로그인
4. Keycloak → 서버: 인증 코드
5. 서버 → Keycloak: 토큰 교환 (client secret 사용)
6. 서버: 토큰 안전하게 저장
7. 서버 → 브라우저: 세션 쿠키 발급
8. 이후 요청: 브라우저 → 서버로 세션 쿠키를 포함하여 요청
9. 서버: 세션 쿠키 검증 후 필요시 토큰으로 리소스 접근

다른 SPA아키텍쳐와 비교한다면 아래와 같은 특징을 가진다.  

  • 토큰이 클라이언트에 노출되지 않음
  • XSS 공격으로부터 상대적으로 안전
  • 세션 관리가 서버에서 중앙화됨

서버 사이드 웹 애플리케이션을 보호하는 경우에는 아래와 같은 설정을 한다.

  • Public Client가 아닌 Confidential Client로 설정한다.
    • 서버사이드 웹 애플리케이션의 경우 Client Secret은 서버에서만 안전하게 보관하고 사용한다.
      (서버에서 안전하기 보관되기때문)
    • Confidential Client를 사용하면 유출된 인가코드를 악용할 수 없다.
  • PKCE (Proof Key for Code Exchange) 활성화를 권장한다.
    • 인증 코드 인터셉트 공격 방지할 수 있다.
    • Authorization Code Flow와 함께 사용하는것을 권장한다.

 

4️⃣ SPA with dedicated Rest API 보안설정

이 아키텍쳐는 브라우저에 렌더링 된 클라이언트(브라우저)에서 Keycloak과 백엔드 API를 직접 호출한다.
SPA에서는 Keycloak과 직접 통신하기때문에, 토큰이 클라이언트(브라우저)에 노출되므로 토큰 저장과 관리에 특별한 주의가 필요하다.

# 아키텍쳐
[브라우저]
    |
    |── SPA (프론트엔드)
    |      ↕ (로컬 저장소/메모리)
    |   [Keycloak]
    |      ↓ (액세스 토큰)
    |      ↓
    ↓      ↓
[백엔드 API] ←→ [리소스/DB]

# 인증 플로우
1. SPA → Keycloak: Authorization Code 요청 (PKCE 사용)
2. 사용자 → Keycloak: 로그인
3. Keycloak → SPA: 인증 코드
4. SPA → Keycloak: 토큰 교환 (PKCE verifier 사용)
5. SPA: 토큰을 브라우저에 저장
6. API 호출 시 Bearer 토큰 사용

토큰을 브라우저에서 직접 관리하게 되며, 이 아키텍쳐에서는 아래와 같은 보안 설정이 필요하다.

  • Access Type: public을 사용한다.
    • Confidential Client를 사용하려면 Client Secret이 필요한데, SPA에 포함하면 누구나 볼수있게 된다.
      다시 정리하자면, SPA는 브라우저에서 실행되는 JavaScript 코드이므로, 소스 코드가 모두 클라이언트에 노출되기때문에
      Client Secret 사용하지 않는다.
  • PKCE (Proof Key for Code Exchange)를 활성화한다.
    • 클라이언트 시크릿을 사용할 수 없기 때문에 PKCE로 반드시 보안을 강화해야한다.
  • 토큰 저장 및 관리에 더 신경써야한다.
    • 브라우저 탭 종료시 자동으로 삭제될 수 있도록 메모리 저장 권장 (localStorage/sessionStorage 지양)
    • 자동 갱신을 위한 Refresh Token 관리 전략 필요 (RefreshToken 재사용 금지)
    • 토큰 만료 시간 적절히 설정

 

5️⃣ SPA with intermediary API 보안설정

이 아키텍쳐는 SPA와 동일한 도메인에서 중개(intermediary)서버를 가진다. 
BFF (Backend For Frontend) 패턴이라고도 하는데, API Gateway와 유사하지만 아래와 같은 특징이 있다.

  • 프록시역할 : 인증/인가 처리, 토큰관리, API요청 중계
  • 보안강화: 민감한 정보(토큰 등) 서버 측 관리, 동일한 도메인으로 CORS 이슈 해결, 세션 기반 인증 가능
  • 최적화: 프론트엔드에 대한 최적화된 API제공, 데이터 집계 및 변환, 네트워크 요청 최소화
  • 세션 관리: 서버 측에서 중앙화된 세션 관리 가능
  • 토큰 갱신: Refresh Token을 서버에서 안전하게 관리하고 자동 갱신

프론트엔드는 오직 BFF서버와 만 통신하며, BFF에서 토큰을 관리하고 백엔드 API 호출시 사용한다.
즉, 이 아키텍쳐는 프론트엔드/ 백엔드/ Keycloak 사이에 중개자를 둔 아키텍쳐라고 할 수 있다.

# 아키텍쳐
[브라우저]
    |─ SPA (프론트엔드)
    |  ↕ (httpOnly 세션 쿠키)
    |  ↓
[BFF 서버] ←→ [백엔드 API] ←→ [리소스/DB]
    ↕
[Keycloak]

# 인증 플로우
1. SPA → BFF: 로그인 요청
2. BFF → Keycloak: Authorization Code 요청
3. Keycloak → BFF: 토큰 발급
4. BFF: 토큰 서버에 안전하게 저장
5. BFF → SPA: httpOnly 세션 쿠키 발급
6. 이후 모든 API 요청은 세션 쿠키로 처리
7. 토큰 만료시 BFF가 자동으로 갱신
8. 세션 만료 정책 적용

Keycloak과 백엔드API 호출을 클라이언트(브라우저)에서 하는것이 아니라 중개 서버가 한다.
따라서, Keycloak의 Client Authentication: confidential를 사용할 수 있어 토큰이 유출될 위험이 줄어든다.

아래와 같은 보안 설정을 한다.

  • Public Client가 아닌 Confidential Client로 설정한다.
    • 서버사이드 웹 애플리케이션의 경우 Client Secret은 서버에서만 안전하게 보관하고 사용한다.
      (서버에서 안전하기 보관되기때문)
    • Confidential Client를 사용하면 유출된 인가코드를 악용할 수 없다.
  • PKCE (Proof Key for Code Exchange) 활성화를 권장한다.
    • 인증 코드 인터셉트 공격 방지할 수 있다.
    • Authorization Code Flow와 함께 사용하는것을 권장한다.
  • 세션 쿠키 설정
    • httpOnly: true (필수)
    • secure: true (HTTPS 필수)
    • sameSite: strict

여기서 Session Cookie에 httpOnly 플래그가 필수인 이유는 보안, 특히 XSS(Cross-Site Scripting) 공격으로부터 보호하기 위해서라고 하는데, 이부분은 이해하지 못했다.. 

 

6️⃣ SPA with external API 보안설정

이 아키텍처는 브라우저에서 렌더링 된 클라이언트(브라우저)에서 외부 도메인의 API를 직접 호출한다.
API Gateway나 다른 도메인의 서비스를 호출하는 경우에 해당한다.

# 아키텍쳐
[브라우저]
    |
    |── SPA (프론트엔드)
    |      ↕ (로컬 저장소/메모리)
    |   [Keycloak]
    |      ↓ (액세스 토큰)
    |      ↓
    ↓      ↓
[외부 API] (다른 도메인)
    ↓
[리소스]

# 인증 플로우
1. SPA → Keycloak: Authorization Code 요청 (PKCE 사용)
2. 사용자 → Keycloak: 로그인
3. Keycloak → SPA: 인증 코드
4. SPA → Keycloak: 토큰 교환 (PKCE verifier 사용)
5. SPA: 토큰을 브라우저에 저장
6. CORS를 통한 외부 API 호출 (Bearer 토큰)

이 아키텍쳐는 Keycloak을 직접 호출하며 아래와 같은 특징을 가진다.

  • CORS 설정 필수
  • 토큰 노출 위험 있음
  • 다중 도메인 요청 처리

아래와 같은 보안설정을 해야한다.

  • Access Type: public을 사용한다.
    • Confidential Client를 사용하려면 Client Secret이 필요한데, SPA에 포함하면 누구나 볼수있게 된다.
      다시 정리하자면, SPA는 브라우저에서 실행되는 JavaScript 코드이므로, 소스 코드가 모두 클라이언트에 노출되기때문에
      Client Secret 사용하지 않는다.
  • PKCE (Proof Key for Code Exchange)를 활성화한다.
    • 클라이언트 시크릿을 사용할 수 없기 때문에 PKCE로 반드시 보안을 강화해야한다.
  • 토큰 저장 및 관리에 더 신경써야한다.
    • 브라우저 탭 종료시 자동으로 삭제될 수 있도록 메모리 저장 권장 (localStorage/sessionStorage 지양)
    • 자동 갱신을 위한 Refresh Token 관리 전략 필요 (RefreshToken 재사용 금지)
    • 토큰 만료 시간 적절히 설정
  • 추가로 고려해야할 부분은 아래와 같다.
       - CSP(Content Security Policy) 설정
       - Rate Limiting 대비
       - 에러 처리 시 민감 정보 노출 주의

 


Native App (Desktop,Mobild App) 보호 

 

Desktop(CLI)/모바일 애플리케이션 보호도 기본적으로는 웹 어플리케이션하고 비슷하다.

인가코드흐름(Authorization Code Flow)를 사용해야하며,
PKCE(Proof key for Code Exchange)를 함께 사용하는것이 좋다.

마찬가지로 Keycloak 로그인 페이지로 Redirect하여 사용하는것이 좋고, 로그인 페이지를 별도로 구축해서 사용하지 않는것이 좋다.

인증을 위해 웹 브라우저를 열어 사용자에게 인증을 요청하고, 인증 코드나 토큰을 받아오는 방식이 안전하며,
OAuth 2.0에서는 이를 "Device Flow" 또는 "Authorization Code Flow with PKCE"로 구현할 수 있다.

 

1️⃣  세 가지 인증 유형

네이티브 애플리케이션에서 인증을 처리할 때, 애플리케이션 유형에 따라 아래 세가지 유형을 사용할 수 있다.

  임베디드 웹 뷰 (사용X) 사용자의 기본 브라우저
(외부 사용자 에이전트)
안드로이드 및 iOS의 인앱 브라우저 탭 사용
설명 애플리케이션 내에서 웹 콘텐츠를 표시하기 위해 임베디드 웹 뷰를 사용한다.
사용자는 앱을 떠나지 않고 인증 과정을 완료할 수 있다.
사용자의 기본 웹 브라우저를 열어 인증을 처리한다.
사용자는 브라우저에서 인증을 완료한 후 앱으로 돌아온다.
안드로이드의 Chrome Custom Tabs나 iOS의 Safari View Controller를 사용하여 앱 내에서 브라우저 탭을 열어 인증을 진행한다.
장점 사용자 경험이 매끄럽고, 앱 내에서 모든 작업이 이루어진다. 브라우저는 앱과 분리되어 있어 민감한 정보가 앱에 노출되지 않는다. (보안강화) 사용자는 앱을 떠나지 않지만, 브라우저의 보안 이점을 활용할 수 있어,
보안과 사용자 경험의 균형을 제공한다. 
단점 사용자가 입력한 민감한 정보가 앱에 노출될 수 있어 OAuth 2.0에서는 권장되지 않는다. (보안 문제) 사용자가 앱을 떠나 브라우저로 이동해야 하기 때문에, 사용자 경험이 다소 끊길 수 있다.  플랫폼에 따라 구현이 다를 수 있고, 모든 플랫폼에서 지원되지 않을 수 있다.

 

2️⃣ 인증흐름 & 리디렉트 URI 옵션

Native App (Desktop,Mobild App)은 아래와 같은 인증 흐름을 가진다.

애플리케이션                     브라우저                   Keycloak
   |                            |                          |
   |----(1) 로그인 -------------->|------------------------->|
   |                            |                          |
   |                            |<---(2) 사용자 인증----------|
   |                            |                          |
   |<---(3) 인가 코드 전달---------|--------------------------|
   |                            |                          |
   |----(4) 토큰 획득--------------------------------------->|
   
# 1. 로그인 요청: 애플리케이션이 브라우저를 통해 Keycloak에 로그인 요청을 보냄
# 2. 사용자 인증: 사용자가 브라우저에서 인증을 완료함
# 3. 인가 코드 전달: 브라우저가 애플리케이션으로 인가 코드를 전달함
# 4. 토큰 획득: 애플리케이션이 인가 코드를 토큰으로 교환함

이때, 네이티브 앱이 브라우저로부터 인증 응답을 받을 때(3번단계) 사용할 수 있는 여러 가지 리디렉트 URI 옵션이 존재한다.
(참고: OAuth 2.0 for Native Apps)

  1. Claimed HTTPS scheme:
    "https" 스킴 URI 리디렉션은 일반적으로 웹 애플리케이션에서 사용하는 기본 리디렉션 방식이며, 네이티브 앱에서도 사용할 수 있다. 앱이 특정 도메인의 "https" URI를 처리하도록 허용하면 브라우저가 해당 URI를 만나면 앱이 실행되며, 브라우저가 아닌 네이티브 앱에서 콜백이 실행된다.
    (예, https://app.example.com/oauth2redirect/example-provider)
  2. Custom URI scheme(Private-Use URI Scheme):
    사용자 지정 URI 구조를 애플리케이션에 등록하고, Keycloak이 사용자 지정 URI로 리다이렉트 하면 애플리케이션에 요청이 전송되는 방식이다.
    사용자 지정 URI 구조는, 소유한 도메인의 역순과 일치해야 한다. (예, "com.example.app://oauth2/providername"
  3. Loopback interface:
    네이티브 앱이 운영되는 컴퓨터의 애플리케이션의 루프백(lookback) 네트워크 인터페이스에 포트를 열고,
    이 포트를 통해 인증 응답을 받는다.
    (IPv4 예, http://127.0.0.1:{port}/{path})
  4. A special redirect URI ( = Out of Band (OOB) 방식/참고링크):
    이건 지정되지 않은 방법을 통해 들어오는 OAuth 응답을 지원하기 위한 방식이다.
    리디렉션하여 자동으로 인가 코드를 전달 하는것이 아니라, 네티이브앱에 수동으로 입력해야하는 코드가 사용자에게 표시된다.
    사용자가 브라우저에서 인증을 완료한 후, 인증 코드를 직접 애플리케이션에 입력하는 방식이며, 주로 브라우저를 사용할 수 없는 환경이나, 리디렉트 URI를 등록할 수 없는 경우에 사용한다.
    (예, "인증 코드: 123456")
// 예시

// 1. HTTPS 스킴을 사용한 리디렉트 URI
const redirectUri = 'https://app.example.com/oauth2redirect';
open(`https://auth.example.com/authorize?client_id=your_client_id&redirect_uri=${encodeURIComponent(redirectUri)}&response_type=code`);

// 2. 사용자 지정 URI 스킴을 사용한 리디렉트 URI
const redirectUri = 'com.example.app:/oauth2redirect';
open(`https://auth.example.com/authorize?client_id=your_client_id&redirect_uri=${encodeURIComponent(redirectUri)}&response_type=code`);

// 3. 루프백 인터페이스를 사용한 리디렉트 URI
const port = 8000; // 또는 임의의 포트 오픈
const redirectUri = `http://127.0.0.1:${port}/oauth2redirect`;

const express = require('express');
const app = express();

app.get('/oauth2redirect', (req, res) => {
    const code = req.query.code;
    console.log('Authorization Code:', code);
    res.send('Authorization complete. You can close this window.');
});

app.listen(port, () => {
    console.log(`Listening on port ${port}`);
    open(`https://auth.example.com/authorize?client_id=your_client_id&redirect_uri=${encodeURIComponent(redirectUri)}&response_type=code`);
});

// 4. 특별 리디렉트(OOB) 방식
const redirectUri = 'urn:ietf:wg:oauth:2.0:oob';
open(`https://auth.example.com/authorize?client_id=your_client_id&redirect_uri=${encodeURIComponent(redirectUri)}&response_type=code`);
   
console.log('Please enter the authorization code:'); // 사용자가 브라우저에서 인증 코드를 수동으로 입력
process.stdin.on('data', (data) => {
    const code = data.toString().trim();
    console.log('Authorization Code:', code); // 여기서 토큰 요청 진행 
});

 

3️⃣  CLI로 인증 받기 테스트

* 테스트 소스코드: https://github.com/PacktPublishing/Keycloak---Identity-and-Access-Management-for-Modern-Applications-2nd-Edition

실습을 위해 위 테스트 코드를 다운받고 아래와 같이 순서대로 준비한다.

# Keycloak 준비
docker run -p 8080:8080 \
          -e KEYCLOAK_ADMIN=admin \
          -e KEYCLOAK_ADMIN_PASSWORD=admin \
          quay.io/keycloak/keycloak \
          start-dev
          
# Backend 어플리케이션 준비
git clone https://github.com/PacktPublishing/Keycloak---Identity-and-Access-Management-for-Modern-Applications-2nd-Edition.git
cd Keycloak---Identity-and-Access-Management-for-Modern-Applications-2nd-Edition/ch6
npm install


이제 Keycloak Client를 생성 하고, 로그인할 수 있는 사용자(user)를 준비한다.

 

  • client id: cli
  • access type: public
  • vaild redirect URLs: http://localhost/callback/

 

 

 

 

 

 

 

이제 코드를 실행해보자.

node app.js

앱을 실행하면 브라우저에서 Keyclock 로그인 페이지가 리디렉션 되며, 사용자로 인증 시 결과를 확인할 수 있다.

 

 


RestAPI 및 Service 보호 

 

1️⃣ 개요

애플리케이션이 Keycloak으로 보호되는 RestAPI를 호출하려는 경우, 먼저 Keycloak에서 접근 토큰을 얻은 다음 RestAPI로 보내는 요청에 접근 토큰을 아래와 같은 형식으로 포함해야 한다.

fetch('https://api.example.com/data', {
    headers: {
        'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIs...'
    }
});

 

접근 토큰을 얻는 방식은 이 전 포스팅 주요 권한 부여 유형에서 다루었다.
승인코드 유형 (Authorization Code Grant)은 로그인 페이지로 리디렉션 되어 사용자의 ID/PW를 이용하여 접근토큰을 얻는다.
이 경우, API 사이의 통신(예,MSA구조에서)인 경우에는 접근 토큰을 얻기 어렵다.

이때 사용할 수 있는 권한부여 유형이 앱 인증 유형(Client Credentials Grant) 이다. (참고자료: Client Credentials Grant)

+-------+                                 +------+
| API 1 |---[Client Credentials Grant]--->| API2 |
|       |                                 +------+
|       |                                 +------+
|       |---[Client Credentials Grant]--->| API3 |
+-------+                                 +------+

이 부분도 이 전 포스팅 AccessToken 검증하기에서 잠깐 다루었는데 여기에서 다시한번 설명한다.

 

2️⃣ 앱 인증 유형(Client Credentials Grant) 테스트

먼저 Client가 필수로 Confidential로 설정되어있어야 한다.

  • client id: client-credentials
  • access type: Confidential
  • Service accounts roles: ON

Client (client-credentials) Setting탭에서 Client authentication을 On으로 변경한다.
Service accounts roles도 Enable 한다.
Save하면 Credentials 탭이 생긴다. 

Credentials 탭에서 Client Secret 값을 복사한다.


Access Token을 curl로 받아오자! 
아래 IrefKp5o3IJxKCBQXCsRYmLyWups8uVA 부분은 위에서 복사한 Client Secret값으로 바꿔야한다.

# Client Secret값 변수로 저장
export KEYCLOAK_CLIENT_SECRET=IrefKp5o3IJxKCBQXCsRYmLyWups8uVA # 위에서 복사한 값으로 변경

# Access Token 요청
export KEYCLOAK_ACCESS_TOKEN=$(curl -X POST \
  'http://localhost:8080/realms/myrealm/protocol/openid-connect/token' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d "client_id=client-credentials" \
  -d "client_secret=${KEYCLOAK_CLIENT_SECRET}" \
  -d 'grant_type=client_credentials' | jq -r '.access_token')

엔드포인트로 요청을 보내보자.

# Base64 인코딩된 Client Secret 저장
export KEYCLOAK_CLIENT_SECRET_ENCODING=$(echo -n "client-credentials:${KEYCLOAK_CLIENT_SECRET}" | base64)

# 값 모두 들어있는지 점검
echo "Client Secret: $KEYCLOAK_CLIENT_SECRET"
echo "Access Token: $KEYCLOAK_ACCESS_TOKEN"
echo "Encoded Client Secret: $KEYCLOAK_CLIENT_SECRET_ENCODING"

# Access Token 검증
curl -X POST \
  'http://localhost:8080/realms/myrealm/protocol/openid-connect/token/introspect' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H "Authorization: Basic $KEYCLOAK_CLIENT_SECRET_ENCODING" \
  -d "token=$KEYCLOAK_ACCESS_TOKEN" | jq '.'

 

 

 

728x90