Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WCF和自定义身份验证(用户名/密码)_C#_Wcf_Authentication_Wcf Security_Nettcpbinding - Fatal编程技术网

C# WCF和自定义身份验证(用户名/密码)

C# WCF和自定义身份验证(用户名/密码),c#,wcf,authentication,wcf-security,nettcpbinding,C#,Wcf,Authentication,Wcf Security,Nettcpbinding,我有通过internet连接到WCF服务的Windows窗体客户端。 WCF服务托管在专用Windows帐户下运行的Windows服务中。 我想通过检查用户名+密码对,根据数据库对客户端进行身份验证 为了避免数百种方法,例如: public int Add(string User, string Password, int A, int B) 我使用以下指南覆盖了UserNamePasswordValidator类: 我的自定义验证器类与示例匹配 class UsernameAuthenti

我有通过internet连接到WCF服务的Windows窗体客户端。 WCF服务托管在专用Windows帐户下运行的Windows服务中。 我想通过检查用户名+密码对,根据数据库对客户端进行身份验证

为了避免数百种方法,例如:

public int Add(string User, string Password, int A, int B)
我使用以下指南覆盖了
UserNamePasswordValidator
类:

我的自定义验证器类与示例匹配

class UsernameAuthentication : UserNamePasswordValidator
    {
        public override void Validate(string userName, string password)
        {
            //Will be checked against database
            var ok = (userName == "Ole") && (password == "Pwd");
            if (ok == false)
                throw new AuthenticationException("u/p does not match");
        }
    }
我的服务器配置是:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
    </startup>
  <system.serviceModel>

    <services>
      <service name="TestWCFCustomAuth.CalculatorService" behaviorConfiguration="customCred">
        <endpoint address="CalcSvc"
                  binding="netTcpBinding"
                  bindingConfiguration="secUP"
                  contract="ServiceInterface.ICalculatorService"/>
        <endpoint address="mex" binding="mexHttpBinding" contract="ServiceInterface.ICalculatorService" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:81/"/>
            <add baseAddress="net.tcp://localhost:82/"/>
          </baseAddresses>
        </host>
      </service>
    </services>

    <bindings>
      <netTcpBinding>
        <binding name="secUP">
          <security mode="Message">
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </netTcpBinding>
    </bindings>

    <behaviors>
      <serviceBehaviors>
        <behavior name="customCred">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <serviceCredentials>
            <!--Service identity + encryption certificate-->
            <serviceCertificate findValue="SHKIService" storeLocation="LocalMachine" storeName="Root" x509FindType="FindBySubjectName"/>
            <userNameAuthentication userNamePasswordValidationMode="Custom"
              customUserNamePasswordValidatorType="TestWCFCustomAuth.UsernameAuthentication, TestWCFCustomAuth" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>
虽然我的代码与指南几乎相同,但我得到一个错误:

System.ServiceModel.Security.SecurityNegotiationException: 'The caller was not authenticated by the service.'
Inner Exception:
FaultException: The request for security token could not be satisfied because authentication failed.

我搜索了几天的答案,并尝试了许多其他配置。我最好的猜测是在幕后发生了其他类型的身份验证?如果是这样的话-我如何禁用它?

官方文档中有一个完整的演示,它使用用户名和密码验证,还具有证书验证。您只需按照教程中的步骤即可成功运行。您可以参考。

我缺少的步骤如下:

  • 按此处所述,为Windows服务帐户授予证书私钥的“读取”权限 在
  • 将私钥权限授予可以使用的帐户 mmc的证书管理单元。可以启动mms.exe,选择“添加/删除” 管理单元”在“文件”菜单中,选择“证书”管理单元并 选择本地计算机的“计算机帐户”。那就应该 选择个人存储的SSL证书,然后使用上下文菜单 “管理私钥…”

  • 运行客户端应用程序的计算机需要在
    CurrentUser\Trusted People
    store中拥有证书(即使客户端和服务器在同一台计算机上运行)。因此,我使用上一步中的mmc工具将没有私钥的证书导出到一个文件中,然后将该文件中的证书导入
    CurrentUser\Trusted People
    store。我想我必须将这个文件包含到我客户的安装包中

  • 这次我还使用了
    makecert.exe
    工具来创建证书,正如@Theobald Du提供的msdn参考中所建议的那样 这些命令是:


    makecert.exe-sr LocalMachine-ss MY-a sha1-n CN=谢谢!这与证书的创建方式或我没有将其复制到“CurrentUser/Trusted People”存储中有关。稍后我将发布更多详细信息,以向任何有类似问题的人说明。另外,wsHttpBinding和netTcpBinding都可以工作,我们现在可以选择了!
    
    var client = new CalculatorServiceClient("NetTcpBinding_ICalculatorService");
    client.ClientCredentials.UserName.UserName = "Ole";
    client.ClientCredentials.UserName.Password = "Pwd";
    var res = client.Add(1, 2);
    Console.WriteLine("Result: {0}", res);
    
    System.ServiceModel.Security.SecurityNegotiationException: 'The caller was not authenticated by the service.'
    Inner Exception:
    FaultException: The request for security token could not be satisfied because authentication failed.