Casbin을 사용하여 APISIX에서 인증 처리
소개
Apache APISIX는 내장 authz-casbin 플러그인을 통해 게이트웨이에서 Casbin 인증 정책을 적용할 수 있습니다. 이 플러그인은 Lua Casbin을 사용하며 ACL, RBAC, ABAC과 같은 접근 제어 모델을 지원합니다.
이 가이드에서는 APISIX 요청 경로에 작은 RBAC 정책을 적용합니다. 허용 및 거부된 요청을 검증한 후, 라우트를 변경하지 않고 플러그인 메타데이터를 통해 공유 정책을 업데이트합니다.
Casbin 커뮤니티는 원래 APISIX Issue #4674에서 통합을 제안했으며, APISIX PR #4710을 통해 플러그인이 추가되었습니다.
이 가이드는 2026년 8월에 갱신되었습니다. 예제는 Apache APISIX 3.17.0으로 검증되었습니다. 원본 2021년 저자의 공로는 그대로 유지되며, 2026년 갱신을 위해 Yilia Lin이 추가로 기재되었습니다.
Casbin은 인증(authorization)을 수행하며, 신원 확인(authentication)은 하지 않습니다. 테스트를 간단하게 유지하기 위해 예제에서는 user 요청 헤더를 주체(subject)로 사용합니다. 프로덕션 환경에서는 클라이언트가 직접 제공하는 신원 헤더를 신뢰하지 마십시오. 인증 레이어 또는 신뢰할 수 있는 프록시가 신원을 확립하고, Casbin이 요청을 평가하기 전에 신뢰할 수 없는 값을 제거하거나 덮어써야 합니다.
사전 요구 사항 및 시작 상태
이 가이드는 이미 실행 중인 일회성 Apache APISIX 3.17.0 인스턴스로 시작합니다. 로컬 인스턴스가 필요한 경우 APISIX Docker 배포 가이드를 따르고 APISIX 이미지를 apache/apisix:3.17.0-debian으로 고정하십시오.
인스턴스에는 다음이 있어야 합니다:
http://127.0.0.1:9080에서 사용할 수 있는 데이터 플레인;http://127.0.0.1:9180에서 사용할 수 있는 Admin API;- 내장
authz-casbin및mocking플러그인이 활성화되어 있습니다.
또한 curl과 jq가 필요합니다. admin_key를 구성한
Admin API 키로 설정하세요:
export admin_key='<your-admin-api-key>'
계속하기 전에 플레이스홀더를 교체하세요. Admin API에 접근할 수 있고 플러그인이 활성화되었는지 확인하세요:
curl --fail-with-body \
"http://127.0.0.1:9180/apisix/admin/plugins/list" \
-H "X-API-KEY: $admin_key" | \
jq -e '(["authz-casbin", "mocking"] - .) | length == 0'
명령어는 true를 출력해야 합니다. Admin API를 신뢰할 수 없는 네트워크에 게시하거나
다른 환경에서 데모 자격 증명을 재사용하지 마세요.
모델 및 정책 정의
플러그인은 세 가지 요청 값을 평가합니다:
sub: 구성된 요청 헤더의 주체(subject);obj: 요청 URI 경로; 그리고act: HTTP 메서드.
model.conf 생성:
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[role_definition]
g = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = (g(r.sub, p.sub) || keyMatch(r.sub, p.sub)) && keyMatch(r.obj, p.obj) && keyMatch(r.act, p.act)
policy.csv 생성:
p, *, /anything, GET
p, admin, *, *
g, alice, admin
이 정책은 모든 주체가 GET /anything을 전송하도록 허용합니다. 또한
alice에게 모든 경로를 모든 메서드로 접근할 수 있는 admin 역할을 할당합니다.
공유 정책을 플러그인 메타데이터에 저장
파일을 JSON 문자열로 로드하고 APISIX 플러그인 메타데이터에 씁니다:
jq -n \
--rawfile model model.conf \
--rawfile policy policy.csv \
'{model: $model, policy: $policy}' | \
curl --fail-with-body \
"http://127.0.0.1:9180/apisix/admin/plugin_metadata/authz-casbin" \
-H "X-API-KEY: $admin_key" \
-H "Content-Type: application/json" \
-X PUT \
--data-binary @-
플러그인 메타데이터는 자체 라우트 로컬 모델 및 정책을 정의하지 않고
authz-casbin을 활성화하는 라우트에 하나의 모델과 정책을 제공합니다.
라우트에서 권한 부여 활성화
라우트를 생성하고 플러그인에게 user 헤더에서 주체를 읽도록 지시합니다:
curl --fail-with-body \
"http://127.0.0.1:9180/apisix/admin/routes/casbin-demo" \
-H "X-API-KEY: $admin_key" \
-H "Content-Type: application/json" \
-X PUT \
-d '{
"uri": "/*",
"plugins": {
"authz-casbin": {
"username": "user"
},
"mocking": {
"_meta": {
"priority": 1000
},
"response_status": 200,
"response_example": "{\"message\":\"authorized\"}"
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1": 1
}
}
}'
이 라우트는 로컬에서 username 필드만 정의하므로 플러그인 메타데이터의
모델과 정책을 사용합니다. 라우트 로컬 모델과 정책이 구성된 경우, 플러그인 메타데이터보다
우선합니다.
mocking 플러그인은 허용된 요청에 대해 결정적인 로컬 응답을 제공하므로,
예제가 공개 업스트림에 의존하지 않습니다. 해당 라우트 로컬 우선순위는
authz-casbin보다 낮아 권한 결정을 먼저 실행합니다.
따라서 도달할 수 없는 업스트림은 연결되지 않습니다. 이 우선순위 오버라이드와
모의 응답은 테스트 픽스처이며, 프로덕션 권장 사항이 아닙니다.
허용 및 거부 결정 검증
공개 경로에 대한 익명 요청은 허용됩니다:
curl -i http://127.0.0.1:9080/anything
기대 상태 코드:
HTTP/1.1 200 OK
{"message":"authorized"}
bob은 admin 역할이 없으므로 다른 경로는 거부됩니다:
curl -i http://127.0.0.1:9080/anything/res -H 'user: bob'
기대 결과:
HTTP/1.1 403 Forbidden
{"message":"Access Denied"}
alice는 admin 역할이 있으므로 동일한 요청은 허용됩니다:
curl -i http://127.0.0.1:9080/anything/res -H 'user: alice'
기대 상태 코드:
HTTP/1.1 200 OK
{"message":"authorized"}
공유 정책 업데이트
bob을 위한 직접 권한을 policy.csv에 추가합니다:
p, *, /anything, GET
p, admin, *, *
p, bob, /anything/res, GET
g, alice, admin
플러그인 메타데이터 명령을 다시 실행하세요. 이 메타데이터를 참조하는 라우트는 라우트 구성을 변경하지 않고도 업데이트된 정책을 사용합니다. 요청을 반복하세요:
curl -i http://127.0.0.1:9080/anything/res -H 'user: bob'
이제 기대 결과는 다음과 같습니다:
HTTP/1.1 200 OK
{"message":"authorized"}
구성 범위 선택
여러 라우트가 하나의 모델과 정책을 공유해야 하는 경우 플러그인 메타데이터를 사용하세요.
라우트가 독립적인 권한 구조가 필요한 경우 라우트 로컬 모델과 정책을 사용하세요.
전체 구성 스키마 및 파일 기반 대안은 APISIX authz-casbin 플러그인 레퍼런스를 참고하세요.
정리
테스트 라우트 제거:
curl --fail-with-body \
"http://127.0.0.1:9180/apisix/admin/routes/casbin-demo" \
-H "X-API-KEY: $admin_key" \
-X DELETE
공유 플러그인 메타데이터 제거:
curl --fail-with-body \
"http://127.0.0.1:9180/apisix/admin/plugin_metadata/authz-casbin" \
-H "X-API-KEY: $admin_key" \
-X DELETE

Comments are powered by giscus and GitHub Discussions. They load from giscus.app and GitHub only after you click the button below.