서비스 의도(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 웹 토큰을 기반으로 서비스 의도를 적용하도록 네트워크를 구성하는 과정은 다음 단계로 구성돼요:

  1. JWT provider 구성 엔트리 생성. 이 구성 엔트리는 토큰 검증을 위한 규칙과 동작을 정의해요. 이러한 구성은 Consul Enterprise의 admin 파티션에 적용되며, 이는 기능적으로 Consul CE의 데이터센터와 동등해요. 그런 다음 jwt-provider 구성 엔트리를 Consul에 기록해요. 이 구성 엔트리를 읽고 수정하기 위한 ACL 정책 요구 사항은 mesh:write예요.

  2. 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: 이 필드는 토큰의 iss claim과 일치해야 해요.

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

더 알아보기 (Learn more)