UserName clientCredentialType的WCF安全问题

时间:2009-06-03 15:45:07

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

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

然后:我有问题!

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

会议#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>

会议#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。

会议#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>

会议#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");
}

有什么想法吗?

谢谢,Alberto

1 个答案:

答案 0 :(得分:2)

嗯,有一点是立即突出的是这种差异:

服务器:

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

启用可靠会话= true。

客户端:

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

启用可靠会话= false。

这绝对是一种不匹配 - 但令人惊讶的是,在你的#1和#2场景中都是如此......

马克