繁体   English   中英

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

[英]WCF and custom Authentication (username/password)

我有 Windows Forms 客户端通过 Internet 连接到 WCF 服务。 WCF 服务托管在 Windows 服务中,该服务在专用 Windows 帐户下运行。 我想通过检查用户名+密码对来针对数据库验证客户端。

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

public int Add(string User, string Password, int A, int B)

我使用以下指南覆盖UserNamePasswordValidator class:

http://blog.clauskonrad.net/2011/03/how-to-wcf-and-custom-authentication.html

我的自定义身份验证器 class 与示例匹配

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>

客户端是自动生成的:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
    </startup>
    
    <system.serviceModel>
        <bindings>
            <netTcpBinding>
                <binding name="NetTcpBinding_ICalculatorService">
                    <security mode="Message">
                        <transport sslProtocols="None" />
                        <message clientCredentialType="UserName" />
                    </security>
                </binding>
            </netTcpBinding>
            <wsHttpBinding>
                <binding name="MetadataExchangeHttpBinding_ICalculatorService">
                    <security mode="None" />
                </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="net.tcp://localhost:82/CalcSvc" binding="netTcpBinding"
                bindingConfiguration="NetTcpBinding_ICalculatorService" contract="ServiceReference1.ICalculatorService"
                name="NetTcpBinding_ICalculatorService">
                <identity>
                    <certificate encodedValue="AwAAAAEAAAAUAAAA5Miz/2tl3pOxgQepIM62wzcAU+8gAAAAAQAAAK0BAAAwggGpMIIBCqADAgECAgkArWjRy0f0w98wCgYIKoZIzj0EAwIwFjEUMBIGA1UEAxMLU0hLSVNlcnZpY2UwHhcNMjEwMzI5MjEzNjUwWhcNMjYwMzI5MjEzNjUwWjAWMRQwEgYDVQQDEwtTSEtJU2VydmljZTCBmzAQBgcqhkjOPQIBBgUrgQQAIwOBhgAEAXE/ZelSAJ7+qjUTECzz2ZHFHTd6KtYsrbgdvBw3Xqt/G9R4IO01Rvxltir7FMfHzLgzsa4LdLkY3yAk/4rOqTPqAXY/sd/TpZOOB7ntZx02BEUvNiKouVu+yzIBMQxyW4aGZGOftiSOA28VKxNnaARN97/IoYyO0FhN+4vlKaPlTGFQMAoGCCqGSM49BAMCA4GMADCBiAJCAa88D2F5LuEFF0BL2+Vn1xIGSrjLo1YpiJk0DNJEbF0OOzH+xuKk/8H4yjQGO/yMmI8/pQWeU36Bu/D2xxJ0XqvtAkIA9udnx+h7lAsAYOtFMT12qHkVHInGWTzGHjNF0nrOldURa7X8B+tDeYrDJGBD+/9R2E4koJeGb0ubAmUl4Hrwyik=" />
                </identity>
            </endpoint>
            <endpoint address="http://localhost:81/mex" binding="wsHttpBinding"
                bindingConfiguration="MetadataExchangeHttpBinding_ICalculatorService"
                contract="ServiceReference1.ICalculatorService" name="MetadataExchangeHttpBinding_ICalculatorService" />
        </client>
    </system.serviceModel>
</configuration>

我做了一个自签名证书,并把它导入到根目录,所以证书配置也OK。

测试客户端代码是:

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.

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

官方文档中有完整的demo,使用用户名密码验证,也有证书验证。 您只需要按照教程中的步骤操作即可成功运行。 你可以参考参考

我缺少的步骤如下:

  1. 为 Windows 服务帐户授予对证书私钥的“读取”权限, 如此处所述

要向帐户授予对私钥的权限,可以使用 mmc 的证书管理单元。 可以启动mms.exe,在“文件”菜单中选择“添加/删除管理单元”,选择“证书”管理单元,然后选择本地计算机的“计算机帐户”。 然后应该 select 个人存储的 SSL 证书,然后使用上下文菜单“管理私钥...”。

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

  2. 这一次我使用makecert.exe工具创建证书,如 @Theobald Du 提供的 msdn 参考中所建议的命令是:

    makecert.exe -sr LocalMachine -ss MY -a sha1 -n CN=<I used server's IP address> -sky exchange -pe

PS 另外我在那台机器上缺少 makecert.exe,所以我从microsoft下载了 Microsoft SDK

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM