如何使用Breeze JS处理授权?

问题描述:

目前我的应用程序查看路由器参数并登录用户(Principal.Identity)来授权访问某些资源(例如:将学生添加到您的班级[标识+班级ID])。但是,如果我没有错,微风js只支持一次批量保存。这似乎是我将不得不打开每一个数据并通过验证/授权运行。这很好,如何使用Breeze JS处理授权?

但是我可能会失去的是交叉切割关心我的业务逻辑(作为消息处理程序)(找到用户对类的角色)和良好的Authroize注释功能(只是说需要什么样的角色)。所以我必须权衡一下,还是有更好的Breeze JS可能提出的编程模型?

更新: 我的问题是更多的关于如何分离授权(发现在消息处理程序分配的角色+验证,如果所需的角色是通过加入授权属性到控制器的方法)从业务或数据访问逻辑的逻辑。如果没有风,我会检查传入的消息及其路由参数,以获取其所有角色,然后在我的put/post/delete方法中使用所需的角色进行注释。我不能轻而易举地使用这种技术(它不是轻而易举的限制,当你进行批量保存时它的折衷)。所以想知道是否有任何编程模型或设计模式已被微风家伙使用。微风的样本上有一些重写上下文和使用存储库模式的东西,现在会遵循这一点。

Breeze可以根据需要拥有尽可能多的“保存”端点。例如,虚拟的服务器实现可能

[BreezeController] 
public class MyController : ApiController { 

    [HttpPost] 
    [Authorize(...)] 
    public SaveResult SaveCustomersAndOrders(JObject saveBundle) { 
    // CheckCustomersAndOrders would be a custom method that validates your data 
    ContextProvider.BeforeSaveEntitiesDelegate = CheckCustomerAndOrders; 
    return ContextProvider.SaveChanges(saveBundle); 
    } 

    [HttpPost] 
    [Authorize] 
    public SaveResult SaveSuppliersAndProducts(JObject saveBundle) { 
    ... 
    } 

你会叫这些端点这样

VAR所以=新SaveOptions({资源名称: “SaveWithFreight2”,标签: “运费更新”});

myEntityManager.saveChanges(customerAndOrderEntities, { 
    resourceName: "SaveCustomersAndOrder" } 
    ).then(...) 

myEntityManager.saveChanges(supplierAndProductEntities, { 
    resourceName: "SaveSuppliersAndProducts" } 
    ).then(...) 

授权经由每个的[HttpPost]方法[授权]属性介导。您可以在这里阅读更多关于[Authorize]属性的信息: http://sixgun.wordpress.com/2012/02/29/asp-net-web-api-basic-authentication/

+0

Thx为详细的答案。在我的情况下,我需要在授权消息处理程序的URL中提供所有可用角色的值,角色提取还取决于操作,如果更新/删除/添加,因为每个角色都有自己的角色,而客户端可能有一个角色不是其他(可以更新但不能添加/删除)。根据我的理解,我可能不得不根据EntityState获取角色,并在不使用[Authorize]属性的情况下手动验证它们。 –

但是,如果我没有错,微风js只支持一个批量保存。

这是完全错误的。你可以*创造你自己的保存方法。阅读文档,它就在那里。

做到这一点的正确方法是分离端点授权和数据库操作授权。

首先,创建一个管理每个控制器/方法和角色的实体。对于每种方法,您都有一个允许值 - 不允许用于特定角色。您可以创建一个特殊的属性(Authorize的子类),并将其应用于控制器(breeze或plain web api),该控制器读取数据并确定是否可以为用户/角色调用特定的端点。否则,它会抛出未经授权的异常。

在微风中端(客户端)您扩展与从您在登录时收到的,像这样的身份将认证报头的方法默认适配器设置:

VAR origAjaxCtor = breeze.config.getAdapterInstance( 'AJAX');

$ .extend(true,origAjaxCtor.defaultSettings,Security.getAuthenticationHeaders());

在服务器上,添加管理CRUD操作授权的第二个实体。您需要一个表(如EntityName,AllowInsert,AllowUpdate,AllowDelete)。在上下文管理器或ORM(EF或其他)上添加一个BeforeSave事件,该事件循环所有实体并应用上表中指定的策略。 通过这种方式,您可以将端点逻辑与后端CRUD逻辑清楚地分离。

在所有情况下,授权逻辑首先应该在服务器端实现,如果需要的话应该推送给客户端。

微风的实施方式和上述设计,你不应该需要超过1个保存端点。

希望它有帮助。

+0

我真的很想理解你的答案,因为我试图在微风应用程序中实现安全性。而且,我认为我了解'在服务器上'的部分。这是关于确保保存访问权限,并且我实施了类似于您所描述的内容。但是,我没有得到前面的部分。我想你正在描述如何根据角色限制对端点的访问。但问题是无限制的微风查询端点可能会传递请求(相关)受限数据的odata查询(来自恶意客户端)。我如何防止这种情况发生? – steve

+0

应限制所有端点。授权属性应该应用于基础控制器(我强烈建议您有一个基类)。通过这种方式,所有端点都将得到保护。我今天晚些时候会发布一些代码来展示它如何实现 –

+0

我们在控制器类上使用了authorize属性。我对'限制'和'不受限制'的使用是WRT基于角色的访问。 – steve