HttpResponseMessage,取消授权状态代码和内容//响应,无需WWW-Authenticate标头字段

时间:2015-05-01 05:46:11

标签: c# asp.net .net asp.net-mvc asp.net-web-api

使用ASP.NET Web API 2,如果我想返回带有未授权状态代码的HttpResponseMessage,我会得到不同的响应头 - 有或没有WWW-Authenticate头字段 - 取决于此响应消息是否包含内容或不

根据Status Code Definitions,WWW-Authenticate标头字段是未授权响应的必填字段。

响应中缺少WWW-Authenticate头字段会导致下一个请求出错。

要查看问题,您可以创建新的Web API项目并添加一个简单的测试控制器:

public class TestController : ApiController
{
    public HttpResponseMessage Get()
    {
        var responseMessage = new HttpResponseMessage(HttpStatusCode.Unauthorized)
        {
            // Content = new StringContent("You are not authorized"),
        };

        return responseMessage;
    }
}

如果回复消息没有内容,我们将获得正常的401响应: enter image description here

回复:

HTTP/1.1 401 Unauthorized
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
WWW-Authenticate: Bearer
X-SourceFiles: =?UTF-8?B?RDpcUHJvamVjdHNcVGVzdEFwaVxUZXN0QXBpXGFwaVxUZXN0?=
X-Powered-By: ASP.NET
Date: Fri, 01 May 2015 05:31:20 GMT
Content-Length: 0

如果我们向响应消息添加内容(取消注释内容行),则每个第二个响应将不是401,而是500

enter image description here

401的回复将包含以下标题:

HTTP/1.1 401 Unauthorized
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 22
Content-Type: text/plain; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RDpcUHJvamVjdHNcVGVzdEFwaVxUZXN0QXBpXGFwaVxUZXN0?=
X-Powered-By: ASP.NET
Date: Fri, 01 May 2015 05:34:38 GMT

You are not authorized

500的回复会说

Server cannot append header after HTTP headers have been sent.
Description: an unhandled exception occurred during the execution of the current web request.Please review the stack trace for more information about the error and  where it originated in the code..... Exception Details: System.Web.HttpException: Server cannot append header after HTTP headers have been sent.

所以它看起来好像是因为以前的回复是非法的 - 它们不包含WWW-Authenticate头属性。

但即使我尝试手动添加WWW-Authenticate

,它也无济于事
public class TestController : ApiController
    {
        public HttpResponseMessage Get()
        {
            var responseMessage = new HttpResponseMessage(HttpStatusCode.Unauthorized)
            {
                Content = new StringContent("You are not authorized"),
            };

            responseMessage.Headers.Add("WWW-Authenticate", "Bearer");

            return responseMessage;
        }
    }

现在它在回复中

HTTP/1.1 401 Unauthorized
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 22
Content-Type: text/plain; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
WWW-Authenticate: Bearer
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RDpcUHJvamVjdHNcVGVzdEFwaVxUZXN0QXBpXGFwaVxUZXN0?=
X-Powered-By: ASP.NET
Date: Fri, 01 May 2015 05:43:51 GMT

You are not authorized

但我仍然有每秒请求500而不是401。

任何人都可以澄清这里发生了什么,以及如何让它正常工作?

1 个答案:

答案 0 :(得分:0)

来自响应500的Server cannot append header after HTTP headers have been sent.错误消息是由一个模块尝试在执行操作后将http标头写入响应流引起的 - 因为您的操作已经写入了标题和正文。

常见的罪魁祸首是 FormsAuthentication Owin Cookie身份验证,并尝试将302替换为302(重定向到登录页面)。< / p>

<强>情境:
1.执行您的操作 - 向标头集合添加标头401 Unauthorized,并将标头写入响应流,然后将主体(您未经授权)写入响应流。 /> 2. FormsAuthenticationModule在响应头集合中看到401 Unauthorized标头,并尝试将其更改为302 Redirect to login page,并尝试将相应的标头写入响应流 - 由于Server cannot append header after HTTP headers have been sent.而失败。标题已经写好了。

可能的解决方法:

1)如果 FormsAuthenticationModule 在您的请求管道中

  • 如果您不使用它,请考虑禁用它
  • 在.net 4.5中,您可以通过将HttpResponse.SuppressFormsAuthenticationRedirect属性设置为 false
  • 来禁止表单身份验证重定向
  • 如果不是.net 4.5,请考虑使用HttpModule来抑制此重定向

Phil Haack blogged on all the above options

2)如果使用 OWIN Cookie身份验证 - 请考虑not setting LoginPath property