서비스 의도(intentions)와 함께 JWT 인가 사용
서비스 의도(intentions)와 함께 JWT 인가 사용
JSON Web Token(JWT)을 사용하여 서비스 의도를 기반으로 서비스 접근을 인가하는 방법을 설명해 드릴게요. JWT provider 구성 엔트리와 service-intentions 구성 엔트리를 함께 사용해요.
출처: 문서
본문
JSON Web Token(JWT)은 사람과 기계 모두를 위한 서비스 접근의 ID 기반 인증 방법이에요. JWT provider 구성 엔트리를 사용하면 JWT를 JSON Web Key Set(JWKS)의 일부로 정의할 수 있으며, 여기에는 Consul이 접근을 검증하고 JWT를 포함하는 요청에 대한 동작을 구성하는 데 필요한 정보가 포함돼요.
구성 엔트리에 JSON Web Key Set(JWKS)을 지정하고 서비스 의도에서 키 세트를 참조하면, Consul은 JWT의 존재에 기반하여 서비스 의도를 적용할 수 있어요. 이 보안 구성은 JWT를 서비스 의도 대신 Consul ACL과 연결하는 JSON Web Token Auth Method와는 관련이 없어요.
워크플로
JSON 웹 토큰을 기반으로 서비스 의도를 적용하도록 네트워크를 구성하는 과정은 다음 단계로 구성돼요:
-
JWT provider 구성 엔트리 생성. 이 구성 엔트리는 토큰 검증을 위한 규칙과 동작을 정의해요. 이러한 구성은 Consul Enterprise의 admin 파티션에 적용되며, 이는 기능적으로 Consul CE의 데이터센터와 동등해요. 그런 다음
jwt-provider구성 엔트리를 Consul에 기록해요. 이 구성 엔트리를 읽고 수정하기 위한 ACL 정책 요구 사항은mesh:write예요. -
JWT provider를 참조하도록 서비스 의도 구성 엔트리 생성 또는 업데이트. 이 구성은 만든
jwt-provider구성 엔트리의 이름을 호출하여, 들어오는 요청이 수락되기 전에 Envoy 프록시가 토큰과 그 토큰이 인가하는 권한을 검증하게 해요. 그런 다음 JWT를 참조하는service-intentions구성 엔트리를 Consul에 기록해요. 이 구성 엔트리를 읽고 수정하기 위한 ACL 정책 요구 사항은mesh:write예요.
와일드카드 및 의도 기본값
토큰이 없는 의도는 대상 프록시에 도착할 때 인가되므로, service-intentions 구성 엔트리의 일반적인 패턴은 엔트리의 Name 필드를 와일드카드 *로 설정하는 거예요. 이 패턴은 특정 서비스의 들어오는 요청을 데이터센터의 모든 서비스에 적용할 수 있게 해줘요.
JSON Web Token으로 서비스 의도를 적용하도록 배포를 구성할 때 여러 다른 권한을 가진 토큰이 HTTP 경로나 요청 메서드 같은 속성에 기반하여 단일 서비스의 들어오는 요청에 적용될 수 있어요. service-intentions 구성 엔트리가 요청과 가장 근접하게 일치하는 의도를 적용하므로, 특정 JWT 인가 구성과 함께 Name 와일드카드를 사용하면 의도하지 않은 결과가 발생할 수 있어요.
service-intentions 구성 엔트리에서 JWT{}.Providers 필드를 와일드카드 *로 설정하면 기존 JWT provider 구성 엔트리와 일치하는 토큰을 제시하는 모든 서비스에 대한 기본 동작을 구성할 수 있어요. 이 구성에서 유효한 토큰이 있지만 더 구체적인 일치 의도가 없는 서비스는 와일드카드 의도에 정의된 동작을 기본값으로 사용해요.
요구 사항
- ACL 활성화. ACL이 활성화되어 있고 default_policy가 deny로 설정되어 있는지 확인해 주세요.
사용
서버로 요청을 전달하기 전에 Envoy 프록시가 JWT를 검증하도록 구성하려면 다음 단계를 완료해 주세요:
JWT provider 구성 엔트리 생성
jwt-provider 구성은 다음 필드가 필요해요:
- Kind: 이 필드는
"jwt-provider"로 설정해야 해요. - Name: 구성 파일의 이름을 구성에 사용된 JWT provider의 이름으로 지정할 것을 권장해요.
- Issuer: 이 필드는 토큰의
issclaim과 일치해야 해요.
JSONWebKeySet 필드에 JSON Web Key Set을 지정해야 해요. JWKS는 다음 중 하나로 지정할 수 있어요:
- 로컬 문자열
- 로컬 파일의 경로
- URI로 지정된 원격 위치
JWKS는 로컬 또는 원격으로 제공할 수 있지만 둘 다는 안 돼요. 또한 로컬 JWKS는 문자열 또는 토큰이 포함된 파일의 경로로 지정해야 해요.
JWT의 위치, 재시도 정책, 토큰 검증 후 요청을 전달할 때 헤더에 추가할 텍스트도 지정할 수 있어요.
다음 예시는 Okta가 발급한 JSON Web Token을 가져오도록 Consul을 구성해요. Consul은 URI에서 토큰을 가져와 토큰이 만료되기 전 30분 동안 캐시에 보관해요. 검증 후 토큰은 HTTP 헤더에 user-token이 추가된 상태로 백엔드로 전달돼요.
Kind = "jwt-provider"
Name = "okta"
Issuer = "okta"
JSONWebKeySet = {
Remote = {
URI = "https://<org>.okta.com/oauth2/default/v1/keys"
CacheDuration = "30m"
}
}
Forwarding = {
HeaderName = "user-token"
}
구성할 수 있는 필드에 대한 자세한 내용은 JWT provider 구성 엔트리를 참고해 주세요.
구성 엔트리를 Consul에 기록하려면 consul config write 명령을 사용해 주세요:
$ consul config write okta-provider.hcl
서비스 의도 업데이트
JWT provider 엔트리를 만든 후에는 프록시가 요청을 인가하기 전에 토큰을 검증하도록 서비스 의도를 업데이트할 수 있어요. 다음 예시는 서비스 의도로 JWT 인가를 활성화하는 데 필요한 최소 구성을 포함해요:
Kind = "service-intentions"
Name = "web"
JWT = {
Providers = [
{
Name = "okta"
}
]
}
토큰이 특정 claim과 일치하도록 요구하는 추가 구성 정보를 포함할 수 있어요. 또한 JWT 필드를 특정 HTTP 경로에서 온 요청에만 적용하도록 구성할 수 있어요. 예시 구성은 의도와 함께 JWT 검증을 참고해 주세요.
서비스 의도를 업데이트한 후 구성을 Consul에 기록하여 적용되게 해 주세요:
$ consul config write web-intention.hcl