🌱 Infra/KeyCloak

[keycloak 맛보기 #3] 접근권한인가 이해하기

mini_world 2024. 12. 1. 20:36

 


참고자료

* 책: https://www.yes24.com/Product/Goods/122459785

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

 


실습 준비) Keycloak & 테스트 애플리케이션 세팅

 

Keycloak 준비

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/ch5/backend
npm install
npm start

# Frontend 어플리케이션 실행
cd Keycloak---Identity-and-Access-Management-for-Modern-Applications-2nd-Edition/ch5/frontend
npm install
npm start

# 테스트 어플리케이션 접속
http://localhost:8000

 

Keycloak Client 준비

  • client id: oauth-playground
  • access type: public
  • vaild redirect URLs: http://localhost:8000/
  • web origin: http://localhost:8000

이때 Keyclock client에서 access type을 직접 변경할 수 있는 부분을 찾을 수 없을텐데, 
아래 캡쳐처럼 Client authentication가 OFF 되어있으면 된다. 기본값이 OFF이므로 설정을 바꿀필요 없다.

 

Keycloak Users 준비

Clients 뿐만 아니라 접속할 수 있는 User를 생성해둔다.
테스트 유저는 임의 ID로 생성한 후 (여기에서는 user01로 생성했다), Credentials탭에서 비밀번호를 설정한다.

이후 Realm roles에서 myrole을 생성한다. 

myrole 이라는 이름으로 role을 생성했다면, 위에서 생성한 user01에 다시 접속하여 Role Mapping에서 myrole을 추가한다.

이 작업을 하는 이유는 ch5/backend/app.js 코드에서 keycloak.protect('realm:myrole')로 엔드포인트를 보호하고 있기 때문이다.
사용자가 myrole에 매핑되어있지 않다면 Invoke service 단계에서 테스트에 실패한다.

 

 


실습하기전에) Access Token의 접근권한 제한에 대해 이해하기

AccessToken은 리소스서버(실습에서는 Backend)에 접근하는데 사용하는 Token이다.
이 토큰으로 리소스에 접근할 수 있기 때문에 접근권한을 제어하는것이 매우 중요하다.

애플리케이션의 보안을 강화하고, 사용자가 접근할 수 있는 리소스를 세밀하게 제어하기 위해 AccessToken의 접근 권한 제어 메커니즘에 대해 확인하고 다음으로 넘어가자!

Keycloak Authorization Service Guide

 

접근제한 메커니즘 설명
Attribute-based access control
(ABAC)
사용자, 리소스, 환경의 속성을 기반으로 접근을 제어
예: 사용자의 부서, 직급, 위치 등의 속성을 기반으로 접근 권한 허용
Role-based access control
(RBAC)
사용자에게 할당된 역할을 기반으로 접근을 제어
예: Realm Role에 매핑된 사용자만 접근 권한 허용
User-based access control
(UBAC)
특정 사용자를 기반으로 접근을 제어 (개별 사용자 단위의 세밀한 권한 제어 가능)
예, user01에게만 접근 권한 허용
Context-based access control
(CBAC)
요청의 컨텍스트(시간, 위치, 디바이스 등)를 기반으로 접근을 제어
예: 특정 IP 범위에서만 접근 허용
Rule-based access control: JavaScript를 사용한 커스텀 규칙 정의 (복잡한 비즈니스 로직을 구현할 수 있음)
Time-based access control: 시간 기반의 접근 제어 (특정 시간대나 기간 동안만 접근 허용)
Custom ACMs through SPI: Service Provider Interface를 통한 커스텀 접근 제어 메커니즘 구현 가능
(필요한 경우 자체 정책 타입을 개발하여 확장 가능)

이런 접근 권한 메커니즘을 구현하기 위해 반드시 이해하고 있어야할 Keycloak 개념이 있다.
아래 실습에서도 계속해서 볼 예정이다.

  • Role:
    • Role은 시스템 내에서 수행할 수 있는 작업을 정의한다
    • RBAC 구현에 사용된다.
  • Scpoe:
    • 리소스에 대해 수행할 수 있는 작업이나 권한의 범위를 정의한다.
    • 예를 들어, read, write, delete 등의 작업을 Scope로 정의할 수 있다.
  • Audience (aud):
    • JWT 토큰의 aud 클레임을 말한다.
    • 토큰이 사용될 . 수있는 대상 리소스 서버 혹은 클라이언트를 지정한다.
    • 특정 리소스 서버만 해당 토큰을 사용할 수 있도록 정의할 수 있다

 

 


실습 #1) 백엔드 리소스에 접근하기 (Role 활용 확인하기)

실습하기

http://localhost:8000 에 접속하고, 2 - Authorization를 클릭한다.
Send Authorization Request를 클릭하면 Access Token 받게 된다. 페이지에서 세부 내용을 확인할 수 있다.

3 - Invoke Service 로 들어가서 Invvoke를 클릭하면 Response값으로 Secret message!를 볼 수 있다.

이해하기

이번 실습에서는 Frontend에서 Backend서버에 AccessToken을 통해 접근하는 부분을 실습한것이다.
다이어그램으로 표기하자면 아래와 같다.

  • Access Token 검증 (6-7단계)
  • Role 확인 (8단계)
  • 권한이 확인된 경우에만 Secret Message! 반환 (9단계)
[클라이언트(frontend)]       [Keycloak]           [리소스 서버(backend)]
     │                        │                        │
     │   1. 인증 요청           │                        │
     │───────────────────────>│                        │
     │                        │                        │
     │   2. Authorization Code│                        │
     │<───────────────────────│                        │
     │                        │                        │
     │   3. Token 교환         │                        │
     │───────────────────────>│                        │
     │                        │                        │
     │   4. Access Token      │                        │
     │<───────────────────────│                        │
     │                        │                        │
     │           5. Access Token으로 리소스 요청           │
     │────────────────────────────────────────────────>│
     │                        │                        │
     │                        │    6. Token 검증 요청    │
     │                        │<───────────────────────│
     │                        │                        │
     │                        │    7. Token 유효성 응답   │
     │                        │───────────────────────>│
     │                        │                        │
     │                        │   8. realm:myrole      │
     │                        │        권한 확인         │
     │                        │      <───────┐         │
     │                        │              │         │
     │             9. Secret Message! 응답              │
     │<────────────────────────────────────────────────│

 

 


실습 #2) 접근권한 부여 동의(Concent) 요청하기 (Scope 활용 확인하기)

 

실습하기

http://localhost:8080 Keycloak 에 접속하고, Clients -> oauth-playground 에서 아래 설정을 변경한다.

  • Consent required: On
  • Display client on screen: On
  • Consent screen text: 권한(Concent) 부여 동의 요청

이제 다시 http://localhost:8000/로 접근하고 2-Authorization에서 다시한번 Send Authorization Request를 클릭한다.
이미 로그인한 세션이 있는 경우 Grant Access 팝업이 나오고, 로그인세션이 없는경우에는 다시한번 로그인 하도록 한다.

이제 이 사용자에 Consents를 확인해보자.
http://localhost:8080 Keycloak 에 접속하고, Users -> user01 -> Consents탭을 확인해보자.
이 사용자에게 부여된 권한을 확인할 수 있다.

이번에는 새로운 Client Scope를 생성하고 사용자에게 추가해보자.
Client Scopes에서 새로운 Client Scope를 생성한다.

  • Name: (아무거나) my-custom-scope
  • Display on consent screen: On

이제 Clients -> oauth-playground -> Client Scope탭으로 이동하고, 위에서 생성한 my-custom-scope를 추가한다.

이제 다시 http://localhost:8000/로 접근하고 다시한번 Send Authorization Request를 클릭한다.
이때 위에서 동의요청 페이지에서 추가한 새로운 Scope를 확인할 수 있다.

사용자에게 어떤 Scope가 허용되었는지는 Users -> 사용자 -> Consents 탭에서 확인할 수 있다.

Scope는 Keycloak User의 Consents 탭에서 제거할수도 있다.
제거한 경우 사용자 동의를 다시 받아야 한다.

 

이해하기

Scope (권한 범위)는 클라이언트가 요청할 수 있는 권한의 범위를 정의한다.

  • openid: OIDC 인증 요청
  • profile: 사용자 프로필 정보
  • email: 이메일 정보
  • address: 주소 정보
  • phone: 전화번호 정보

Consent (사용자 동의)는 사용자에게 클라이언트의 스코프 요청에 대한 동의를 받는 과정을 말하며, 
사용자가 명시적으로 권한 부여를 승인하는것이다.

[Client(frontend)]     [Auth Server(Keycloak)]  [Resource Server(backend)]
   │                         │                           │
   │                         │                           │
   │───── 1. Scope 요청 ─────>│                           │
   │                         │                           │
   │<─── 2. Consent Screen ──│                           │
   │                         │                           │
   │───── 3. 사용자 동의 ──────>│                           │
   │                         │                           │
   │<─── 4. Auth Code ───────│                           │
   │                         │                           │
   │───── 5. Code 교환 ──────>│                           │
   │                         │                           │
   │<─── 6. Access Token ────│                           │
   │                         │                           │
   │────────────── 7. Access Token으로 요청 ──────────────>│
   │                         │                           │
   │<──────────────── 8. Protected Resource ─────────────│

Scope를 Sample어플리케이션에서는 아래와 같이 수정하여 활용할 수 있다. (샘플코드에서는 구현되어있지 않다)

# AS-IS
app.get('/secured', keycloak.protect('realm:myrole'), function (req, res) {
  res.setHeader('content-type', 'text/plain');
  res.send('Secret message!');
});

# TO-BE
# 단일 스코프 확인
app.get('/secured', keycloak.protect('scope:my-custom-scope'), function (req, res) {
  res.send('Secret message!');
});
# 여러 스코프 확인
app.get('/secured', keycloak.protect(['scope:my-custom-scope', 'scope:another-scope']), function (req, res) {
  res.send('Secret message!');
});

 

 


실습 #3) Audience로 접근권한 제한 하기 (Audience 활용 확인하기)

 

실습하기

ch5/backend/keycloak.json 파일을 수정한다.

{
  "realm": "myrealm",
  "bearer-only": true,
  "auth-server-url": "${env.KC_URL:http://localhost:8080}",
  "resource": "oauth-playground",  // 위에서 생성한 Client이름으로 수정
  "verify-token-audience": true    // true로 수정
}
  • realm: Keycloak에서 인증을 관리하는 논리적 단위
  • bearer-only: 클라이언트가 사용자 인터페이스 없이 백엔드 서비스로만 사용될 때 설정
                           true로 설정하면 Keycloak이 이 클라이언트에 대해 로그인 페이지를 제공하지 않음
  • auth-server-url: Keycloak 인증 서버의 URL
  • resource: 클라이언트 ID, Keycloak에서 클라이언트를 식별하는 데 사용함
  • verify-token-audience: 토큰의 aud(Audience) 클레임을 검증할지 여부 설정
                                               true로 설정하면 토큰이 올바른 대상 클라이언트를 위해 발급되었는지 확인함

 

이제 http://localhost:8000/ 에 접근하여 Send Authorization Request를 클릭하여 Access Token을 발급받고
3-Invoke Service에서 Invoke를 클릭해보자.

이때 Access Deny가 보인다.

"resource": "oauth-playground"는 클라이언트 ID를 의미하고, "verify-token-audience": true로 설정되어 있으므로
"aud" 값에 ClientID가 포함되어야 하는데 account만 있어서 Access Deny가 나왔다.

 

이제 aud값에 ClientID가 출력되도록 수정해보자

먼저, Client(http://localhost:8080/admin/master/console/#/myrealm/clients/) 에서 oauth-playground을 클릭한다.
Clients scope 탭에서 oauth-playground-dedicated를 클릭한다. (클라이언트별로 고유한 권한이나 속성을 정의할 때 사용)

Mapper 탭에서 Configure a new mapper를 클릭하고, Audience를 선택한다.

client id와 같은 이름(oauth-playground)의 Audiance type의 매퍼를 생성한다. 

 

이제 다시한번  http://localhost:8000/ 에 접근하여 Send Authorization Request를 클릭하여 Access Token을 발급받고
3-Invoke Service에서 Invoke를 클릭해보자.

이제 aud 클레임에 ClientID와 같은 값이 들어있어 Access 가 허용 되었다.

 

 

Audience 이해하기

verify-token-audience 값을 False 에서 True로 수정하면, Audience 검증 활성화된다.
Audience 검증은 잘못된 대상 클라이언트에서 토큰을 사용하는 것을 방지한다. 토큰이 의도된 리소스 서버에서만 사용되도록 보장한다.

  • 변경 전 (false): Audience 검증 비활성화
    • 토큰의 aud(Audience) 클레임을 검증하지 않는다.
    • 토큰이 특정 클라이언트를 대상으로 발급되었는지 확인하지 않기 때문에 보안에 취약하다.
  • 변경 후 (true): Audience 검증 활성화
    • 토큰의 aud 클레임을 검증한다.
    • 토큰이 올바른 대상 클라이언트를 위해 발급되었는지 확인한다.
    • 클라이언트가 자신에게 발급된 토큰만 수락하게 되어 보안이 강화된다.

 

 


실습 #4) Role로 접근권한 제한 하기 (Role 활용 확인하기)

 

Client의 Full scope allowed 이해하기

Full scope allowed 설정은 클라이언트 스코프의 권한 범위를 제어하는 중요한 옵션이다.
Full scope allowed가 기본적으로 ON으로 되어있는데, 이유는 초기 설정 시 클라이언트가 모든 역할에 접근할 수 있도록 하여 설정의 편의성을 제공하기 위함이다. 
프로덕션 환경에서는 보안을 위해 필요한 역할만 명시적으로 매핑하여 사용하도록 한다.

  • Full scope allowed가 ON인 경우:
    • 클라이언트는 모든 가능한 역할(Realm 역할과 다른 클라이언트의 역할 포함)에 접근할 수 있다.
    • 별도의 역할 스코프 매핑 없이도 모든 역할에 대한 접근이 가능하다.
    • 보안상 주의가 필요한 설정이며, 프로덕션 환경에서는 사용하지 않도록 주의해야한다.
  • Full scope allowed가 OFF인 경우:
    • 클라이언트는 명시적으로 매핑된 역할에만 접근할 수 있다.
    • 스코프 매핑을 통해 특정 역할에 대한 접근을 개별적으로 설정해야 한다.
# Full scope allowed: ON
{
  "realm_access": {
    "roles": ["role1", "role2", "role3"] #realm내의 모든 역할 접근 가능
  }
}

# Full scope allowed: OFF
{
  "realm_access": {
    "roles": ["role1"] # client에 명시적으로 매핑된 역할만 접근 가능
  }
}

 

실습하기

먼저, 위에서 설명한데로 Full scope allowed 를 OFF로 변경한다. (위 스크린샷 참고)
ON에서 OFF로 변경하면 아래처럼 AccessToken이 변경된다.

실습준비 단계에서 언급한데로,
ch5/backend/app.js 코드에서는 keycloak.protect('realm:myrole')로 엔드포인트를 보호하고 있다.

app.get('/secured', keycloak.protect('realm:myrole'), function (req, res) {
  res.setHeader('content-type', 'text/plain');
  res.send('Secret message!');
});

myrole에 매핑되어있지 않다면 Invoke service 단계에서 테스트에 실패한다.

 

이제 myrole을 명시적으로 Client에 연결해보자.

 

Client에 realm_access Role 매핑방법 1) {client id}-dedicated(전용스코프)를 사용하여 Role 매핑

oauth-playground에서 Client scope -> {client id}-dedicated -> Scope -> Assign role -> myrole -> Assign으로 myrole을 매핑한다.

이제 http://localhost:8000/에서 Access Token을 확인해보자. myrole이 포함되어있고 Invoke도 성공했다.

 

설명 클라이언트에 자동으로 생성된 전용 스코프({client id}-dedicated)를 사용하여 역할을 매핑한다.
이 방법은 특정 클라이언트에만 적용되는 전용 설정을 사용한다.
장점 클라이언트별로 고유한 설정을 유지할 수 있다.
단점 전용 스코프에 의존하므로, 다른 클라이언트에 동일한 설정을 적용하기 어렵다.

 

 

Client에 realm_access Role 매핑방법 2) Client Scope를 사용하여 Client에 Role 매핑

Client Scope에서 새로운 ClientScope를 생성하고, Scope탭에서 myrole을 연결한다.

이제 Client (oauth-playground)에 위에서 생성한 Client Scope를 추가한다.

그럼 이제 다시한번 실행해보자.
마찬가지로 realm_access.role에 myrole이 추가되어있고 Invoke가 성공했다.

 

설명 새로운 Client Scope를 생성하고, 해당 스코프에 역할을 매핑한 후, 클라이언트에 이 스코프를 추가한다.
장점 여러 클라이언트에서 동일한 설정을 쉽게 재사용할 수 있다.
스코프를 통해 역할과 권한을 중앙에서 관리할 수 있다.
단점 적용한 클라이언트에 동일한 스코프가 적용되므로, 개별 클라이언트에 대한 세밀한 제어가 어려울 수 있다.

 

실습 #5) Scope 활용하기 (Scope 명명규칙/ Default&Optional)

 

Scope 명명규칙

Scope의 명명규칙은 정해진 표준이 없다. 리소스와 작업을 명확히 구분할 수 있게 규칙을 정하는것이 권한관리에 용이다.
예를들어 resource:action 형식으로 지정할 수 있다. (AWS IAM Policy를 참고할 수 있음)

  •    기본적인 CRUD 작업
    • users:read
    • users:write
    • users:delete
    • users:update
  • 세부적인 권한구분
    • users:profile:read
    • users:settings:write
  • 특정 리소스의 모든 권한: resource:*
  • 모든 리소스의 읽기 권한: *:read
  • 모든 리소스의 모든 권한: *:*

 

Scope 유형 (Default/ Optional)

Keycloak의 Client Scope에는 Default와 Optional 두 가지 유형이 있다.

  • Default
    • 클라이언트가 명시적으로 요청하지 않아도 자동으로 포함되는 스코프
    • 모든 토큰 요청에 기본적으로 포함됨
    • 클라이언트가 scope 파라미터를 지정하지 않아도 자동 포함
    • 기본적인 사용자 정보나 권한에 사용
  • Optional
    • 클라이언트가 명시적으로 요청할 때만 포함되는 스코프
    • scope 파라미터에 포함시켜야 토큰에 포함됨
    • 라이언트가 필요할 때만 요
    • 가적인 권한이나 정보가 필요할 때 사용

 

실습하기

내 어플리케이션에 Read, Write권한이 있다고 가정하고, 모든 사용자에게는 Read를 필요한 사용자에게만 Write권한을 제공한다고 가정하자.

먼저 Role을 추가한다.

  • myapp:read  테스트 어플리케이션에 읽기만 가능한 Role이라고 가정
  • myapp:write  테스트 어플리케이션에 쓰기만 가능한 Role이라고 가정

방금 생성한 Role을 User에 매핑한다.
지금은 테스트 환경이니 유저에 Role을 매핑했지만, 프로덕션 환경에서는 Group을 만들어 해당 그룹에 Role을 매핑하는것이 좋다.

 

이제 Client Scope를 생성한다.

  • myapp:read  테스트 어플리케이션에 읽기만 가능한 권한범위라고 가정
  • myapp:write  테스트 어플리케이션에 쓰기만 가능한 권한범위라고 가정

이제 Client Scope에 각각 올바른 Role을 매핑한다.

  • myapp:read  테스트 어플리케이션에 읽기만 가능한 권한범위라고 가정
  • myapp:write  테스트 어플리케이션에 쓰기만 가능한 권한범위라고 가정

 

이제 Client(oauth-playground) -> Client Scope탭에서 위에서 생성한 두개 모두 추가한다.
이때, read는 Default로, write는 Optional로 설정한다.

이제 http://localhost:8000/에서 Send Authorization Request 생성시 새로운 권한 허용이 나오고, 
허용하면 realm_access에 새로운 myapp:read 역할이 추가된것을 볼 수있다.

이제 Write권한을 추가할 수 있도록 요청을 생성한다.
Scope에 myapp:write를 명시적으로 작성하고, Send Authorization Request를 실행한다.
realm_access에 새로운 myapp:write 역할이 추가된것을 확인한다.

\

 

추가설명) Role은 User(or Group) 그리고 Scope에 모두 할당되어있어야한다.

Role은 User와 Scope에 모두 할당되어있어야 정상적으로 동작한다.
User -> Role -> Scope -> Client 의 연결 고리가 모두 완성되어야 정상적으로 접근 제어가 가능하다.
프로덕션에서는 User대신 Group을 사용하자!

  • Client Scope에 Role 할당
    • 목적: 해당 스코프가 어떤 역할을 포함할 수 있는지 정의
    • 설정 위치: Client Scope > {scope-name} > Scope 탭
    • 의미: "이 스코프는 이러한 역할들을 포함할 수 있다"
  • User에 Role 할당
    • 목적: 사용자가 실제로 어떤 역할을 가질 수 있는지 정의
    • 설정 위치: Users > {user-name} > Role Mappings
    • 의미: "이 사용자는 이러한 역할들을 가진다"

 


실습 #6) Access Token 검증하기

 

이제 Introspect 엔드포인트를 이용해서 Access Token을 검증해본다.

# http://localhost:8080/realms/myrealm/.well-known/openid-configuration 에서 
# introspection_endpoint확인
"introspection_endpoint": "http://localhost:8080/realms/myrealm/protocol/openid-connect/token/introspect"

 

Introspection_endpoint 이해하기

Token Introspection 엔드포인트는 OAuth 2.0 토큰의 상태와 메타데이터를 확인하는 데 사용되는 표준 엔드포인트이다.
AccessToken의 유효성을 검증하고, 토큰의 현재상태(active/inactive) 확인을 해당 엔드포인트에서 진행한다.

# 요청예시
curl -X POST \
'http://localhost:8080/realms/myrealm/protocol/openid-connect/token/introspect' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'Authorization: Basic {여기에_Base64_인코딩된_값}' \
-d 'token={your_access_token}'

# 응답예시
{
 "active": true,                    // 토큰 유효성
 "exp": 1678901234,                // 만료 시간
 "sub": "user-id",                 // 사용자 ID
 "username": "user01",             // 사용자명
 "scope": "myapp:read myapp:write",// 스코프
 "client_id": "oauth-playground",  // 클라이언트 ID
 "token_type": "Bearer"            // 토큰 타입
}

 

실습하기

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

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

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

Access Token을 curl로 받아오자! (Credentials 설정으로 변경하면 http://localhost:8000/에서는 AccessToken발급 안됨)
아래 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=oauth-playground" \
  -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 "oauth-playground:${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