WCF客户端NTLM身份验证返回500

时间:2020-07-08 19:24:42

标签: c# wcf authentication http-status-code-500 ntlm-authentication

我使用WinLMs应用程序使用NTLM身份验证连接到WCF服务时遇到问题。

原始应用程序是我在2005年编写的,这是我的第一个C#代码。进行少量修改,效果很好。 Web服务是带有DataSet的asmx。最近由于以下原因来进行升级:性能问题和客户端上的Windows 10升级(Crystal Reports 10.5.37需要升级到x64,并且SAP站点上没有官方的运行时下载)。 我使用WCF,.NET 4.8重写了它,并用库替换了Crystal以创建Excel文件。在开发人员环境中,除了500个代码外,新版本都可以正常工作。没有考虑Rest和.NET Core(太难解释;不是技术原因)。

当用户启动新版本时,第一个直接问题是“访问被拒绝”。然后以管理员身份启动。错误代码:“该应用程序无法启动,因为其并行配置不正确”。然后,我尝试在事件查看器中获取更多信息,但未成功:没有信息。 sxstrace工具引发访问被拒绝。几天后,我明白了:我在包含国家非英语字符的配置文件中添加了注释。删除注释后,连接期间发生错误500。

<\ LongStory-optional>

应用程序调用验证服务,该服务仅返回常数1。

错误消息:“响应消息的内容类型text / html与绑定的内容类型不匹配(text / xml; charset = utf-8)。

如果使用自定义编码器,请确保正确实施IsContentTypeSupported方法。响应的前75个字节是:

由于发生内部服务器错误,因此无法显示该页面。” 不使用Https。

奇怪的是,在IE中打开.svc后,错误消失了,直到工作站重新启动。这证明客户端和服务器可以正常工作。同时,旧的应用程序没有这样的问题。因此,我尝试使用“ Web参考”代替“服务参考”。似乎“ Web参考”可以正常工作。接下来,我在客户端尝试了不同的设置。我发现此更改后可以使用“服务参考”:client.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;

使用提琴手工具,我发现消息交换几乎是相同的,除了最终结果:更改之前,我的状态为401/401/500,更改之后为401/401/200,其他区别是时间和NTLM base64值,没什么。

我认为这不是解决方案,而只是解决方法。您知道如何使用WCF正确处理NTLM身份验证吗?

我的代码和配置的基本要点:

var client = new ServiceClient();
client.ClientCredentials.Windows.ClientCredential.UserName = Dialog1.textBox1.Text;
client.ClientCredentials.Windows.ClientCredential.Domain = Dialog1.textBox2.Text;
client.ClientCredentials.Windows.ClientCredential.Password = Dialog1.textBox3.Text;
try
{
    i = client.Verify().Status;
} ...         

   

配置:

<system.serviceModel>
  <bindings>
    <basicHttpBinding>
      <binding name="basicEndpoint" sendTimeout="infinite"  >
        <security mode="TransportCredentialOnly">
          <transport clientCredentialType="Ntlm"/>
        </security>
      </binding>
    </basicHttpBinding>
  </bindings>
  <client>
    <endpoint address="http://wro67zt2/AlsbWebServices/WindService/WindService.svc" binding="basicHttpBinding" bindingConfiguration="basicEndpoint" contract="WindService.IService" name="basicEndpoint"/>
  </client>
</system.serviceModel>

我认为不需要服务器端配置。它可以很好地与Web参考一起使用,因此我可以认为此处一切正常。我尝试用“ Windows”代替“ Ntlm”,但是问题仍然相同,它将字符串NTLM更改为“请求/响应消息”中的“协商”,还将消息数从3变为2(401/500或401/200)。

编辑-服务器配置:

<?xml version="1.0"?>
<configuration>
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.7.2" />
    <httpRuntime targetFramework="4.7.2"/>
    <globalization culture="en-GB" requestEncoding="utf-8" responseEncoding="utf-8"/>
    <pages controlRenderingCompatibilityVersion="4.0" clientIDMode="AutoID"/>
    <identity impersonate="false" />
  </system.web>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="basicBinding" >
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Windows"  realm="XXXXX"/>
            <message clientCredentialType="UserName" algorithmSuite="Default"/>
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>

    <services>
      <service behaviorConfiguration="WindService.Behavior" name="WindLibrary.Service">
        <endpoint 
          address="" 
          binding="basicHttpBinding"
          bindingConfiguration="basicBinding"
          name="basicEndpoint" 
          bindingNamespace="http://XXXXX.com/services/prime/"
          contract="WindLibrary.IService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="WindService.Behavior">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
            <add scheme="http" binding="basicHttpBinding" bindingConfiguration="HttpBinding" />
    </protocolMapping>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <directoryBrowse enabled="false"/>
  </system.webServer>
</configuration>

0 个答案:

没有答案