插件窝 干货文章 多租户微服务架构下,如何结合JetStream和Passport OAuth2实现基于Scope的RBAC权限控制?

多租户微服务架构下,如何结合JetStream和Passport OAuth2实现基于Scope的RBAC权限控制?

Scope 租户 访问 Passport 85    来源:    2025-03-15

在多租户微服务架构下,结合JetStream和Passport OAuth2实现基于Scope的RBAC(基于角色的访问控制)权限控制,可以通过以下步骤来实现:

1. 系统架构设计

首先,明确系统的架构设计。多租户架构意味着每个租户的数据和配置是隔离的,微服务架构则意味着系统被拆分为多个独立的服务。JetStream用于消息传递,Passport OAuth2用于身份验证和授权。

2. 使用Passport OAuth2进行身份验证和授权

Passport OAuth2是一个流行的身份验证中间件,支持OAuth2协议。你可以使用它来管理用户身份验证和授权。

  • OAuth2授权服务器:负责颁发访问令牌(Access Token)。
  • 资源服务器:负责验证访问令牌并保护资源。

3. 定义Scope和角色

在OAuth2中,Scope用于定义用户或客户端可以访问的资源范围。RBAC则通过角色来管理权限。

  • 定义Scope:例如 read:users, write:users, delete:users 等。
  • 定义角色:例如 admin, editor, viewer 等。
  • 角色与Scope的映射:例如 admin 角色可以访问所有Scope,editor 角色可以访问 read:userswrite:usersviewer 角色只能访问 read:users

4. 在Passport OAuth2中实现Scope和角色的关联

在OAuth2授权服务器中,当用户或客户端请求访问令牌时,可以根据用户的角色来分配相应的Scope。

  • 用户登录:用户登录时,Passport OAuth2会验证用户身份并获取用户的角色。
  • 分配Scope:根据用户的角色,分配相应的Scope到访问令牌中。

5. 在资源服务器中验证Scope

在资源服务器中,当接收到请求时,需要验证访问令牌中的Scope是否允许执行请求的操作。

  • 验证访问令牌:使用Passport OAuth2的中间件来验证访问令牌的有效性。
  • 检查Scope:根据请求的操作,检查访问令牌中是否包含相应的Scope。

6. 使用JetStream进行消息传递

JetStream是NATS的一个功能,用于持久化消息流和消息队列。在多租户架构中,可以使用JetStream来确保消息的可靠传递和隔离。

  • 租户隔离:为每个租户创建独立的Stream和Consumer,确保消息的隔离。
  • 消息路由:根据租户ID将消息路由到相应的Stream。

7. 实现基于Scope的RBAC权限控制

结合上述步骤,实现基于Scope的RBAC权限控制。

  • 用户请求:用户通过OAuth2授权服务器获取访问令牌,令牌中包含相应的Scope。
  • 资源访问:用户访问资源时,资源服务器验证访问令牌并检查Scope。
  • 消息传递:如果需要跨服务通信,使用JetStream确保消息的可靠传递和租户隔离。

8. 示例代码

以下是一个简单的示例代码,展示如何在Node.js中使用Passport OAuth2和JetStream实现基于Scope的RBAC权限控制。

const passport = require('passport');
const { JetStreamClient } = require('nats');

// OAuth2授权服务器
passport.use(new OAuth2Strategy({
  authorizationURL: 'https://authorization-server.com/auth',
  tokenURL: 'https://authorization-server.com/token',
  clientID: 'your-client-id',
  clientSecret: 'your-client-secret',
  callbackURL: 'https://your-app.com/callback'
},
function(accessToken, refreshToken, profile, cb) {
  // 根据用户角色分配Scope
  const user = findUserByProfile(profile);
  const scopes = getScopesByRole(user.role);
  cb(null, { accessToken, scopes });
}));

// 资源服务器
app.get('/users', passport.authenticate('oauth2', { session: false }), (req, res) => {
  const scopes = req.user.scopes;
  if (scopes.includes('read:users')) {
    // 允许访问
    res.json({ users: [] });
  } else {
    // 拒绝访问
    res.status(403).json({ error: 'Forbidden' });
  }
});

// JetStream消息传递
const nc = await connect({ servers: 'nats://localhost:4222' });
const js = nc.jetstream();
const stream = await js.streams.add({ name: 'tenant1-stream', subjects: ['tenant1.>'] });
const consumer = await stream.consumers.add({ name: 'tenant1-consumer' });

// 发布消息
js.publish('tenant1.order.created', JSON.stringify({ orderId: 123 }));

// 消费消息
const sub = consumer.subscribe();
for await (const msg of sub) {
  console.log(`Received message: ${msg.data}`);
  msg.ack();
}

9. 总结

通过结合JetStream和Passport OAuth2,你可以在多租户微服务架构中实现基于Scope的RBAC权限控制。Passport OAuth2负责身份验证和授权,JetStream负责消息传递和租户隔离。通过定义Scope和角色,并在资源服务器中验证Scope,你可以实现细粒度的权限控制。