是什么原因导致“ HTTP状态401:确定”

问题描述 投票:3回答:4

我有一个ASP.NET Web服务,当我偶尔调用它时,它返回正确的响应,而其他时候它返回异常The request failed with HTTP status 401: OK.有人可以向我提供某些发生这种情况的原因吗?由于200正常且401未经授权,我似乎无法在HTTP 401和OK消息中找到任何内容...为什么托管在IIS6中的Web服务将返回此消息?

这里是直接的异常详细信息:

Message:
    The request failed with HTTP status 401: OK.
Stack Trace:
    at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
    at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
    at ws.Main.MethodName(param1, param2)

提供此错误后,我将尝试获取此错误的WireShark数据包跟踪。

客户端和Web服务都是我们维护的代码。异常仅是间歇性发生,并非总是如此,传递的凭据详细信息是帐户的有效AD用户详细信息,并且IIS站点正在使用Windows身份验证。

.net asp.net web-services http-status-codes
4个回答
3
投票

我已经找到原因并找到答案。

问题是由多个线程通过同一TCP管道同时访问WebService引起的。这导致IIS重置身份验证握手,结果应用程序收到HTTP 401 UNAUTHORIZED异常代替200 OK消息,.NET报告响应为HTTP 401 OK,但是使用WireShark,我能够确定内容仍为HTTP 401 UNAUTHORIZED

由于问题的多线程性质,我们使其间歇性地发生。

解决方案是编写一个新的代理类,该类包含我们自动生成的ws代理类(来自WSDL),并在此新代理类中的每个方法上实现SYNCLOCK对象。

[当我使用服务器名称而不是DNS名称时,问题似乎也消失了,因为每个单独的线程调用都在不同的TCP管道上进行。


1
投票

401未经授权

类似于403禁止,但专门用于身份验证时使用可能,但是失败或尚未提供。

这意味着您没有试图访问的资源的权限,并且进行身份验证可能会有所不同。我不认为OK是相对的,尽管这很不寻常。确认actual Http Status code in Fiddler

相反:

403禁止进入

该请求是合法请求,但服务器拒绝回复对它。与401未经授权的回应不同,验证不会差异。

该服务在农场吗?可能是一台服务器配置不正确。

根据您的最新评论,您应该检查是否没有资源泄漏导致意外行为。如果您使用数据库,请确保要处理一次性物品等,请对服务器进行配置,以监视内存使用情况。如果您有长时间运行的请求,请考虑使用异步服务来保持线程池空闲。检查事件日志。

思考当IIS无法处理经过身份验证的流量时,我可能已经看到类似的行为,它只是用401轰炸。我从没注意到可以,但很可能在这种情况下发生。


0
投票

401表示您正在尝试访问受密码保护的资源,而未在请求中包含任何身份验证信息。检查您是否没有将服务器错误地配置为要求返回响应的URL的密码,并检查所有请求是否都在同一域中:您可能无意中向了受密码保护的域发出请求(例如,过去看到的是使用单独的主机来提供静态文件,但静态文件虚拟主机已设置HTTP基本身份验证。)


0
投票

TL; DR,我在HTTP正文中放置了HTTP标头信息

我的示例在Angular中,但是任何TypeScript / JavaScript(框架)都可能有相同的问题。

[当对后端API进行HTTP POST调用时,它要求标头包含已登录的用户信息,我在我的HTTP正文应为HTTP标头且标头为空的位置添加了HTTP标头。

问题

  markInstructionAsCompleted(visitScheduleId: string, instructionId: number) {
    return this.http.post(`${environment.apiUrl}/VisitInstructions/schedule/${visitScheduleId}/done/${instructionId}`, this.getHeaderWithAuthorization());
  }

解决方案,请注意,HTTP post调用中添加了第二个参数,该参数为null

  markInstructionAsCompleted(visitScheduleId: string, instructionId: number) {
    return this.http.post(`${environment.apiUrl}/VisitInstructions/schedule/${visitScheduleId}/done/${instructionId}`, null, this.getHeaderWithAuthorization());
  }
© www.soinside.com 2019 - 2024. All rights reserved.