14

我正在使用 MVC4 编写一个 Web API,应该由多种客户端类型使用。我想使用 OpenID 进行身份验证。

我已经下载了 DotNetOpenAuth NuGet 包,但到目前为止,所有示例都是针对客户端应用程序,而不是 API。

我的问题很简单。我想让客户端向我的 API 发送身份验证请求。API 通过 OpenID 提供者进行身份验证。然后,API 设置它需要的任何内容,以便在整个 Web api 调用中使用 [Authorize] 标签。

我知道在 .NET 应用程序中可以调用 FormsAuthentication.SetCookie ,但这也是其他语言的易于实现的解决方案吗?

简而言之,这个问题。如何将 OpenID 集成到 MVC4 Web api 中,以允许使用可以被多种语言调用和使用的 Authorize 标签?

4

1 回答 1

24

您可能会混淆身份验证和授权的角色。听起来您的 Web API 需要两者

让我们从授权开始。每个 API(即由浏览器以外的客户端应用程序访问的 Web URL)要么允许匿名访问,要么必须经过授权(即授权)。授权是OAuth的域。OAuth(大概是 v2)描述了客户端如何授权对您的 WebAPI 的调用。

大概作为授权过程的一部分,用户登录到您的服务。登录用户的这一步就是认证。它与授权正交。您是否通过 OpenID、用户名/密码、X.509 证书等对用户进行身份验证,应该与您的 WebAPI 调用的授权方式无关。换句话说,您的 WebAPI 方法不应该关心用户是如何进行身份验证的(阅读:没有任何 OpenID 绑定)。他们将拥有一个应用于他们的授权过滤器,用于验证传入请求的授权并将其转换为一些信息,包括授权访问的帐户的用户名、访问级别、授权的 ID客户端等

所以一步一步,整个场景可能会是这样的:

  1. 操作第 3 方客户端应用程序的用户(为简单起见,我们假设此客户端应用程序是第 3 方 Web 应用程序)想要使用要求客户端以用户名访问您的 WebAPI 的功能。
  2. 当客户端调用您的 WebAPI 时,客户端需要获得有限模拟用户的授权。它们从 OAuth 2 重定向到您服务的授权端点开始。如果这是使用 DotNetOpenAuth 实现的,则可以使用WebServerClient类。
  3. 您的授权端点扮演 OAuth 2 授权服务器的角色,因此使用 DotNetOpenAuth 的AuthorizationServer类。它所做的第一件事是检查请求中是否包含 ASP.NET 表单身份验证 cookie。此 cookie 是用户是否已在其浏览器上登录您的服务的自然指示,如果已登录,该用户是谁。检查此 cookie 是对Controller.User的简单调用。请注意,您的授权端点是 MVC 而不是 WebAPI,因为它的响应是针对浏览器/用户,而不是客户端应用程序。让我们假设没有这样的 cookie 并且Controller.User为 null (或User.Identity.IsAuthenticatedis false)。有关如何实现此端点的信息,请参阅 OAuthAuthorizationServer 示例。
  4. 您的授权端点响应重定向到用户登录页面,包括redirectUrl查询字符串中的一个参数,该参数保留完整的传入 OAuth 2 授权请求 URL。
  5. 您的用户登录页面是充当 OpenID 依赖方的 MVC 端点。此端点使用 DotNetOpenAuth 的OpenIdRelyingParty类。请注意,此端点对 OAuth 2 或授权内容一无所知。它仅对用户进行身份验证。在对用户进行身份验证后,它会重定向回redirectUrl参数中的 URL。有关如何执行此操作,请参阅 OpenIdRelyingPartyMvc 示例。
  6. 授权端点重复之前的步骤,除了这次有一个 FormsAuthentication cookie,因此它继续向用户显示一个页面,询问他们是否要授权客户端访问用户的数据。用户单击是。(注意:在此用户授权页面上实施 XSRF 和点击劫持缓解措施)。
  7. 授权端点处理用户的肯定响应并调用AuthorizationServer以创建授权记录并将响应返回给客户端。此调用的结果之一是对客户端的重定向响应的制定,该响应为其提供授权代码。
  8. 浏览器现在正在拉取客户端应用程序的 URL,该 URL 向其传递授权代码。然后,客户端使用WebServerClient该类将授权代码交换为访问令牌(通常也是刷新令牌)。
  9. 客户端应用程序现在直接调用您的 WebAPI URL,包括它通过 HTTP 授权标头中的 OAuth 2 获得的访问令牌。
  10. 您的 WebAPI 充当 OAuth2 资源服务器的角色,并且您应用于 WebAPI 方法以验证传入 OAuth 2 访问令牌的授权过滤器属性使用 DotNetOpenAuth ResourceServer类来完成其工作。您可以参考 OAuthResourceServer 示例,或者更好的是David Christiansen 的 WebAPI 示例,了解如何执行此操作。

这就是整个故事。是的,无论他们碰巧使用何种语言或库,客户角色都很容易编写。

顺便说一句,我提到的 DotNetOpenAuth 示例不是通过 NuGet 分发的。您从 SourceForge 获得样本

于 2012-09-03T21:21:07.837 回答