【问题标题】:Is it possible to expose multiple endpoints using the same WebAPI controller?是否可以使用同一个 WebAPI 控制器公开多个端点?
【发布时间】:2013-09-21 18:38:23
【问题描述】:

我想创建一个 WebAPI 服务以在我的单页应用程序中使用,但我也希望它也可用于移动应用程序。

当用户使用 SPA 时,他们使用表单身份验证登录并拥有会话 cookie,但如果他们使用的是移动应用程序,则情况并非如此。

是否可以将同一个 API 控制器公开为 2 个不同的端点,其中一个使用相互 SSL、令牌或作为最后手段的基本身份验证进行身份验证,而另一个使用会话 cookie?

以如下控制器为例:

public class TodoController : 
{
    public IQueryable<TodoModel> GetTodos()
    {
        ...
    }
}

我可以添加多个映射到同一个方法的路由吗?

https://myapp.example.org/api/todo
https://myapp.example.org/mutual-auth/api/todo 

我想将 IIS 配置为对相互身份验证端点使用相互 SSL,对另一个端点使用表单身份验证。

【问题讨论】:

  • 我显然没有很好地解释自己,我会编辑再试一次。

标签: asp.net-web-api


【解决方案1】:

简短回答:

这是一个非常广泛的问题,因此我不会对每个方面进行过多的详细介绍。我认为您还应该看看BreezeJS,因为它使构建这些应用程序的事情变得更加容易。

设计

您想构建纯 HTML 和 JavaScript 还是合并 CSHTML?决定权在你手中,但如果你想最终使用 PhoneGap Build 之类的东西创建基于本机的应用程序,你需要坚持使用纯 HTML 和 JavaScript,以便以后编译代码。

您想在设计控制器时使用其他 JS 库(例如 BreezeJS)让生活更轻松吗?开箱即用,您的 Web API 控制器将在 WebApiConfig 中以 api/{controller}/{id} 为前缀。如果您不使用 BreezeJS 之类的东西,您可能需要添加 {action} 路由,以便您可以更灵活地使用控制器。

最后,我们来谈谈存储库模式和工作单元模式。这是一个热门话题,但我发现通常创建存储库可以为您提供很大的灵活性,并且非常适合依赖注入。向控制器添加额外的存储库层可以让您非常轻松地区分不同的用户或访问方式,例如 SPA 或移动应用程序。您可以使用完全相同的控制器,但只需从不同的存储库中提取。

安全

您需要对[Authorize][ValidateHttpAntiForgeryTokenAttribute][Roles("")] 和其他几个数据注释进行一些修改,以供初学者使用。这是一个巨大的话题,有大量的在线阅读材料——投资一些研究。您的控制器可以有多个具有不同限制的操作,例如阻止 SPA 上的 CSRF,但通过在控制器上使用不同的操作或从单独的存储库中提取来减少对移动设备的限制。

我可以添加多个映射到同一个方法的路由吗?

https://myapp.example.org/api/todo

https://myapp.example.org/mutual-auth/api/todo

是的,当然。您只需要对路由配置文件做一些额外的工作。使用 BreezeJS,您不仅可以访问 /api/,还可以访问 /~breeze/,它们的工作方式非常相似。

【讨论】:

  • 作为一个无耻的插件,请查看github.com/ehotinger/RequireAdditionalPylons,这是我在这篇文章中提到的一些技术的一个示例,以及一个非常原始(无安全性)的模板,它可以让你开始正确的方向。
  • 这是关于存储库的一个有趣点,你是说注入一个存储库“工厂”然后我可以使用它来根据登录用户改变行为吗?
  • 是的,您可以根据登录用户轻松更改它,因为您可以访问存储库中的 Context 的 IPrincipal。您甚至可以创建不同的过滤器来打开不同的东西,例如 cookie 等。
【解决方案2】:

假设您在 IIS 中托管 Web API,如果您启用表单身份验证,FormsAuthenticationModule 将建立身份。也就是说,如果您在成功验证后查看HttpContext.Current.UserThread.CurrentPrincipal,则IPrincipal 类型的对象将具有标识(即FormsIdentity)并且IsAuthenticated 属性将设置为true。您可以使用自定义 DelegatingHandler 对任何其他凭据执行相同的操作。您需要做的就是验证凭证(HTTP 授权标头中基本方案中的令牌、用户 ID 和密码等),并将HttpContext.Current.UserThread.CurrentPrincipal 设置为GenericPrincipal 类型的对象GenericIdentity。在此之后,用Authorize 装饰的控制器的相同操作方法将适用于两种类型的请求。

【讨论】:

    【解决方案3】:

    您可以使用您想要的方式保护您的 Web API。例如,您可以提供自定义Message Handler 或自定义Authorization Filter 以通过令牌提供外部身份验证。

    ASP.NET 团队有一个完整的会议涵盖了这一点,您只需选择要选择的:

    Security issues for Web API.

    【讨论】:

      猜你喜欢
      • 2017-10-13
      • 1970-01-01
      • 1970-01-01
      • 2013-09-19
      • 2016-03-14
      • 1970-01-01
      • 1970-01-01
      • 2013-08-11
      • 1970-01-01
      相关资源
      最近更新 更多