英文:
Is it bad practice to put additional claims for authorization
问题
我想在我的微服务项目上实现授权层。我有3个微服务:customer-service、workspace-service和cloud-service。所以,如果一个客户想要创建一个云实例,他将代表一个工作空间创建它,这意味着云实例将属于工作空间,而不是属于客户本人,他还可以邀请其他客户加入工作空间,并访问云实例。数据结构可能如下所示。
// 工作空间
{
"workspaceId": "ws-123",
"customers": ["customer-123", "customer-456"]
}
// 云实例
{
"cloudId": "cloud-123",
"workspaceId: "ws-123"
}
我想实现授权逻辑,检查用户是否有权限访问特定的云实例。为了做到这一点,我需要在我的身份验证对象中的某个地方有workspaceId。我可以考虑的一种方法是将workspaceId放入JWT声明中,所以我的JWT可能看起来像这样。
header.{..., workspaceId: ["ws-123"]}.signature
但这种解决方案的缺点是workspaceId声明在令牌被刷新之前不会更新。
另一种解决方案是实现一个服务,从workspace-service查询数据并用它来验证。
const hasAccess = (customerId, workspaceId_on_cloud_instance) => {
let actual_workspaceId_that_he_has = workspace_service_exposed_api.findWorkspaceByCustomerId(customerId)
return actual_workspaceId_that_he_has == workspaceId_on_cloud_instance
}
但这种方法将严重依赖于workspace-service,如果workspace-service宕机,其他服务将无法处理请求,因为它无法访问workspaceId。
所以在我看来,我宁愿选择第一种选项,因为我使用OAuth 2.0,令牌每30秒刷新一次,但这样做是否不好呢?我想知道是否有更好的解决方案。
英文:
I want to implement authorization layer on my microservices project. I have 3 microservices customer-service, workspace-service and cloud-service. So if a customer want to create a cloud instance he will create on behalf of a workspace which means that the cloud instance will belong to the workspace instead of him and also he may invite other customer to the workspace, and have access to the cloud instance. The data structure may looks like this.
// workspace
{
"workspaceId": "ws-123",
"customers": ["customer-123", "customer-456"]
}
// cloud-instance
{
"cloudId": "cloud-123",
"workspaceId: "ws-123"
}
I want to implement authorization logic that check if a user has access to a particular cloud instance. In order to do that I need to have workspaceId somewhere else in my authentication object. One thing that I can think of is that to put workspaceId in the jwt claims so my jwt may looks like this.
header.{ ..., workspaceId: ["ws-123"] }.signature
but the drawback of this solution is that the workspaceId claim won't be updated until the token has been refresh.
another solution that is to implement a service that query data from workspace-service and use it to validate.
const hasAccess = (customerId, workspaceId_on_cloud_instance) => {
let actual_workspaceId_that_he_has = workspace_service_exposed_api.findWorkspaceByCustomerId(customerId)
return actual_workspaceId_that_he_has == workspaceId_on_cloud_instance
}
but this approach would heavily rely on workspace-service if workspace-service is down then the other service can not handle a request at all since it doesn't have access to workspaceId.
So IMHO I would rather go for the 1st option since I use oauth2.0 and token will be refresh every 30s, but is it bad practice to do that? I wonder if there's better solution.
答案1
得分: 1
以下是翻译好的内容:
拥有3个微服务时,不能假设一个服务已经宕机来实现功能。我有一种感觉,访问令牌的生命周期也是根据这个限制来定义的,以便在令牌中获得最新的数据。如我所理解,最坏的情况下,与令牌有效载荷中的workspaceId更新相关还会有大约30秒的延迟。
令牌声明仅在邀请或从工作区中移除人员时才会更改,因此此服务必须始终正常工作。我会使用第二种方案,将令牌的生命周期延长,以便不必经常生成它。
另一种解决方案是在每次更改工作区时生成新的令牌 - 您可以将添加/删除到工作区视为使令牌失效的业务逻辑,但可能在这种情况下还需要与工作区服务进行通信。
如果您担心微服务会宕机或与通信有问题,也许您应该更多关注应用程序基础架构,或者选择基于单体应用程序的新解决方案。
回到标题的问题 - 向令牌有效载荷添加任何自定义声明都是标准的方法。
英文:
Having 3 microservices you cannot implement functionality with assumption that one service is down. I have feeling that access token lifespan is also defined based on this restriction - to have up to date data in the token. As I correctly understand, in worst case there is also ~30 sec. delay related to workspaceId update in token payload.
Token claim will change only when you invite or remove person from workspace so this service must work anyway. I would use 2nd solution with longer token lifespan to not generate it so often.
Another solution is to generate new token every time when workspace is changed - you can treat adding/removing to workspace as a business logic that invalidates token, but probably in this case communication to workspace service is also required.
If you are afraid that microservice will be down or you will have problem with communication, maybe you should focus more on app infrastructure or choose a new solution based on monolith application.
And back to question from title - adding any custom claim to token payload is standard approach.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论