微服务架构中 docker 个容器之间的身份验证,绕过内部调用的 JWT 身份验证
Authentication between docker containers in microservices architecture, bypassing JWT auth for internal calls
我有以下 docker 架构,用 docker 组合编排:
- Service1: 前端应用,React 应用
- Service2:ExpressJS 服务器
- Service3: Django 服务器
这三个应用程序通过 HTTP API 调用相互通信。谁可以打电话给谁没有限制。每个应用都对外暴露
用户在前端应用程序 (Service1) 上进行身份验证,它解析了一个 JWT,该 JWT 稍后可以传递给其他后续调用,然后每个其他服务都有一个身份验证层来验证 JWT 调用。
我的问题是:我们如何在没有任何用户的情况下验证从 Service2 到 Service3 的调用 activity(没有 JWT)?
这是 cron 或维护作业所必需的。
我的第一个解决方案是在我们的 docker-compose 中创建一个带有固定子网的 docker 网络,如下所示:
networks:
our-network:
ipam:
driver: default
config:
- subnet: "172.100.100.0/24"
然后,在 Service2 和 Service3 中,我允许来自该子网的 API 调用未经身份验证。
我担心这可能是一个安全问题,想知道是否有更好的解决方案。
JWT 令牌通常签名,带有属于令牌发行者的私钥。 JWT-tokens 作为 issuer claim.
是一个很好的做法
A JWT-token 通常可以通过两种方式进行验证:
- 调用发行者的 OAuth token introspection endpoint - 但这会增加延迟
- 使用发行者缓存的 public 密钥 进行本地验证 - 难以添加注销功能
如果您使用不会增加太多延迟的缓存解决方案,JWT 发行者必须实施 OpenID Discovery endpoint including a reference to the JWKS endpoint 发行者发布其 public 密钥.
如果您使用 Kubernetes,则可以使用带有 OpenPolicyAgent 的边车来为应用程序执行令牌验证。对于开发人员来说,在每个应用程序中实现 token-validation 功能并不是那么有趣,因此这是一个有趣的替代方案。您还可以使用此解决方案轻松添加授权规则。
How would we validate calls from Service2 to Service3 without any user activity (without JWT)?
当 Service2 收到用户的请求时,使用 JWT 进行身份验证 - 它向 Service3 on-behalf-of 用户发出请求,因此它也应该将 JWT 令牌传递给 Service3 - 这样 Service3 就可以操作并仅使用属于用户的资源,例如从数据库中获取。这可以在没有用户干预的情况下完成(直到 JWT 过期)。
This is required for crons or maintenance jobs
对于由 on-behalf-of 用户执行的作业,通常需要存储 JWT-token 具有较长 到期时间 的 JWT-token,例如在数据库中。通常这可以由用户撤销,并且通常在 3 个月左右后过期,然后用户可能需要再次进行身份验证(或超过 3 个月 - 取决于您的需要)。重要的是,此类令牌具有较低的权限,通常只有作业所需的权限。
我有以下 docker 架构,用 docker 组合编排:
- Service1: 前端应用,React 应用
- Service2:ExpressJS 服务器
- Service3: Django 服务器
这三个应用程序通过 HTTP API 调用相互通信。谁可以打电话给谁没有限制。每个应用都对外暴露
用户在前端应用程序 (Service1) 上进行身份验证,它解析了一个 JWT,该 JWT 稍后可以传递给其他后续调用,然后每个其他服务都有一个身份验证层来验证 JWT 调用。
我的问题是:我们如何在没有任何用户的情况下验证从 Service2 到 Service3 的调用 activity(没有 JWT)?
这是 cron 或维护作业所必需的。
我的第一个解决方案是在我们的 docker-compose 中创建一个带有固定子网的 docker 网络,如下所示:
networks:
our-network:
ipam:
driver: default
config:
- subnet: "172.100.100.0/24"
然后,在 Service2 和 Service3 中,我允许来自该子网的 API 调用未经身份验证。 我担心这可能是一个安全问题,想知道是否有更好的解决方案。
JWT 令牌通常签名,带有属于令牌发行者的私钥。 JWT-tokens 作为 issuer claim.
是一个很好的做法A JWT-token 通常可以通过两种方式进行验证:
- 调用发行者的 OAuth token introspection endpoint - 但这会增加延迟
- 使用发行者缓存的 public 密钥 进行本地验证 - 难以添加注销功能
如果您使用不会增加太多延迟的缓存解决方案,JWT 发行者必须实施 OpenID Discovery endpoint including a reference to the JWKS endpoint 发行者发布其 public 密钥.
如果您使用 Kubernetes,则可以使用带有 OpenPolicyAgent 的边车来为应用程序执行令牌验证。对于开发人员来说,在每个应用程序中实现 token-validation 功能并不是那么有趣,因此这是一个有趣的替代方案。您还可以使用此解决方案轻松添加授权规则。
How would we validate calls from Service2 to Service3 without any user activity (without JWT)?
当 Service2 收到用户的请求时,使用 JWT 进行身份验证 - 它向 Service3 on-behalf-of 用户发出请求,因此它也应该将 JWT 令牌传递给 Service3 - 这样 Service3 就可以操作并仅使用属于用户的资源,例如从数据库中获取。这可以在没有用户干预的情况下完成(直到 JWT 过期)。
This is required for crons or maintenance jobs
对于由 on-behalf-of 用户执行的作业,通常需要存储 JWT-token 具有较长 到期时间 的 JWT-token,例如在数据库中。通常这可以由用户撤销,并且通常在 3 个月左右后过期,然后用户可能需要再次进行身份验证(或超过 3 个月 - 取决于您的需要)。重要的是,此类令牌具有较低的权限,通常只有作业所需的权限。