简体   繁体   English

如何在Windows Server 2012 R2上调试NTLM身份验证

[英]How to debug NTLM authentication on Windows Server 2012 r2

I have set up a SOAP service on a virtual machine running Windows Server 2012 r2. 我已经在运行Windows Server 2012 r2的虚拟机上设置了SOAP服务。 I secured it using NTLM and I managed to access it from the host computer using SoapUI . 我使用NTLM保护它,并设法使用SoapUI从主机访问它。 So far so good... 到现在为止还挺好...

I am now trying to access my service, still from the host, but using a golang program this time. 我现在仍在尝试从主机访问我的服务,但是这次使用了golang程序。 I am using this library to do it (I only had to implement the GenerateNegotiateMessage() method and made sure that the Negotiate flags are the same as the ones of SoapUI). 我正在使用此库来执行此操作(我只需要实现GenerateNegotiateMessage()方法,并确保Negotiate标志与SoapUI的标志相同)。

To make sure that I did things right, I downloaded the source code of SoapUI and compared the outputs (NegotiateMessage and AuthenticateMessage) of my golang program and SoapUI. 为了确保我做对了,我下载了SoapUI的源代码,并比较了golang程序和SoapUI的输出(NegotiateMessage和AuthenticateMessage)。 If I fix the inputs (timestamp and random client challenge), I do get the same outputs. 如果我固定输入(时间戳和随机客户机挑战),则确实会得到相同的输出。 However, when I try to connect to the service, I get a 401 with "Access is denied due to invalid credentials". 但是,当我尝试连接到服务时,出现“ 401由于无效凭据而拒绝访问”的提示。 No need to say I'm 100% sure the credentials are right as I am able to access the service with the same credentials using SoapUI. 无需说我100%确信凭据正确,因为我能够使用SoapUI以相同的凭据访问该服务。 So there must be something wrong in my go code. 因此我的go代码中肯定有问题。 But to figure it out, I would need more logs from my Windows Server. 但是要弄清楚,我将需要Windows Server上的更多日志。 Any idea of where I could start looking? 对我可以开始寻找的地方有任何想法吗?

Below is the web.config of my Soap service: 以下是我的Soap服务的web.config:

<?xml version="1.0"?>
<configuration>
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5"/>
    <httpRuntime targetFramework="4.5"/>
    <trace enabled="true" pageOutput="true" requestLimit="40" localOnly="false"/>
  </system.web>
  <system.serviceModel>

    <diagnostics wmiProviderEnabled="true">
      <messageLogging
           logEntireMessage="true"
           logMalformedMessages="true"
           logMessagesAtServiceLevel="true"
           logMessagesAtTransportLevel="true"
           maxMessagesToLog="3000"
       />
    </diagnostics>

    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="false"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <bindings>
      <basicHttpBinding>
        <binding>
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Ntlm" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>

    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <directoryBrowse enabled="true"/>
  </system.webServer>
  <system.diagnostics>
    <sources>
      <source name="System.ServiceModel" switchValue="All" propagateActivity="true">
        <listeners>
          <add name="myListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="C:\logs\TextWriterOutput.log"/>
        </listeners>
      </source>
    </sources>
  </system.diagnostics>
</configuration>

Thanks a lot for your help! 非常感谢你的帮助!

I eventually managed to solve my problem. 我最终设法解决了我的问题。 It came from the fact that I wasn't reading entirely the response body of my HTTP request in my golang program. 这是因为我没有在golang程序中完整读取HTTP请求的响应正文。 Therefore, every time I made a request, the server interpreted as a new connection but the NTLM authentication scheme requires all the requests to be made in a single connection. 因此,每次我发出请求时,服务器都将其解释为新连接,但NTLM身份验证方案要求所有请求均在单个连接中进行。 It's actually this answer that solved my problem. 正是这个答案解决了我的问题。

For future coders, this is the code that you should use if you want to reuse the same connection: 对于以后的编码器,如果要重用相同的连接,则应使用以下代码:

res, _ := client.Do(req)
io.Copy(ioutil.Discard, res.Body)
res.Body.Close()

To conclude, I didn't manage to get much info from the logs of Windows. 总而言之,我没有从Windows日志中获取太多信息。 The tools that put me on the right track were the Failed Request Tracer that you can access from the IIS Manager and the goold old Wireshark to compare the requests made by my program and those of SoapUI. 使我步入正轨的工具是“失败请求跟踪程序”,您可以从IIS管理器和老式的Wireshark中访问该请求跟踪程序,以比较我的程序和SoapUI发出的请求。

Hope this can be useful to someone. 希望这对某人有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在Windows Server 2012 R2上发送http / 2请求 - send http/2 request on windows server 2012 R2 Windows Server 2012 R2上的意外崩溃WCF服务 - Unexpected crash WCF Service on Windows Server 2012 R2 Windows Server 2012 R2 IIS托管应用程序 - Windows server 2012 R2 IIS Hosting application 如何在Windows Server 2008 R2中托管Wcf服务? - How to host a Wcf service in Windows server 2008 R2? 402.2.1260 IIS7 Windows Server 2008 R2 Web服务 - 402.2.1260 IIS7 Windows Server 2008 R2 Web Service 通过具有 Windows (NTLM) 身份验证的代理访问具有基本身份验证的 Web 服务 - Access Web Service with Basic authentication through a proxy with Windows (NTLM) authentication 客户端身份验证方案“ Ntlm”对HTTP请求进行了未经授权的操作。 从服务器收到的身份验证标头是“ NTLM” - The HTTP request is unauthorized with client authentication scheme 'Ntlm'. The authentication header received from the server was 'NTLM' 如何将PHP Web服务连接到SQL Server 2008 R2 - How to connect php webservice to sql server 2008 r2 用于IIS集成Windows身份验证(NTLM)的JAX-WS客户端 - JAX-WS client for IIS Integrated Windows authentication (NTLM) 将我的网站移动到其他服务器,将身份验证从Kerberos更改为NTLM - Moving my website to different server changes authentication from Kerberos to NTLM
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM