多租户ServiceStack API,相同的部署以应对在不同的主机名请求? [英] Multi-tenant ServiceStack API, same deployment to respond to requests on different hostnames?
问题描述
我们正在创建使用的是多租户的API ServiceStack 。我们要做的基于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属性可以从主机模式读取数值呢?因此,使路线值为从出主机名匹配以及路径?
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:// {租户} {环境DNS区域}
/ {与令牌路径的休息}。
https://{tenant}.{DNS zone for environment}/{rest of path with tokens}
此外 - 出DNS区域将根据其环境我们在不同 - 非生产我们使用(说) testing-foobar.com
,而我们使用的生产 real-live.com
。理想情况下,我们会能够有一个路由声明,同时支持(我们preFER在运行时装饰请求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.
您想最终是这样的:
You'd end up with something like this:
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屋!