OAuth 2.0 토큰 인트로스펙션 인증
본문
Token Introspection
Traefik Hub 기능
이 미들웨어는 Traefik Hub에서만 사용할 수 있어요. Traefik Hub의 고급 기능에 대해 더 알아보세요.
OAuth 2.0 토큰 인트로스펙션(Token Introspection)은 Token Introspection 확장을 사용해 OAuth 2.0 서버에서 접근 토큰에 대한 메타데이터를 가져올 수 있게 해 줍니다.
이 메타데이터는 애플리케이션에 대한 접근을 제한하는 데 사용할 수 있어요. 자세한 내용은 RFC를 참고하세요.
구성 예시
Middleware OAuth Token Introspection
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-oauth-intro
spec:
plugin:
oAuthIntrospection:
tokenSource:
header: Authorization
headerAuthScheme: Bearer
clientConfig:
url: "https://YOUR-KEYCLOAK-ADDRESS/realms/YOUR-REALM/protocol/openid-connect/token/introspect"
headers:
Authorization: Basic ZXhhbX...cGxl # echo -n "$CLIENT_ID:$CLIENT_SECRET" | base64
tokenTypeHint: access_token
forwardHeaders:
Group: grp
Expires-At: exp
claims: Equals(`grp`, `admin`)
구성 옵션
| Field | Description | Default | Required |
| claims | 요청을 승인하기 위해 검증할 클레임을 정의해요. claims 옵션은 JWT 형식 토큰에서만 사용할 수 있어요. (자세한 내용은 여기) | "" | No |
| clientConfig.url | 인트로스펙션 엔드포인트 URL을 정의해요. 스킴과 경로를 포함해야 해요. | "" | Yes |
| clientConfig.headers | 모든 인트로스펙션 요청에 보낼 헤더를 정의해요. 값은 일반 문자열이거나 유효한 Go 템플릿일 수 있어요. 현재 템플릿에서는 인트로스펙션되는 요청에 해당하는 Request 유형 변수에 접근할 수 있습니다. | "" | No |
| clientConfig.tokenTypeHint | 인트로스펙션되는 토큰의 유형을 정의하며, 인트로스펙션 서버에 힌트로 보냅니다. 자세한 내용은 공식 문서를 참고하세요. | "" | No |
| clientConfig.tls.ca | 인증 서버와 TLS 연결을 맺는 데 사용하는 인증서 번들을 담은 PEM 인코딩 인증서 번들이나 비밀을 참조하는 URN (자세한 내용은 여기) | "" | No |
| clientConfig.tls.cert | 인증 서버와 TLS 연결을 맺는 데 사용하는 인증서를 담은 PEM 인코딩 인증서나 비밀을 참조하는 URN. (자세한 내용은 여기) | "" | No |
| clientConfig.tls.key | 인증 서버와 TLS 연결을 맺는 데 사용하는 키를 담은 PEM 인코딩 키나 비밀을 참조하는 URN. (자세한 내용은 여기) | "" | No |
| clientConfig.tls.insecureSkipVerify | 인증 서버와 통신할 때 TLS 인증서 검증을 끕니다. 테스트 목적으로는 유용하지만 프로덕션에는 강력히 권장되지 않아요. (자세한 내용은 여기) | false | No |
| clientConfig.timeoutSeconds | 인증 서버에 대한 요청을 포기하기 전의 시간을 정의해요. | 5 | No |
| clientConfig.maxRetries | 실패한 인증 서버 요청에 대한 재시도 횟수를 정의해요. | 3 | No |
| forwardAuthorization | 미들웨어가 요청을 승인한 뒤 authorization 헤더를 전달할지, 아니면 요청에서 제거할지 정의해요. | false | No |
| forwardHeaders | 요청에 추가할 HTTP 헤더를 정의하고, 인증 서버가 반환한 접근 토큰 클레임에서 추출한 값으로 채웁니다. JWT에서 찾지 못한 전달 대상 클레임은 빈 헤더가 돼요. forwardHeaders 옵션은 JWT 형식 토큰에서만 사용할 수 있어요. | [] | No |
| tokenSource.header | 클라이언트가 보낸 비밀을 담고 있는 헤더 이름을 정의해요. tokenSource 옵션 중 하나는 반드시 설정해야 해요. | "" | No |
| tokenSource.headerAuthScheme | 헤더 이름으로 Authorization을 사용할 때의 스킴을 정의해요. Authorization 헤더 문서를 확인하세요. tokenSource 옵션 중 하나는 반드시 설정해야 해요. | "" | No |
| tokenSource.query | 클라이언트가 보낸 비밀을 담고 있는 쿼리 파라미터 이름을 정의해요. tokenSource 옵션 중 하나는 반드시 설정해야 해요. | "" | No |
| tokenSource.cookie | 클라이언트가 보낸 비밀을 담고 있는 쿠키 이름을 정의해요. tokenSource 옵션 중 하나는 반드시 설정해야 해요. | "" | No |
| usernameClaim | 접근 로그의 clientusername을 채우는 데 평가할 클레임을 정의해요. usernameClaim 옵션은 JWT 형식 토큰에서만 사용할 수 있어요. | "" | No |
claims
문법
claims에서 지원하는 함수는 다음과 같아요:
| Function | Description | Example |
| Equals | key의 값이 value와 같은지 검증해요. | Equals(grp, admin) |
| Prefix | key의 값이 value를 접두사로 갖는지 검증해요. | Prefix(referrer, http://example.com) |
| Contains (string) | key의 값이 value를 포함하는지 검증해요. | Contains(referrer, /foo/) |
| Contains (array) | key 배열이 value를 포함하는지 검증해요. | Contains(areas, home) |
| SplitContains | key의 값을 구분자로 나눴을 때 value를 포함하는지 검증해요. | SplitContains(scope, , writer) |
| OneOf | key 배열이 values 중 하나를 포함하는지 검증해요. | OneOf(areas, office, lab) |
모든 함수는 불리언 연산자로 결합할 수 있어요. 지원되는 연산자는 다음과 같아요:
| Operand | Description | Example |
| && | 두 함수를 비교해서 둘 다 참일 때만 참을 반환해요. | Equals(grp, admin) && Equals(active, true) |
| || | 두 함수를 비교해서 둘 중 하나라도 참이면 참을 반환해요. | Equals(grp, admin) || Equals(active, true) |
| ! | 함수가 참이면 false를, 그 외에는 참을 반환해요. | !Equals(grp, testers) |
다음 데이터 구조에서는 모든 예시가 참을 반환해요:
JSON
{
"active": true,
"grp": "admin",
"scope": "reader writer deploy",
"referrer": "http://example.com/foo/bar",
"areas": [
"office",
"home"
]
}
중첩 클레임 (Nested Claims)
키 사이에 .를 사용해 중첩 클레임을 지원해요. 예를 들어:
Key
user.name
Claims
{
"active": true,
"grp": "admin",
"scope": "reader writer deploy",
"referrer": "http://example.com/foo/bar",
"areas": [
"office",
"home"
],
"user" {
"name": "John Snow",
"status": "undead"
}
}
Result
John Snow
.을 포함하는 키 처리
key에 점이 포함되어 있으면 \.로 이스케이프할 수 있어요.
\를 포함하는 키 처리
key에 \가 포함되어 있으면 \\로 두 번 적어야 합니다.
clientConfig
API 게이트웨이를 Identity Provider 같은 서드파티 소프트웨어에 연결하는 데 사용하는 구성을 정의해요.
clientConfig.tls
Kubernetes secret에 비밀 값 저장하기
tls.ca, tls.cert, tls.key를 구성할 때, Middleware와 같은 네임스페이스에 정의된 Kubernetes secret을 참조할 수 있어요. Kubernetes secret에 대한 참조는 URN 형식을 취합니다:
urn:k8s:secret:[name]:[valueKey]
Middleware JWT
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-oauth-intro
spec:
plugin:
oAuthIntrospection:
clientConfig:
tls:
ca: "urn:k8s:secret:tls:ca"
cert: "urn:k8s:secret:tls:cert"
key: "urn:k8s:secret:tls:key"
insecureSkipVerify: true
Kubernetes TLS Secret
apiVersion: v1
kind: Secret
metadata:
name: tls
stringData:
ca: |-
-----BEGIN CERTIFICATE-----
MIIB9TCCAWACAQAwgbgxGTAXBgNVBAoMEFF1b1ZhZGlzIExpbWl0ZWQxHDAaBgNV
BAsME0RvY3VtZW50IERlcGFydG1lbnQxOTA3BgNVBAMMMFdoeSBhcmUgeW91IGRl
Y29kaW5nIG1lPyAgVGhpcyBpcyBvbmx5IGEgdGVzdCEhITERMA8GA1UEBwwISGFt
aWx0b24xETAPBgNVBAgMCFBlbWJyb2tlMQswCQYDVQQGEwJCTTEPMA0GCSqGSIb3
DQEJARYAMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCJ9WRanG/fUvcfKiGl
EL4aRLjGt537mZ28UU9/3eiJeJznNSOuNLnF+hmabAu7H0LT4K7EdqfF+XUZW/2j
RKRYcvOUDGF9A7OjW7UfKk1In3+6QDCi7X34RE161jqoaJjrm/T18TOKcgkkhRzE
apQnIDm0Ea/HVzX/PiSOGuertwIDAQABMAsGCSqGSIb3DQEBBQOBgQBzMJdAV4QP
Awel8LzGx5uMOshezF/KfP67wJ93UW+N7zXY6AwPgoLj4Kjw+WtU684JL8Dtr9FX
ozakE+8p06BpxegR4BR3FMHf6p+0jQxUEAkAyb/mVgm66TyghDGC6/YkiKoZptXQ
98TwDIK/39WEB/V607As+KoYazQG8drorw==
-----END CERTIFICATE-----
cert: |-
-----BEGIN CERTIFICATE-----
MIIB9TCCAWACAQAwgbgxGTAXBgNVBAoMEFF1b1ZhZGlzIExpbWl0ZWQxHDAaBgNV
BAsME0RvY3VtZW50IERlcGFydG1lbnQxOTA3BgNVBAMMMFdoeSBhcmUgeW91IGRl
Y29kaW5nIG1lPyAgVGhpcyBpcyBvbmx5IGEgdGVzdCEhITERMA8GA1UEBwwISGFt
aWx0b24xETAPBgNVBAgMCFBlbWJyb2tlMQswCQYDVQQGEwJCTTEPMA0GCSqGSIb3
DQEJARYAMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCJ9WRanG/fUvcfKiGl
EL4aRLjGt537mZ28UU9/3eiJeJznNSOuNLnF+hmabAu7H0LT4K7EdqfF+XUZW/2j
RKRYcvOUDGF9A7OjW7UfKk1In3+6QDCi7X34RE161jqoaJjrm/T18TOKcgkkhRzE
apQnIDm0Ea/HVzX/PiSOGuertwIDAQABMAsGCSqGSIb3DQEBBQOBgQBzMJdAV4QP
Awel8LzGx5uMOshezF/KfP67wJ93UW+N7zXY6AwPgoLj4Kjw+WtU684JL8Dtr9FX
ozakE+8p06BpxegR4BR3FMHf6p+0jQxUEAkAyb/mVgm66TyghDGC6/YkiKoZptXQ
98TwDIK/39WEB/V607As+KoYazQG8drorw==
-----END CERTIFICATE-----
key: |-
[REDACTED PRIVATE KEY]
Traefik OSS를 프로덕션에서 사용하시나요?
직장에서 Traefik을 사용한다면, 엔터프라이즈급 API 게이트웨이 기능이나 Traefik OSS 상용 지원을 추가하는 것을 고려해 보세요.
-
API Gateway 데모 영상 보기
-
24/7/365 OSS 지원 요청
Traefik OSS에 API 게이트웨이 기능을 추가하는 것은 빠르고 매끄러워요. 기존 구성을 교체하거나(rip and replace) 버릴 필요 없이 그대로 유지됩니다. 짧은 영상으로 직접 확인해 보세요.