【问题标题】:AngularJS, .NET Web API, and back-end authorization when returning views in a SPA在 SPA 中返回视图时的 AngularJS、.NET Web API 和后端授权
【发布时间】:2015-04-20 04:29:21
【问题描述】:

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

这些看起来合理吗?还是我只是疯了,我应该让 .NET MVC 处理返回的视图?

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

【问题讨论】:

  • bitoftech.net/2014/06/01/… 5 部分文章,涵盖 AngularJS 令牌身份验证与 ASP.Net 身份、CORS、OAUTH 刷新、外部登录等。
  • 我今天早些时候读过那篇文章。它没有解释当 Angular 在使用后端处理路由时如何防止未经授权的视图返回客户端。在此过程中绕过 MVC 和 Web API。我读到我需要将角色注入前端,这是不可能的。

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


【解决方案1】:

当您使用 AngularJs 开发 SPA 时,您可能会使用 angular-route 扩展。在这种情况下,您的视图只是数据的占位符。所以我想说你最关心的应该是数据(Web API)。您绝对应该为此使用一些身份验证。

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

【讨论】:

  • 我的一位同事确实建议通过 AJAX 返回一个部分,然后注入到布局中。但是,这是否比让 MVC 处理路由更有效?我的目标是在保持 SPA 的同时减少带宽消耗。
【解决方案2】:

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

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

如果您不通过 MVC 控制器提供模板,则需要一些替代方法来保护模板(例如 OWIN 中间件,是的。)

就个人而言,我建议使用 MVC 工具来获得纯粹的便利性和未来的持续支持。但是,如果您没有任何 MVC 控制器,OWIN 将是一个更合适的解决方案(例如,当所有逻辑发生在 SPA 和 API 之间时,不需要 MVC。)

为此:

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

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

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

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

TL:博士? 使用 MVC 控制器交付包含您的模板的 MVC 视图,并将 [Authorize] 属性应用于需要限制为授权/经过身份验证的用户的任何控制器或操作。为简单起见,考虑使用 MVC 视图来交付整个 SPA,并进一步考虑使用 MVC 部分视图来帮助组织标记,您应该有类似 ~/Home/Index 之类的东西,它不过是 Html.Partial 调用的集合(没有实际的标记。)

也就是说,现在您已经开始使用纯 OWIN 解决方案了。如果 SO 上尚不存在这种方法,我将在下周左右尝试使用纯 OWIN 方法进行更新。

希望对您有所帮助。

【讨论】:

  • Web API 和 MVC 都需要在应用程序中进行授权。然而,当 AngularJS 处理路由时,它不会命中任何一层。相反,当 Angular 处理路由时,服务器只是通过传递 MVC 和 Web API 授权来提供视图。
  • @AlexanderLi 在构建用于交付的 SPA(ASP.NET 路由和 MVC 控制器)时,您可能希望执行安全检查以包含/排除部分。不断联系服务器以授权访问已经交付给客户端的 SPA 内容似乎是不合适的,我永远不会在 Live 场景中这样做,它最终会无法扩展。
  • 我想我不明白。目前,MVC 正在处理所有路由。 Web API 处理发布到数据库。要求两者都进行身份验证和授权不是明智之举吗?
  • 是的。 :) 这正是我所说的,对不起,如果不清楚我试图重组我的答案。我还根据您对问题的更新更新了我的答案,并尝试解释一下我通常用于基于 ASP.NET MVC 的 SPA 的模式。
  • 在我的评论中,我明确指出“我永远不会做”是“不断联系服务器以授权访问已已经交付给客户端的 SPA 内容。”您“需要”执行的任何其他安全检查都应在您的 Web api 中完成,并且您的前端应实施以正确处理来自 XHR 的 401 错误(通常通过显示一个对话框让用户知道他们刚刚失败身份验证检查。)
猜你喜欢
  • 2018-10-05
  • 2014-10-08
  • 2020-11-13
  • 2018-11-19
  • 2017-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多