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

时间:2016-08-23 19:19:11

标签: security authentication oauth adfs api-design

背景

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

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

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

问题

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

当前解决方案

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

  1. 直接来自JavaScript(首选解决方案)
  2. 通过MVC服务器路由请求,然后将其转发给API。
  3. 为了选择一种方法,我首先需要找到一种方法来保护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 个答案:

答案 0 :(得分:0)

  1. 是的,使用ADFS或任何IdP产品作为应用程序的IdP是实施SSO的好方法。这样做可以帮助您将所有联合访问管理以及声明规则委派给ADFS。
  2. 是的,您可以在会话中存储声明,并以某种方式将它们发送到WebAPI。请注意,如果您使用WIF,它已将Thread.CurrentPrincipal中的声明存储为ClaimsPrincipal对象。另一件事是我假设你只想以某种方式发送声明,而不是整个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/