在早期的管道阶段停止身份验证 - 除非进入/登录?

时间:2014-11-02 17:19:37

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

我正在编写MessageHandler来验证用户身份。

如果请求包含特殊标头,我想在MessageHandler阶段阻止它。

但是如果用户想要转到Users/Login方法,他可能没有标题(因为他还没有登录)。

问题在于我不想在[authorize]控制器级别阻止他。

这很简单:

  • 如果他没有标题并且他不在登录的路上 - BLOCK
  • 如果他没有标题并且他正在登录的路上 - 只有那时 - 允许

问题

  • 1)在MessaageHandler阶段,我怎么知道他正在登录? (注意:我没有提及路线中的{action}。例如:

-

 public class User :ApiController
 { 
   [HttpPost]
   public bool CheckLogin (....) //i'm not specifying action in the route
    {
    }
}
  • 2)查看读取标题的命令:

AuthenticationHeaderValue auth = actionContext.Request.Headers.Authorization;

但是 - 授权!=身份验证

那么为什么web api将授权标头引用为身份验证?

2 个答案:

答案 0 :(得分:3)

MessageHandler在路由发生之前执行。所以在这个阶段你还不知道将执行哪个控制器动作。

一种可能性是检查动词和所请求的路径,并根据以下内容执行自定义验证:

protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
    string path = request.RequestUri.PathAndQuery;
    if (request.Method == HttpMethod.Post && path.StartsWith("/api/checklogin", StringComparison.InvariantCultureIgnoreCase))
    {
        // Do not enforce the presence of the custom header
        return base.SendAsync(request, cancellationToken);
    }

    // Check for the presence of your custom header
}
  

那么为什么web api将授权标头引用为身份验证?

在HTTP级别,标头名为Authorization

答案 1 :(得分:1)

  1. 我相信你正在尝试重新发明它已经存在的轮子。您有AutorizeAllowAnonymous(针对您的Login操作),然后您可以使用自定义身份验证过滤器来读取标头并为请求生命周期设置Principal

  2. 原因是术语授权标头始终在基于HTTP标头的身份验证的上下文中使用。第一次使用这个燕鸥的人可能不知道身份验证标题可能稍微合适一些。

相关问题