.net - UserName clientCredentialType 的 WCF 安全问题

标签 .net wcf .net-3.5 wcf-security

首先我为我的英语道歉...

那么:我有问题了!

我为一个简单的 WCF 服务编写了代码,配置 #1 一切正常。

Conf#1 - 服务器

<configuration>
  <system.serviceModel>
    <services>
      <service name="WCFservice.Service" 
               behaviorConfiguration="WCFservice.ServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress = "http://localhost:8731/WCFservice/" />
          </baseAddresses>
        </host>
        <endpoint address="" binding="wsHttpBinding" contract="WCFservice.IService"/>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <bindings>
      <wsHttpBinding>
        <binding name="WSCertificateSecurity">
          <reliableSession enabled="true"/>
          <security mode="Message">
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="WCFservice.ServiceBehavior">
          <serviceCredentials>
            <serviceCertificate findValue="cn=abc" 
                    storeLocation="LocalMachine" storeName="TrustedPeople" 
                    x509FindType="FindBySubjectDistinguishedName"/>
            <clientCertificate>
              <authentication certificateValidationMode="PeerTrust"/>
            </clientCertificate>
          </serviceCredentials>
          <serviceMetadata httpGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="True" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

Conf#1 - 客户

<configuration>
  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="WSHttpBinding_IService">
          <reliableSession enabled="false" />
          <security mode="Message">
            <transport clientCredentialType="Windows" 
                       proxyCredentialType="None" realm="" />
            <message clientCredentialType="Windows" 
                  negotiateServiceCredential="true"
                  establishSecurityContext="true" 
                  algorithmSuite="Default" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://localhost:8731/WCFservice/" 
                binding="wsHttpBinding"
                bindingConfiguration="WSHttpBinding_IService" 
                contract="WCF.IService"
                name="WSHttpBinding_IService">
        <identity>
          <userPrincipalName value="myname" />
        </identity>
      </endpoint>
    </client>
  </system.serviceModel>
</configuration>

当我尝试使用我创建的个人验证类设置 userName 身份验证时出现问题。我发布配置 #2。

Conf#2 - 服务器

<configuration>
  <system.serviceModel>
    <services>
      <service name="WCFservice.Service" 
               behaviorConfiguration="WCFservice.ServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress = "http://localhost:8731/WCFservice/" />
          </baseAddresses>
        </host>
        <endpoint address="" binding="wsHttpBinding" contract="WCFservice.IService"/>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <bindings>
      <wsHttpBinding>
        <binding name="WSCertificateSecurity">
          <reliableSession enabled="true"/>
          <security mode="Message">
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="WCFservice.ServiceBehavior">
          <serviceCredentials>
            <userNameAuthentication 
                 userNamePasswordValidationMode="Custom"  
                 customUserNamePasswordValidatorType="WCFservice.Login, WCFservice"/>
            <serviceCertificate findValue="cn=abc" 
                 storeLocation="LocalMachine" storeName="TrustedPeople" 
                 x509FindType="FindBySubjectDistinguishedName"/>
            <clientCertificate>
              <authentication certificateValidationMode="PeerTrust"/>
            </clientCertificate>
          </serviceCredentials>
          <serviceMetadata httpGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="True" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

Conf#2 - 客户

<configuration>
  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="WSHttpBinding_IService">
          <reliableSession enabled="false" />
          <security mode="Message">
            <transport clientCredentialType="Windows" 
                  proxyCredentialType="None" realm="" />
            <message 
                  clientCredentialType="UserName" 
                  negotiateServiceCredential="true"
                  establishSecurityContext="true" 
                  algorithmSuite="Default" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://localhost:8731/WCFservice/" binding="wsHttpBinding"
        bindingConfiguration="WSHttpBinding_IService" contract="WCF.IService"
        name="WSHttpBinding_IService">
        <identity>
          <userPrincipalName value="myname" />
        </identity>
      </endpoint>
    </client>

当我启动应用程序时,我得到一个

System.ServiceModel.Security.SecurityNegotiationException

private void button1_Click(object sender, EventArgs e) 
{
    WCF.XnottaLightServiceClient client = new WCF.XnottaLightServiceClient();
    client.ClientCredentials.UserName.UserName = "user";
    client.ClientCredentials.UserName.Password = "pass";

    string[] s = textBox6.Text.Split('§');
    int[] i = new int[s.Length];
    for(int j = 0; j < i.Length; j++) 
    {
        i[j] = Convert.ToInt32(s[j]);
    }

    string string1 = client.getString("xnl");
}

有什么想法吗?

谢谢,阿尔贝托

最佳答案

嗯,有一点很明显:

服务器:

<wsHttpBinding>
        <binding name="WSCertificateSecurity">
          <reliableSession enabled="true"/>

启用可靠 session = true。

客户:

<wsHttpBinding>
        <binding name="WSHttpBinding_IService">
          <reliableSession enabled="false" />

启用可靠 session = false。

这绝对是不匹配的 - 令人惊讶的是,在您的#1 和#2 场景中都是这种情况......

马克

关于.net - UserName clientCredentialType 的 WCF 安全问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/945497/

相关文章:

wcf - 如何在不使用任何证书的情况下在 wcf 中使用 wsHttpBinding

java - WCF\.Net\C# 中的 WSSE(带摘要)- 一种简单的方法?

c# - WPF 中 Datacontext 和 ItemSsource 的区别

c# - 将此委托(delegate)转换为匿名方法或 lambda

c# - WPF TextBlock 中的自动垂直滚动条?

C# Linq Where(表达式).FirstorDefault() 与 .FirstOrDefault(表达式)

wcf - 为什么基于声明的身份验证而不是基于角色的身份验证

c# - C# 中的老化数据结构

c# - 目录路径为字符串 : ensure DirectoryPathSeperator at the end of the string

c# - 我应该如何缓冲绘制的矩形以提高性能(C#/.NET/WinForms/GDI+)