在SPA中返回视图时的AngularJS,.NET Web API和后端授权

时间:2015-02-18 23:33:08

标签: angularjs asp.net-mvc asp.net-web-api owin owin-middleware

所以我想使用AngularJS和.NET Web API编写SPA。我希望Angular能够处理大部分路由。但是,如何防止未经授权的用户(无论身份验证)获取某些视图?我想在后端执行此操作,而不涉及.NET MVC,因为MVC返回整个视图,这违背了SPA的目的。同样根据我的理解,Web API在向客户端返回视图方面没有任何作用。鉴于这是正确的,当返回请求的视图时,Web API和MVC中的授权在SPA中变得无用。我考虑编写一些OWIN中间件来检查传入的AJAX调用的标头,然后确定用户是否有权接收视图。但我不知道从哪里开始。如果编写OWIN中间件来处理授权是切合实际的,我该从哪里开始?

这有什么看似合理吗?或者我只是疯了,我应该让.NET MVC处理返回视图?

跟进:MVC和Web API都有[授权]装饰,并且正在传递令牌。身份验证很好。问题在于Angular。当Angular处理路由时,它会从服务器请求一个视图。但是服务器不会进入.NET MVC或Web API,而是绕过MVC和Web API中的授权。它只是回馈了视图。有前端授权,但这不是理想的。因此,当用户被授权接收该视图时,我需要后端处理返回视图。

2 个答案:

答案 0 :(得分:3)

有保护“Web API”的有效案例,您不应放弃Web API的基本授权(因为即使没有View,恶意用户仍然可以访问API。)因此,您最终希望授权访问前端视图和后端API。

但是,为防止用户获得对特定模板的访问权限,您需要在“MVC控制器”或“操作方法”上应用Authorize属性,以保护为您的模板提供服务。听起来好像您的客户端框架直接从Web服务器获取文件(而不是激活MVC Controller Action来接收View。)

如果您没有通过MVC控制器提供模板,则需要一些其他方法来保护模板(例如OWIN Middleware,是的。)

就个人而言,我建议使用MVC设施,以便将来提供便利和持续的支持。但是,如果您没有任何MVC控制器,OWIN将是更合适的解决方案(例如,当SPA和API之间出现所有逻辑时,不需要MVC。)

为此目的:

当我使用knockout或angular创建单页应用程序(SPA)时,我通常会将所有模板移动到partials中。然后我使用MVC视图和控制器动作来传递这些部分。

这允许我授权访问我的模板。这也允许我基于服务器端知识来修改发出的模板内容,无论是安全性还是其他数据。例如,我有时会使用User.IsInRole()根据用户角色在模板中包含/排除内容(例如,发布一个模板,为管理员用户提供管理员操作,并为常规用户发送相同的模板但没有管理员操作。 )

根据SPA的大小和复杂程度,我通常在单页加载(单个MVC视图)中提供整个SPI。这与假设模板来自服务器的模板不兼容(而不是说, ,当前DOM中的一个元素,但它为用户提供了非常快捷的体验,根据我的经验,相当复杂的SPA的大小仍然比一些最常见的JavaScript框架小。

如果应用程序的复杂性或SLA要求它,我可以批量交付SPA的部分(多个MVC视图,作为常规应用程序导航的一部分按需拉入浏览器)。例如,〜/ Home / Index本身可以提供整个应用程序中使用的所有共享模板,但是〜/ Account / Index可以提供帐户管理视图,并且〜/ Uploader / Index可以提供资产上载视图。我实际上不需要将这些额外的帐户和上传者模板添加到应用程序中,除非我打算使用这些功能。

TL:DR? 使用MVC控制器提供包含模板的MVC视图,并将[Authorize]属性应用于需要限制为授权/验证用户的任何控制器或操作。为了简单起见,考虑使用MVC View来提供整个SPA,并进一步考虑使用MVC部分视图来帮助组织标记,你应该有〜/ Home / Index之类的东西,它只是{{1}的集合。 }调用(没有实际标记。)

那就是说,现在你已经开始使用纯粹的OWIN解决方案了。如果SO上还没有一个纯粹的OWIN方法,我将在接下来的一周左右尝试更新。

希望有所帮助。

答案 1 :(得分:0)

当您使用AngularJs开发SPA时,您可能使用角度路径扩展。在这种情况下,您的视图只是数据的占位符。所以我要说你最关心的应该是数据(Web API)。你肯定应该使用一些身份验证。

对于需要一些非常具体的auth的其他视图,您仍然可以将ASP.NET MVC与AngularJs结合使用。我认为MVC部分是一个很好的解决方案。您可以从角度控制器返回渲染的局部视图。当然,您可以使用Ajax请求它。