【问题标题】:How to add user/pass authentication in WCF如何在 WCF 中添加用户/通过身份验证
【发布时间】:2019-05-16 12:51:00
【问题描述】:

我想为我的WCF 应用程序服务添加一些安全性。我想出了如何添加用户名/密码身份验证:

<system.serviceModel>
  <behaviors>
    <serviceBehaviors>
      <behavior name="MyBehavior">
        <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
        <serviceDebug includeExceptionDetailInFaults="false" />
        <serviceCredentials>
          <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="Changer.Service.Validation.ServiceAuthenticator, Changer.Service"/>
        </serviceCredentials>
      </behavior>
    </serviceBehaviors>
  </behaviors>
  <bindings>
    <wsHttpBinding>
      <binding name="MyBinding">
        <security mode="TransportWithMessageCredential">
          <message clientCredentialType="UserName" />
        </security>
      </binding>
    </wsHttpBinding>
  </bindings>
  <services>
    <service name="Changer.Service.Request.RequestService" behaviorConfiguration="MyBehavior">
      <endpoint address="/" binding="wsHttpBinding" contract="Changer.Service.Request.IRequestService" bindingConfiguration="MyBinding" />
    </service>
  </services>
</system.serviceModel>

这是我的自定义数据验证:

public class ServiceAuthenticator : UserNamePasswordValidator
{
    public override void Validate(string userName, string password)
    {
        // Check the user name and password
        if (userName != Authentication.Providers.Service.PasswordChanger.UserName || 
            password != Authentication.Providers.Service.PasswordChanger.Password)
        {
            throw new System.IdentityModel.Tokens.SecurityTokenException("Unknown username or password.");
        }
    }
}

不幸的是,我收到了错误,因为我没有有效的证书。我尝试按照本教程进行操作: https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-configure-an-iis-hosted-wcf-service-with-ssl

但没有成功。它说,证书主机与我正在访问的站点 url 不匹配。在客户端我收到错误:

Could not establish trust relationship for the SSL/TLS secure channel with authority 'foo'. The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. The remote certificate is invalid according to the validation procedure

我可以通过添加到我的客户端应用程序来解决这个问题:

System.Net.ServicePointManager.ServerCertificateValidationCallback += delegate { return true; };

这基本上不能解决我的问题。我该怎么办?我只想进行简单的用户/通过身份验证。

我决定摆脱SSL,然后我的代码改为:

<system.serviceModel>
  <behaviors>
    <serviceBehaviors>
      <behavior name="MyBehavior">
        <serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
        <serviceDebug includeExceptionDetailInFaults="true" />
        <serviceCredentials>
          <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="PasswordChanger.Service.Validation.ServiceAuthenticator, PasswordChanger.Service"/>
        </serviceCredentials>
      </behavior>
    </serviceBehaviors>
  </behaviors>
  <bindings>
    <wsHttpBinding>
      <binding name ="NewBinding">
        <security mode="Message">
          <message clientCredentialType="UserName"/>
        </security>
      </binding>
    </wsHttpBinding>
  </bindings>
  <protocolMapping>
    <add binding="basicHttpsBinding" scheme="https" />
  </protocolMapping> 
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>

然后我得到了这个错误:

Error: Cannot obtain Metadata from http://localhost:53705/R.svc If this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled metadata publishing at the specified address. For help enabling metadata publishing, please refer to the MSDN documentation at www.WS-Metadata Exchange Error URI: http://localhost:53705/R.svc Metadata contains a reference that cannot be resolved: 'http://localhost:53705/R.svc'. Content Type application/soap+xml; charset=utf-8 was not supported by service http://localhost:53705/R.svc. The client and service bindings may be mismatched. The remote server returned an error: (415) Cannot process the message because the content type 'application/soap+xml; charset=utf-8' was not the expected type 'text/xml; charset=utf-8'..HTTP GET Error URI: http://localhost:53705/R.svc The HTML document does not contain Web service discovery information.

所以我决定在web.config 旁边的bindings 旁边添加services 标签

<services>
  <service name="PasswordChanger.Service.Request.RequestService" behaviorConfiguration="MyBehavior">
    <endpoint address="/" binding="wsHttpBinding" contract="PasswordChanger.Service.Request.IRequestService" bindingConfiguration="NewBinding" />
  </service>

我又遇到了另一个错误: The service certificate is not provided. Specify a service certificate in ServiceCredentials.

【问题讨论】:

  • 尝试将设置文件中的这一行 更改为
  • @ClaytonC 还是同样的问题
  • 您想要/需要 SSL 吗?如果没有,您应该遵循this 教程。
  • @mm8 我没有得到这些 ms 指南,因为在大多数情况下它们从不工作。我在线程中添加了更多信息,其中包含您共享的链接中所写的内容。

标签: c# wcf


【解决方案1】:

无论我们使用消息安全还是传输层安全模式,我们都需要提供证书来确保用户名/密码认证模式是安全的。 我做了一个与传输安全模式相关的例子。我们需要提供证书以确保服务托管成功。

    <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
          <serviceCredentials>
            <userNameAuthentication customUserNamePasswordValidatorType="WcfService1.CustUserNamePasswordVal,WcfService1" userNamePasswordValidationMode="Custom"/>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <wsHttpBinding>
        <binding>
          <security mode="TransportWithMessageCredential">
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <protocolMapping>
      <add binding="wsHttpBinding" scheme="https" />
    </protocolMapping>    
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

如果我们没有证书,我们可以使用 IIS 服务器证书工具生成自签名证书。


然后我们在IIS网站绑定模块中添加https绑定,这样WCF服务就托管成功了。
自定义认证类。根据实际情况,在上面的配置文件中配置这个认证类。

    internal class CustUserNamePasswordVal : UserNamePasswordValidator
    {
        public override void Validate(string userName, string password)
        {
            if (userName != "jack" || password != "123456")
            {
                throw new Exception("Username/Password is not correct");
            }
        }
}
  <serviceCredentials>
            <userNameAuthentication customUserNamePasswordValidatorType="WcfService1.CustUserNamePasswordVal,WcfService1" userNamePasswordValidationMode="Custom"/>
          </serviceCredentials>

客户。

//for validating the server certificate. 
ServicePointManager.ServerCertificateValidationCallback += delegate
              {
                  return true;
              };
            ServiceReference2.Service1Client client = new ServiceReference2.Service1Client();
            client.ClientCredentials.UserName.UserName = "jack";
            client.ClientCredentials.UserName.Password = "123456";

如果我们使用消息安全,我们可以通过以下代码设置证书。(根据实际情况配置您的实际证书)

<serviceCredentials>
            <serviceCertificate storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" findValue="869f82bd848519ff8f35cbb6b667b34274c8dcfe"/>
            <userNameAuthentication customUserNamePasswordValidatorType="WcfService1.CustUserNamePasswordVal,WcfService1" userNamePasswordValidationMode="Custom"/>
          </serviceCredentials>

请参考以下链接。
WCF-TransportWithMessageCredential The HTTP request is unauthorized with client authentication scheme 'Anonymous'
WCF UserName & Password validation using wshttpbinding notworking
如果有什么可以帮助的,请随时告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-16
    • 2015-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多