来源:JX8NET小游戏网 ACL/PermissionCode/NoNeed
JX8NET其中AuthType可以为:ACL/PermissionCode/NoNeed,需要仅登录可以再加上系统的[Authorize]。可以看到这个Controller里基本都是通用代码,所以实际上可以直接复制粘贴快速的创建资源Api,至于那个自定义的抽象类BaseController实现的功能:
- 从数据上下文中把对应的数据提取出来。JX8NET小游戏网
- 使用EmitMapper提供了数据模型和传输模型间的映射。
- InitVisibleSiteIds实现了调用租户模块提供的服务,查找TenantId对应的SiteIds。
- 调用Member模块,读取当前登录用户,用户信息。
- 提供Get、GetOne、Post、Put、Delete模板方法,如果需要可以深度集成Odata for WebApi,就可以使用Patch方法。
权限部分实现了RBAC和ACL两种权限方式,用RBAC来管理“谁能怎么操作哪些资源”这种权限,用ACL来管理“谁能怎么操作哪些数据”这种权限。权限模块可以同时应用于MVC和WebApi。实现的方式是自定义AuthorizeAttribute,来实现拦截,可以很容易拿到RBAC所需要的数据,而ACL就麻烦些了,总不能定死url吧,所以根据Sharepoint的启发设计了这种路由:
api/XXX/WebApiExt/ACL/Activity/{TenantId}/{AggregationId}/{SiteId}/{Id}?xxx
- “XXX/WebApiExt”是插件的命名空间。
- “ACL”代表这些Api需要采用ACL方式进行控制,写什么都可以没有强制定义,一般开放给资源管理者的Api都用ACL(后台),如果不用ACL的,比如开放给资源读取、动词类的Api,我们一般写成“Common”(前台),以示区分。
- 我设计的ACL的判断方式为:比对路由和实际访问路径的差异化部分再加上Http Method作为特征值和数据库存储的用户可访问列表进行比对,支持通配符。所以“{TenantId}/{AggregationId}/{SiteId}”是ACL实现的基础,就是租户模块。
资源A的实体字段里存储SiteId,而租户模块中存储着TenantId和SiteId的对应关系、AggregationId和SiteId的对应关系,AggregationId作为聚合租户内不同子站点的一种方式,甚至可以根据需要聚合不同租户下的数据,为系统提供了足够的灵活性。