Как добавить пользователя / пройти аутентификацию в WCF - PullRequest
0 голосов
/ 16 мая 2019

Я хочу добавить немного безопасности для моей 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.

Поэтому я решил добавить тег services к своему web.config рядом с bindings

<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.

1 Ответ

0 голосов
/ 17 мая 2019

Независимо от того, используем ли мы режим безопасности сообщений или режим безопасности транспортного уровня, нам всем необходимо предоставить сертификат, обеспечивающий безопасность режима аутентификации по имени пользователя и паролю.Я сделал пример, связанный с режимом безопасности транспорта.нам нужно предоставить сертификат, чтобы обеспечить успешное размещение службы.

    <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 Server.
enter image description here
enter image description here
затем мы добавляем привязку https в модуль привязки веб-сайта IIS, чтобы служба WCF была успешно размещена.enter image description here
Пользовательский класс аутентификации. В зависимости от реальной ситуации настройте этот класс аутентификации в приведенном выше файле конфигурации.

    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 HTTP-запрос не авторизован с помощью схемы аутентификации клиента 'Anonymous'
Проверка имени пользователя и пароля WCF с использованием wshttpbinding notworking
Не стесняйтесь, дайте мне знать, если есть что-то, с чем я могу помочь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...