如何在使用者使用声明身份验证时保护 API



Background

我正在构建一个 .NET MVC 企业 Web 应用程序,该应用程序必须能够对来自不同公司的用户进行身份验证。主要要求之一是确保用户无需创建和记住新凭据即可使用应用程序,而是应继续使用用于访问公司 Intranet 内应用程序的任何凭据。

由于应用程序将托管在 Extranet 上,并且需要处理针对多个域(即多个 Active Directory(进行身份验证,因此我们希望每个客户端都设置一个安全令牌服务 (AD FS(,应用程序可以与之交互以实现声明身份验证。

MVC 应用程序将检查用户是否已通过身份验证,如果没有,则启动工作流,该工作流以 MVC 应用程序获得与用户关联的 SAML 声明结束。

问题

此时,用户已经过身份验证并被授予对 MVC 应用程序的访问权限。但是,应用程序本身是一个现代的 Web 应用程序,它使用相当多的 JavaScript 来使用处理大多数业务逻辑的 .NET Web API。我的主要问题是如何保护这个 API。我想确保发送到此服务器的唯一请求是从有效源发送的,并且使用该服务的用户有权这样做。

当前解决方案

我可以采用两种方法来使用 API:

  1. 直接来自JavaScript(首选解决方案(
  2. 通过 MVC 服务器路由请求,然后 MVC 服务器将其转发到 API。

为了选择一种方法,我首先需要找到一种方法来保护 API。

HMAC 身份验证

我发现的最直接的解决方案是HMAC身份验证 - http://bitoftech.net/2014/12/15/secure-asp-net-web-api-using-api-key-authentication-hmac-authentication/。但是,此方法要求所有 API 请求直接来自 MVC 服务器,因为密钥需要位于 MVC 服务器上。

OAuth 2.0

我可以实现的第二种方法是OAuth 2.0的某种风格。我熟悉的口味可以在这里找到 http://alexbilbie.com/guide-to-oauth-2-grants/:

  • 授权码
  • 含蓄
  • 资源所有者凭据
  • 客户端凭据

授权代码授予

这不是我想采取的方法。MVC 应用程序已经收到了用户的声明 - 他们不应该仅仅因为 API 需要声明而再次执行此操作。(我有一个后续问题,询问我是否可以简单地将声明传递给 API 服务器(

隐式授予

我喜欢这种方法听起来的方式,因为我将能够在客户端中执行 API 请求(即 JavaScript 代码(,但它遇到了与第一种方法相同的问题。

资源所有者凭据授予

这种方法是不可能的 - 我不希望 MVC 应用程序或 API 保留用户的凭据。

客户端凭据授予

这种方法是唯一合理的OAuth方法 - 但是我没有看到这种方法与上面详述的HMAC身份验证之间的主要区别。

问题

  1. 我是否正确设置 MVC 应用程序的身份验证结构?具体而言,在此上下文中,是否适合让 AD FS 处理身份验证并使用表示用户声明的 SAML 令牌进行响应?
  2. 我计划将用户数据存储在服务器的会话中。我是否还可以将用户的声明存储在会话中,然后以某种方式将其发送到 API 进行身份验证?
  3. 如果我可以将声明从 MVC 服务器传递到 API 服务器,并且 API 服务器可以正确验证请求,那么将声明传递给客户端(浏览器/JS 代码(以便使用 API 可以绕过 MVC 服务器是否安全?
  4. HMAC 身份验证方法是最佳方法吗?
  1. 是的,使用 ADFS 或任何 IdP 产品作为应用程序的 IdP 是实施 SSO 的好方法。这样做有助于将所有联合访问管理以及声明规则委托给 ADFS。
  2. 是的,您可以将声明存储在会话中,并以某种方式将它们发送到 WebAPI。请注意,如果您使用的是 WIF,它已将声明作为 ClaimsPrincipal 对象存储在 Thread.CurrentPrincipal 中。另一件事是,我假设您只想以某种方式发送声明,而不是整个 SAML2 令牌。
  3. 我会说它与您用于在客户端保护令牌的机制一样安全。查看 https://auth0.com/blog/ten-things-you-should-know-about-tokens-and-cookies/和 https://security.stackexchange.com/questions/80727/best-place-to-store-authentication-tokens-client-side 了解更多详情。
  4. 我不能说它是否最适合你,但这似乎是一种可行的方法,因为你也可以控制 WebAPI。但是,使用JWT令牌似乎也更容易:https://vosseburchttechblog.azurewebsites.net/index.php/2015/09/19/generating-and-consuming-json-web-tokens-with-net/。谈到JWT代币,你也可以要求ADFS为你发行:https://blogs.technet.microsoft.com/maheshu/2015/05/26/json-web-token-jwt-support-in-adfs/。

最新更新