【问题标题】:Differentiate between the first request (authentication) and subsequent requests (also authentication)区分第一个请求(身份验证)和后续请求(也是身份验证)
【发布时间】:2014-02-10 22:41:13
【问题描述】:

使用基本身份验证,我在身份验证处理程序中执行此操作:

protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
    var authHeader = request.Headers.Authorization;
    if (authHeader == null || authHeader.Scheme != BasicScheme)
    {
        return CreateUnauthorizedResponse();
    }

    // Now authenticate the user with his name+pw

    // Return Auth token to user

}

每次这意味着第一个请求或所有后续请求,用户请求都将通过上述 SendAsnyc 方法。在上述方法中,我应该如何区分用户是第一次验证自己(使用用户名+密码)还是继续验证自己(让服务器生成身份验证令牌)?

【问题讨论】:

  • 您在说什么“服务器生成的身份验证令牌”? HTTP Basic Auth. 中没有这样的东西
  • 我知道...但是您如何在登录表单之后验证后续请求?将用户+密码存储在客户端并为每个请求发送?希望不会。
  • 每个浏览器都是这样操作的……如果你不喜欢这样,不要使用基本的,而是消化的。
  • @CBroe ...仅当浏览器窗口打开时,凭据就会随 http 请求一起重新发送。当浏览器关闭并重新打开时,用户不想再次登录,因此是令牌。

标签: authentication asp.net-web-api token basic-authentication


【解决方案1】:

您可以使用授权方案来区分。当用户发送用户名/密码时,请使用“基本”身份验证方案。发送令牌时,使用“承载”身份验证方案。

【讨论】:

  • 我更喜欢这种方法:strathweb.com/2013/08/… 仅将 AuthHandler 插入不是身份验证路由的路由上。此处显示:codeproject.com/Articles/630986/…
  • @Pascal 我看到这种方法的唯一问题是,如果您共享指向受保护资源的链接,那么收件人将获得 401 和 www-authenticate: Bearer。他们如何知道如何对自己进行身份验证并获得不记名令牌以访问资源?您需要重定向到具有基本方案的资源,然后在它们拥有不记名令牌后将它们重定向回受保护的资源。
  • @Pascal 通过在所有资源上支持两种身份验证方案,承载令牌就成为了一种性能增强机制。
  • 致您的第一条评论:对于我的项目,每个人都有自己的帐户和自己的数据。共享链接没有意义。因为通过操作 URL,您可以获得我无论如何都禁止的其他数据...并且我粘贴的链接只是每个路由的 messageHandler 的示例等... :-) A 但是感谢您的关注。
  • 对您的第二条评论:这是积极的意思吗?不确定我是否理解正确。
【解决方案2】:

两个选项。

(1) 假设在成功验证用户名/密码后从服务器发回的令牌在 Authorization 标头中发送给后续请求(在不同的方案中),重新排列你的逻辑,以便你寻找授权标头中的基本方案,如果存在,则进行身份验证并发回令牌。如果具有基本方案的 authz 标头不存在,但您的方案或承载方案(无论是什么)存在,则假设它是令牌并进行身份验证。如果 authz 标头不存在或基本方案中的凭据无效或其他方案中的令牌无效,则发送 401。

(2) 更改消息处理程序,使其仅进行基本方案身份验证。如果标头不存在或无效凭据或存在,它将不会在request.GetRequestContext().Principal 中设置正确的主体,但不会发回 401。引入另一个将执行令牌身份验证的消息处理程序。仅当请求中存在令牌并且令牌有效时,此处理程序才设置正确的主体。同样,此处理程序不会发回 401。最后,在操作方法、控制器甚至全局应用 Authorize 过滤器。如果两个消息处理程序都没有建立经过身份验证的身份,过滤器会将响应状态设置为 401。

我更喜欢第二个,因为处理程序只负责身份验证。顺便说一句,一般不建议使用消息处理程序进行身份验证。一旦执行回到 IIS 管道(假设您使用 IIS),您在此处建立的身份将被恢复。

【讨论】:

  • 我找到了这个示例代码:codeproject.com/Articles/630986/… 作者留下了那条评论:" //只需排除用户控制器不需要提供有效令牌,这样他们就可以进行身份​​验证 "这是缺少的部分我的头巴德里。我想知道您没有提到这种方法(请参阅注册方法)。您写道:“它只是不会在 request.GetRequestContext().Principal 中设置正确的主体,但不会发回 401”这对我来说毫无意义,必须有语法?
  • 您让过滤器返回 401 的方法对我来说似乎是新的,从未听说过,但很有趣!一般不推荐使用message handler做auth ???但是每个人都在这样做,并且所有样本都显示了它;-) 说真的,为什么不呢?您的意思是在响应开始时将删除身份/主体?是的,我使用 IIS。
  • 关于消息处理器的话题,在消息处理器中建立身份并查看IIS日志。它不会记录用户,因为身份会恢复。查看asp.net/web-api/overview/security/… 中的“用于身份验证的HTTP 消息处理程序”部分。是的,每个人都在这样做,甚至我的书 Pro ASP.NET Web API 安全性也广泛使用消息处理程序,但是如果您很高兴将您的安全机制仅与 Web API 管道隔离,那么消息处理程序就可以了。如果是网络托管,请考虑使用 HTTP 模块或 OWIN 中间件。
  • 正如您所做的最详细的描述(但类似于 Darrel 的方法,您有解决方案。顺便说一句。我现在在带有 topshelf 的 Windows 服务中运行 Owin ;-)
  • 关于您的选项 2) “最后,在操作方法、控制器甚至全局应用授权过滤器。如果两个消息处理程序均未建立经过身份验证的身份,过滤器会将响应状态设置为 401。”微软甚至建议您这样做,但是您如何能够返回一条单独的错误消息,告诉用户 401 的原因是什么?我认为这行不通。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-15
  • 1970-01-01
  • 1970-01-01
  • 2016-09-29
  • 2013-10-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多