验证站点/应用程序以访问 Web API 服务

Posted

技术标签:

【中文标题】验证站点/应用程序以访问 Web API 服务【英文标题】:Authenticate a site/app to access a Web API Service 【发布时间】:2014-07-06 06:07:51 【问题描述】:

简短的问题: 我有一个 .NET 中的 Web API 服务,以及一个仅使用 html 和 AngularJS 制作的站点。

如何才能只授权我的网站使用我的服务?


我正在寻找一个安全的答案来解决一个似乎很常见但并不常见的问题。最近看了很多答案、想法和各种东西,但我找不到解决办法。

假设我有一个来自 MS 的 Web Api 服务(最新的)。 所以我必须使用需要消耗它的应用程序。让我们定义两个场景。

场景 1:

在同一个 IIS 中,我有一个 ASP.NET MVC 3/4,其特殊性在于所有 MVC 工作都在客户端,由 AngularJS 制作,因此应用程序直接从 javascript 指向 Web Api 服务。

场景 2:

我有一个直接指向 Web Api 服务的第三方应用程序,并且位于其他网络/站点/除相关之外的任何位置。

所以,我的问题是:

如何对两个系统进行身份验证,以便 Web Api 服务提供对两个系统的访问权限(我不在乎是否相同),而不是向拥有 REST 客户端的人提供访问权限,并使用用户/通行证授权登录到该站点?我希望这两个例子都能说明我感兴趣的观点。

请在下方评论您需要以更好的方式改进此问题的任何内容!

顺便说一句,不,不能使用混淆。 我想了一个类似令人耳目一新的令牌,但我想不通。

【问题讨论】:

【参考方案1】:

我将如何使用您的场景 1 设置身份验证:

我将强制静态文件通过服务器以确保身份验证

Web.config

<compilation>
    <buildProviders>
        <add extension=".html" type="System.Web.Compilation.PageBuildProvider" />
        <add extension=".htm" type="System.Web.Compilation.PageBuildProvider" />
    </buildProviders>
</compilation>

<system.webServer>
     <handlers>
         <add name="HTML" path="*.html" verb="GET, HEAD, POST, DEBUG"   type="System.Web.UI.PageHandlerFactory" resourceType="Unspecified" requireAccess="Script" />
         <add name="HTM" path="*.htm" verb="GET, HEAD, POST, DEBUG" type="System.Web.UI.PageHandlerFactory" resourceType="Unspecified" requireAccess="Script" />
     </handlers>
</system.webServer>

这将允许我在我的 web.config 中设置 &lt;authentication&gt;&lt;authorization&gt;,例如:

<authorization>
  <allow roles="demo" />
</authorization>

 <authorization>
   <deny users="?" />
 </authorization>

另外我将设置我的登录页面:

<authentication mode="Forms">
      <forms  path="/" loginUrl="~/login"..

对于场景 2

您可能需要启用 CORS,如果是这种情况,您需要:

Register 方法中设置配置选项config.EnableCors();;您还需要通过使用 [EnableCors] 属性以及控制器的声明在 ApiController 中启用 CORS,这是一个示例:

 [EnableCors(origins: "http://localhost:49595", headers: "*", methods: "*")]
 public class ValuesController : ApiController
 
 ...

最后,为了保护 WebApi,我们需要在控制器中使用属性 [Authorize],并且您很可能需要定义自定义身份验证方法来授权您的第二个调用者。您可以按照以下步骤操作:

How to set up WebApi Custom Authorization

【讨论】:

天啊,这是一个功能性的答案!我需要几个小时来学习和尝试这个!非常感谢!这就是我一直在寻找的答案 是否允许所有经过身份验证的用户而不是基于角色的用户? @Purushoth 只需将其更改为 &lt;deny users="?" /&gt; 其中? 表示未知或未经身份验证 @Purushoth 如果您支持这个答案并投赞成票会很好 嗨@Dalorzo,我想授权视频文件夹中的视频,当我这样使用时, 我仍然可以访问视频,它仅适用于我提供内容/视频时尝试重定向到登录页面。当我在 url 中提供这样的 Content/videos/bigbugbunny.mp4 时,可以访问视频。【参考方案2】:

不完全是问题的答案,但我想说的太长了,无法发表评论,所以...

有various ways to secure a RESTful service,但是如果要限制访问主要有两种方法:

仅从内部网络或通过某种 *** 使用服务(即控制访问服务的环境并仅允许从某些特定来源进行访问); 将服务公开,但随后让应用程序或服务器丢弃任何不满足某些要求的请求(即未经过身份验证、缺少令牌、签名错误等)。

根据您的操作,上述方法均无效。

您想要的(正如我从您的问题中了解到的那样)是将访问您服务的客户端限制为两个。在我的脑海中,我只能想到带有mutual authentication 的HTTPS。您使用客户端证书来验证客户端。 IIS 将处理连接,因此如果您的客户端在不提供证书的情况下提出请求,则请求将被拒绝。除非拥有您提供的客户端证书,否则任何人都无法访问您的服务。

因此,问题是为每个客户颁发一个证书。这适用于第三方应用程序,但由于浏览器直接访问您的 API,因此可能无法实现。这意味着您需要为访问您的 MVC 应用程序的每个浏览器安装证书,或者将访问权限转移到 MVC 服务器端的 API,并且不再直接从 AngularJS 调用它。如果你能做到其中任何一个都很好,否则就回到绘图板......

希望这会有所帮助!如果您找到合适的解决方案,请将其作为答案发布在 SO 上。

【讨论】:

谢谢博格丹,它有很大帮助,甚至您的 5 项答案的链接。最后一个想法是我们需要跳转到 ASP.NET 并直接与 $http 到 AngularJS 连接。但是 HTTPS 相互认证确实是一个很好的提示。

以上是关于验证站点/应用程序以访问 Web API 服务的主要内容,如果未能解决你的问题,请参考以下文章

Web API接口 安全验证

无法验证从 Azure AD 获得的访问令牌签名以保护 Web API

Intranet API 的 REST 身份验证缓存

Restful Web API 安全性

利用CA证书配置安全Web站点

Google OAuth2 服务帐户 API 授权