【问题标题】:Setting WWW-Authenticate response header within a DelegatingHandler causes havoc on w2k3在 DelegatingHandler 中设置 WWW-Authenticate 响应标头会对 w2k3 造成严重破坏
【发布时间】:2013-06-03 15:02:31
【问题描述】:

我通过发送会话令牌来使用自定义身份验证机制。在 DelegatingHandler 中检查令牌的存在,该处理程序相应地设置当前主体。如果 principal 没有被授权调用 ApiController 方法,控制器会发送 401 Unauthorized 状态。由于 RFC 2616 要求在发送 401 响应时始终设置 WWW-Authenticate 标头,因此我的 DelegatingHandler 会处理此问题。

现在,在 Web API 自托管的场景中,应以 401 响应的请求在 Windows 7 上可以正常工作,但在 Windows Server 2003 上,它会因“远程主机强制关闭现有连接”异常而终止。此外,我注意到控制器方法中的断点在 W2k3 中被击中两次,而在 Win7 中则被击中两次,就好像 HttpClient 在收到 401 响应时以某种方式重试了请求。

当我取消注释带有 WWW-Authenticate 标头的行时,程序可以正常工作。请参阅下面的代码示例,了解控制台应用程序中的简约再现示例。

TestController.cs:

public class TestController : ApiController
{
    public HttpResponseMessage Get()
    {
        return Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "go away");
    }
}

AuthenticationHandler.cs:

public class AuthenticationHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        return base.SendAsync(request, cancellationToken).ContinueWith<HttpResponseMessage>(task =>
        {
            HttpResponseMessage response = task.Result;
            if ( response.StatusCode == HttpStatusCode.Unauthorized &&
                 !response.Headers.Contains("WWW-Authenticate") )
            {
                // comment out this line and the code works
                response.Headers.Add("WWW-Authenticate", "SessionToken");
            }
            return response;
        });
    }
}

Program.cs:

    static void Main(string[] args)
    {
        HttpSelfHostConfiguration config = new HttpSelfHostConfiguration("http://localhost:81");
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}"
        );
        config.MessageHandlers.Add(new AuthenticationHandler());

        using ( HttpSelfHostServer server = new HttpSelfHostServer(config) )
        using ( HttpClient client = new HttpClient() )
        {
            server.OpenAsync().Wait();

            try
            {
                HttpResponseMessage response = client.GetAsync("http://localhost:81/api/test").Result;
                Console.Out.WriteLine(response.StatusCode);
            }
            catch ( AggregateException ex )
            {
                Console.Out.WriteLine(ex.ToString());
            }

            server.CloseAsync().Wait();
        }

        Console.In.ReadLine();
    }

我是否正确调用 API?有什么想法可能是错的吗?

【问题讨论】:

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


    【解决方案1】:

    您需要安装 .net Framework 4.0.3。 .net 框架的早期版本无法设置 www-authenticate 标头。得到它here,关于这个问题的更多信息在KB2600211

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多