多租户 ServiceStack API,相同的部署来响应不同主机名上的请求? [英] Multi-tenant ServiceStack API, same deployment to respond to requests on different hostnames?

查看:18
本文介绍了多租户 ServiceStack API,相同的部署来响应不同主机名上的请求?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在使用 ServiceStack 创建多租户 API.我们想要进行基于 DNS 的负载平衡和路由,而不是通过反向代理(如 nginx 或 haproxy)进行拼接.

We're creating APIs using ServiceStack that are multi-tenant. We want to do DNS-based load-balancing and routing, rather than stitch things up via a reverse proxy (like nginx or haproxy).

我们有具有租户参数的请求 DTO.ServiceStack(及其 SwaggerFeature)允许我们定义自定义路由,并记录 DTO,以便我们可以从路径、查询、标题或正文中读取值.

We have Request DTOs that have a Tenant parameter. ServiceStack (and its SwaggerFeature) allow us to define custom routes, and document the DTOs such that we can read values from path, query, headers, or body.

我们如何(最好)连接东西以便 DTO 属性也可以从主机名模式中读取值?那么,让 Route 从匹配的主机名和路径中获取值?

How do we (best) wire things so that DTO properties can read values from a hostname pattern as well? So, make the Route take values from matching out of the hostname as well as the path?

我们想要像这样的网址

  • https://{tenant}.{DNS zone for environment}/{rest of path with tokens}

此外 - 外部 DNS 区域将根据我们所处的环境而有所不同 - 对于非生产我们使用(比如)testing-foobar.com,而生产我们使用 real-live.com.理想情况下,我们可以通过单个路由声明来支持两者(并且我们更喜欢在运行时装饰请求 DTO 而不是命令式声明AppHost.Init).

Also - out DNS zone will vary depending which environment we're in - for non-production we use (say) testing-foobar.com, and production we use real-live.com. Ideally we'd be able to support both with a single route declaration (and we prefer decorating the Request DTO instead of imperative declaration at run-time AppHost.Init).

推荐答案

我就在本周解决了这个问题,在一个现有的多租户系统上,该系统使用 .NET 安全主体来处理用户权限和租户.我使用自定义 ServiceRunner 来选择租户并设置安全性.您的多租户方法有所不同,但使用 ServiceRunner 似乎仍然是一种有效的方法.

I solved this just this week, on a existing multi-tenant system which uses .NET security principals to deal with the user permissions and tenants. I used a custom ServiceRunner to select the tenant and set up the security. Your approach to multi-tenant is different, but using a ServiceRunner still seems a valid approach.

你会得到这样的结果:

public class MyServiceRunner<T> : ServiceRunner<T>
{
    public MyServiceRunner(IAppHost appHost, ActionContext actionContext)
        : base(appHost, actionContext)
    {}

    public override void BeforeEachRequest(IRequestContext requestContext, T request)
    {
        // Set backend authentication before the requests are processed.
        if(request instanceof ITenantRequest)
        {
            Uri uri = new Uri(requestContext.AbsoluteUri);
            string tenant = uri.Host; // Or whatever logic you need...
            ((ITenantRequest).Tenant = tenant;
        }
    }
}

public class MyAppHost : AppHostBase
{
    public MyAppHost() : base("My Web Services", typeof(MyService).Assembly) { }

    public override IServiceRunner<TRequest> CreateServiceRunner<TRequest>(ActionContext actionContext)
    {
        return new MyServiceRunner<TRequest>(this, actionContext);
    }

    public override void Configure(Container container)
    {
        ...
    }
}

也许请求过滤方法在某种程度上更好,但这对我们有用.

Perhaps the Requests filtering approach is somehow better, but this does the job for us.

这篇关于多租户 ServiceStack API,相同的部署来响应不同主机名上的请求?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆