c# - 具有 Multi-Tenancy 数据访问的 Web API 身份验证

标签 c# authentication oauth-2.0 asp.net-web-api2 owin

我不确定我是否使用了正确的标题,但我想不出更好的方式来描述它。这可能更像是一个设计问题。

我有一个 Multi-Tenancy 数据库,其中一个用户可以属于一个或多个实体。我通过调用/token 端点使用他/她的凭据对用户进行身份验证。

收到 token 后,我调用自己的端点(使用 token )来获取该用户的可用实体列表,然后允许该用户在内存缓存中设置他的当前实体。然后,我在内存缓存中使用它来查找所有后续请求的实体/租户 ID,以了解用户在调用数据库时“登录”到哪个实体/租户。

理想情况下,我想消除对内存缓存的需求,以便通过将实体/租户 ID 作为声明包含在 token 中来使我的应用程序更加无状态,但我只在用户通过身份验证并选择他的之后才知道这个 ID/她的实体。我显然无法在 token 发布后更改或添加声明,但是否有替代设计来实现这种行为?

我考虑过可能为每个租户使用一个子域,但从技术上讲,这更难设置和维护。我还考虑过提示用户输入他/她希望登录的实体,作为带有凭据的自由文本,但这并不理想。

有没有人遇到过这个挑战?

最佳答案

我同意您的观点,即租户选择必须以无状态方式完成,以避免在基于 REST 的架构中进行有状态交互。缓存方法可能会导致许多陷阱,并引入对基于 session 的交互的强烈依赖。

我可以想到两个主要选项来使租户选择无状态:

  1. 基于 URI 的选择:您可以向 API 添加租户参数,在所有 Controller 之间共享。类似于此的映射:api/{tenantId}/{controller}/{id} 可以让您以简单的客户端方式在租户之间切换。这可以使用基于约定的路由来完成:

    routes.MapHttpRoute(
        name: "API Default",
        routeTemplate: "api/{tenantId}/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
    

    或者基于属性的路由,在你的 Controller 上使用 RoutePrefixAttribute:

    [RoutePrefix("api/{tenantId}/myentities")]
    public class EntityController : ApiController
    {
        [Route("")]
        public IHttpActionResult GetAllEntities(string tenantId)
        {
            //...
    
  2. 基于 header 的选择:您可以考虑添加自定义 HTTP header ,其中将包含有关所选租户的信息:例如X-Tenant-Selection: TenantId,然后你可以阅读这个 Header inside a custom Filter ,或者在 Web API 之前执行的 OwinMiddleware 中,并设置一个上下文变量(或者甚至是一个将持续当前请求的用户声明)以在您的 Controller 中使用。

当然,在这两种情况下,您都必须在返回数据之前验证当前用户是否可以访问所选租户。

坦率地说,我会排除将 tenantId 包含在访问 token 中的可能性,而且子域方法对我来说太复杂了。

关于c# - 具有 Multi-Tenancy 数据访问的 Web API 身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36583626/

相关文章:

c# - 如何在单独的方法中对变量进行排序

c# - 使用 LINQ 求字段总和

ruby-on-rails - 设计的 token_authenticable 安全吗?

c# - 如何在azure函数中处理dbContext?

c# - 在 .aspx 页面中获取设置值?

reactjs - 没有当前用户 AWS Amplify 身份验证错误 - 无需登录即可访问

javascript - MarkLogic 应用程序服务器自定义登录页面 sessionID cookie 与 GET 请求

ios - 带有 iOS 的 Google App Engine 上的 Facebook OAuth

php - 隐式授予 Laravel 5.4 护照 unsupported_grant_type 错误

oauth-2.0 - OAuth2 授予类型密码正在撤销其他 access_token