在多租户网站处理数据访问 [英] Handling data access in multi tenant site

查看:159
本文介绍了在多租户网站处理数据访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想AP preciate有关数据访问一些指针/在基于MVC的多租户现场控制:

I would appreciate some pointers regarding data access/control in a MVC based multi tenant site:

有没有更好/更安全的/优雅的方式,以确保在多租户站点的用户只能处理自己的数据。
有使用相同的应用程序租户数量:firstTenant.myapp.com,secondTenant.myapp.com ...

Is there a better/more secure/elegant way to make sure that in a multi tenant site the user can handle only its own data. There are number of tenants using same app: firstTenant.myapp.com, secondTenant.myapp.com...

    //
    // GET: /Customer/
    // show this tenant's customer info only

    public ViewResult Index()
    {
        //get TenantID from on server cache
        int TenantID =  Convert.ToInt16( new AppSettings()["TenantID"]);
        return View(context.Customers.ToList().Where(c => c.TenantID == TenantID));
    }

如果用户首次登录并没有服务器端缓存此租户/ DB中并存储用户可检查的AppSettings在TenantID缓存。

If a user logs in for the first time and there is no server side cache for this tenant/user- AppSettings checks in db and stores TenantID in the cache.

在数据库中的每个表中包含的字段TenantID,用于对数据的访问仅限制到适当的租户

Each table in database contains the field TenantID and is used to limit access to data only to appropriate Tenant.

那么,来点,而不是在每个控制器每个动作检查,如果数据属于目前的租户,我可以做更多的事情生产力?

So, to come to the point, instead of checking in each action in each controller if data belong to current tenant, can I do something more 'productive'?

例如:

在firstTenant管理员尝试编辑用户4的一些信息,网址有:
http://firstTenant.myapp.com/User/Edit/4

When firstTenant admin tries editing some info for user 4, url has: http://firstTenant.myapp.com/User/Edit/4

假设ID为2的用户属于secondTenant。从firstTenant看跌期权管理员
http://firstTenant.myapp.com/User/Edit/2 的网址,并尝试它不受他的公司拥有获得信息。

Let's say that user with ID 2 belongs to secondTenant. Admin from firstTenant puts http://firstTenant.myapp.com/User/Edit/2 in url, and tries getting info which is not owned by his company.

在为prevent这个控制器我是否正在编辑的信息实际上是由目前的租户拥有。

In order to prevent this in the controller I check if the info being edited is actually owned by current tenant.

    //
    // GET: /User/Edit/

    public ActionResult Edit(int id)
    {
        //set tennant ID
        int TenanatID = Convert.ToInt32(new AppSettings()["TenantID"]);
        //check if asked info is actually owned by this tennant
        User user = context.Userss.Where(u => u.TenantID == TenantID).SingleOrDefault(u => u.UserID == id);

        //in case this tenant doesn't have this user ID, ie.e returned User == null
        //something is wrong, so handle bad request
        //

        return View(user);
    }

基本上这种setneeds的被放置在每个控制器在有任何数据的访问。有没有(以及如何)更好的方式来处理这个问题? (过滤器,属性...)

Basically this sort of setneeds to be placed in every controller where there is an access to any data. Is there (and how) a better way to handle this? (Filters, attributes...)

推荐答案

我选择了用行动过滤器来做到这一点。它可能不是最完美的解决方案,但它是最干净的,到目前为止,我们已经尝试过的解决方案。

I choose to use action filters to do this. It may not be the most elegant solution, but it is the cleanest of the solutions we've tried so far.

我把租户(在我们的例子,这是一个团队),在这样的网址: https://myapp.com/ {}队/任务/信息/ 1234

I keep the tenant (in our case, it's a team) in the URL like this: https://myapp.com/{team}/tasks/details/1234

我用自定义绑定映射{}团队为实际的团队对象,所以我的操作方法是这样的:

I use custom bindings to map {team} into an actual Team object so my action methods look like this:

[AjaxAuthorize, TeamMember, TeamTask("id")]
public ActionResult Details(Team team, Task id)

TeamMember 属性验证当前登录的用户实际上属于团队。这也验证了球队确实存在:

The TeamMember attribute verifies that the currently logged in user actually belongs to the team. It also verifies that the team actually exists:

public class TeamMemberAttribute : ActionFilterAttribute
{
  public override void OnActionExecuting(ActionExecutingContext filterContext)
  {
    base.OnActionExecuting(filterContext);
    var httpContext = filterContext.RequestContext.HttpContext;

    Team team = filterContext.ActionParameters["team"] as Team;
    long userId = long.Parse(httpContext.User.Identity.Name);

    if (team == null || team.Members.Where(m => m.Id == userId).Count() == 0)
    {
        httpContext.Response.StatusCode = 403;
        ViewResult insufficientPermssions = new ViewResult();
        insufficientPermssions.ViewName = "InsufficientPermissions";
        filterContext.Result = insufficientPermssions;
    }
  }
}

同样, TeamTask 属性确保有问题的任务实际上属于团队。

Similarly, the TeamTask attribute ensures that the task in question actually belongs to the team.

这篇关于在多租户网站处理数据访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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