JWT 토큰
JWT 토큰 (JWT Token)
이 작업은 JSON 웹 토큰(JWT)을 기반으로 접근을 시행하는 Istio 인가 정책을 설정하는 방법을 보여드려요. Istio 인가 정책은 string 및 string 목록 유형의 JWT 클레임을 모두 지원해요.
출처: Istio 문서
본문
이 작업은 JSON 웹 토큰(JWT)을 기반으로 접근을 시행하는 Istio 인가 정책을 설정하는 방법을 보여드려요. Istio 인가 정책은 string 유형과 string 목록 유형의 JWT 클레임을 모두 지원해요.
시작하기 전에 (Before you begin)
이 작업을 시작하기 전에 다음을 수행하세요.
- Istio 최종 사용자 인증 작업을 완료하세요.
- Istio 인가 개념을 읽으세요.
- Istio 설치 가이드를 사용해서 Istio를 설치하세요.
- 두 워크로드
httpbin과curl을 배포하세요. 예:foo네임스페이스에 배포하세요. 두 워크로드 모두 앞에 Envoy 프록시가 있어요. 다음 명령으로 예시 네임스페이스와 워크로드를 배포하세요.
$ kubectl create ns foo
$ kubectl apply -f <(istioctl kube-inject -f @samples/httpbin/httpbin.yaml@) -n foo
$ kubectl apply -f <(istioctl kube-inject -f @samples/curl/curl.yaml@) -n foo
- 다음 명령으로
curl이httpbin과 성공적으로 통신하는지 확인하세요.
$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" -c curl -n foo -- curl http://httpbin.foo:8000/ip -sS -o /dev/null -w "%{http_code}\n"
200
[!note] 예상 출력이 안 보이면 몇 초 후에 다시 시도하세요. 캐싱과 전파로 인해 지연이 발생할 수 있어요.
유효한 JWT 및 목록 유형 클레임이 있는 요청 허용하기 (Allow requests with valid JWT and list-typed claims)
- 다음 명령은
foo네임스페이스의httpbin워크로드에 대한jwt-example요청 인증 정책을 만들어요.httpbin워크로드에 대한 이 정책은[email protected]가 발급한 JWT를 수락해요.
$ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1
kind: RequestAuthentication
metadata:
name: "jwt-example"
namespace: foo
spec:
selector:
matchLabels:
app: httpbin
jwtRules:
- issuer: "[email protected]"
jwksUri: "https://raw.githubusercontent.com/istio/istio/release-1.31/security/tools/jwt/samples/jwks.json"
EOF
- 잘못된 JWT가 있는 요청이 거부되는지 확인하세요.
$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" -c curl -n foo -- curl "http://httpbin.foo:8000/headers" -sS -o /dev/null -H "Authorization: Bearer ***" -w "%{http_code}\n"
401
- 인가 정책이 없으므로 JWT가 없는 요청이 허용되는지 확인하세요.
$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" -c curl -n foo -- curl "http://httpbin.foo:8000/headers" -sS -o /dev/null -w "%{http_code}\n"
200
- 다음 명령은
foo네임스페이스의httpbin워크로드에 대한require-jwt인가 정책을 만들어요. 정책은httpbin워크로드에 대한 모든 요청이requestPrincipal이[email protected]/[email protected]로 설정된 유효한 JWT를 가질 것을 요구해요. Istio는 JWT 토큰의iss와sub를/구분자로 결합해서requestPrincipal을 구성해요. 다음과 같이요.
$ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: require-jwt
namespace: foo
spec:
selector:
matchLabels:
app: httpbin
action: ALLOW
rules:
- from:
- source:
requestPrincipals: ["[email protected]/[email protected]"]
EOF
iss와sub키를 같은 값[email protected]로 설정하는 JWT를 가져오세요. 이렇게 하면 Istio가 값[email protected]/[email protected]로requestPrincipal속성을 생성해요.
$ TOKEN=$(curl https://raw.githubusercontent.com/istio/istio/release-1.31/security/tools/jwt/samples/demo.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode
{"exp":4685989700,"foo":"bar","iat":1532389700,"iss":"[email protected]","sub":"[email protected]"}
- 유효한 JWT가 있는 요청이 허용되는지 확인하세요.
$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" -c curl -n foo -- curl "http://httpbin.foo:8000/headers" -sS -o /dev/null -H "Authorization: Bearer ***" -w "%{http_code}\n"
200
- JWT가 없는 요청이 거부되는지 확인하세요.
$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" -c curl -n foo -- curl "http://httpbin.foo:8000/headers" -sS -o /dev/null -w "%{http_code}\n"
403
- 다음 명령은
require-jwt인가 정책을 업데이트해서 JWT가group1값을 포함하는groups라는 클레임을 갖도록 요구해요.
$ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: require-jwt
namespace: foo
spec:
selector:
matchLabels:
app: httpbin
action: ALLOW
rules:
- from:
- source:
requestPrincipals: ["[email protected]/[email protected]"]
when:
- key: request.auth.claims[groups]
values: ["group1"]
EOF
[!note] 클레임 자체에 따옴표가 없는 한
request.auth.claims필드에 따옴표를 포함하지 마세요.
groups클레임을 string 목록group1과group2로 설정하는 JWT를 가져오세요.
$ TOKEN_GROUP=$(curl https://raw.githubusercontent.com/istio/istio/release-1.31/security/tools/jwt/samples/groups-scope.jwt -s) && echo "$TOKEN_GROUP" | cut -d '.' -f2 - | base64 --decode
{"exp":3537391104,"groups":["group1","group2"],"iat":1537391104,"iss":"[email protected]","scope":["scope1","scope2"],"sub":"[email protected]"}
groups클레임에group1이 포함된 JWT가 있는 요청이 허용되는지 확인하세요.
$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" -c curl -n foo -- curl "http://httpbin.foo:8000/headers" -sS -o /dev/null -H "Authorization: Bearer ***" -w "%{http_code}\n"
200
groups클레임이 없는 JWT가 있는 요청이 거부되는지 확인하세요.
$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" -c curl -n foo -- curl "http://httpbin.foo:8000/headers" -sS -o /dev/null -H "Authorization: Bearer ***" -w "%{http_code}\n"
403
정리 (Clean up)
foo 네임스페이스를 제거하세요.
$ kubectl delete namespace foo
더 알아보기 (Learn more)
- JWT 인증과 요청 원칙에 대한 자세한 내용은 인증 문서를 참고하세요.
- 인가 정책의
when조건과 요청 속성에 대해서는 인가 개념 문서를 참고하세요.