مشاركة عبر


اتصالات خدمة الاتصال عن بُعد الآمنة في خدمة C#‎

الأمان هو أحد أهم جوانب الاتصال. يوفر إطار عمل تطبيق الخدمات الموثوقة عدداً قليلاً من مكدسات وأدوات الاتصال المنشأة مسبقاً والتي يمكنك استخدامها لتحسين الأمان. تتناول هذه المقالة طريقة تحسين الأمان عند استخدام خدمة الاتصال عن بعد في خدمة C#. إنها تعتمد على مثال يشرح كيفية إعداد الاتصال عن بعد للخدمات الموثوقة المكتوبة في C#‎.

للمساعدة في تأمين خدمة عند استخدام خدمة الاتصال عن بعد مع خدمات C#، اتبع الخطوات التالية:

  1. قم بإنشاء واجهة IHelloWorldStatefulتحدد الطرق التي ستكون متاحة لاستدعاء إجراء عن بعد في خدمتك. ستستخدم خدمتك FabricTransportServiceRemotingListener، والتي يتم الإعلان عنها في Microsoft.ServiceFabric.Services.Remoting.FabricTransport.Runtime مساحة الاسم. هذا هو ICommunicationListenerتطبيق يوفر قدرات الاتصال عن بعد.

    public interface IHelloWorldStateful : IService
    {
        Task<string> GetHelloWorld();
    }
    
    internal class HelloWorldStateful : StatefulService, IHelloWorldStateful
    {
        protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
        {
            return new[]{
                    new ServiceReplicaListener(
                        (context) => new FabricTransportServiceRemotingListener(context,this))};
        }
    
        public Task<string> GetHelloWorld()
        {
            return Task.FromResult("Hello World!");
        }
    }
    
  2. أضف إعدادات المُستمع وبيانات اعتماد الأمان.

    تأكد من تثبيت الشهادة التي تريد استخدامها للمساعدة في تأمين اتصال الخدمة الخاص بك على جميع العقد في نظام المجموعة.

    إشعار

    في عقد Linux، يجب أن تكون الشهادة موجودة كملفات بتنسيق PEM في الدليل /var/lib/sfcerts. لمعرفة المزيد، راجع موقع شهادات X.509 وتنسيقها على عقد Linux.

    هناك طريقتان يمكنك من خلالهما توفير إعدادات المستمع وبيانات اعتماد الأمان:

    1. وفرها مباشرة في رمز الخدمة:

      protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
      {
          FabricTransportRemotingListenerSettings  listenerSettings = new FabricTransportRemotingListenerSettings
          {
              MaxMessageSize = 10000000,
              SecurityCredentials = GetSecurityCredentials()
          };
          return new[]
          {
              new ServiceReplicaListener(
                  (context) => new FabricTransportServiceRemotingListener(context,this,listenerSettings))
          };
      }
      
      private static SecurityCredentials GetSecurityCredentials()
      {
          // Provide certificate details.
          var x509Credentials = new X509Credentials
          {
              FindType = X509FindType.FindByThumbprint,
              FindValue = "4FEF3950642138446CC364A396E1E881DB76B48C",
              StoreLocation = StoreLocation.LocalMachine,
              StoreName = "My",
              ProtectionLevel = ProtectionLevel.EncryptAndSign
          };
          x509Credentials.RemoteCommonNames.Add("ServiceFabric-Test-Cert");
          x509Credentials.RemoteCertThumbprints.Add("9FEF3950642138446CC364A396E1E881DB76B483");
          return x509Credentials;
      }
      
    2. وفرها باستخدام حزمة تكوين:

      إضافة قسم باسم TransportSettings في ملف settings.xml.

      <Section Name="HelloWorldStatefulTransportSettings">
          <Parameter Name="MaxMessageSize" Value="10000000" />
          <Parameter Name="SecurityCredentialsType" Value="X509" />
          <Parameter Name="CertificateFindType" Value="FindByThumbprint" />
          <Parameter Name="CertificateFindValue" Value="4FEF3950642138446CC364A396E1E881DB76B48C" />
          <Parameter Name="CertificateRemoteThumbprints" Value="9FEF3950642138446CC364A396E1E881DB76B483" />
          <Parameter Name="CertificateStoreLocation" Value="LocalMachine" />
          <Parameter Name="CertificateStoreName" Value="My" />
          <Parameter Name="CertificateProtectionLevel" Value="EncryptAndSign" />
          <Parameter Name="CertificateRemoteCommonNames" Value="ServiceFabric-Test-Cert" />
      </Section>
      

      في هذه الحالة، CreateServiceReplicaListenersسيبدو الأسلوب كالآتي:

      protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
      {
          return new[]
          {
              new ServiceReplicaListener(
                  (context) => new FabricTransportServiceRemotingListener(
                      context,this,FabricTransportRemotingListenerSettings .LoadFrom("HelloWorldStatefulTransportSettings")))
          };
      }
      

      إذا أضفت TransportSettings قسمًا في ملف settings.xml، FabricTransportRemotingListenerSettingsسيتم تحميل جميع الإعدادات من هذا القسم بشكل افتراضي.

      <!--"TransportSettings" section .-->
      <Section Name="TransportSettings">
          ...
      </Section>
      

      في هذه الحالة، CreateServiceReplicaListenersسيبدو الأسلوب كالآتي:

      protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
      {
          return new[]
          {
              return new[]{
                      new ServiceReplicaListener(
                          (context) => new FabricTransportServiceRemotingListener(context,this))};
          };
      }
      
  3. عند استدعاء طرق على خدمة مؤمنة باستخدام مكدس الاتصال عن بُعد، بدلًا من استخدام Microsoft.ServiceFabric.Services.Remoting.Client.ServiceProxyالفئة لإنشاء وكيل خدمة، استخدمMicrosoft.ServiceFabric.Services.Remoting.Client.ServiceProxyFactory. مرر في FabricTransportRemotingSettings، والذي يحتوي على SecurityCredentials.

    
    var x509Credentials = new X509Credentials
    {
        FindType = X509FindType.FindByThumbprint,
        FindValue = "9FEF3950642138446CC364A396E1E881DB76B483",
        StoreLocation = StoreLocation.LocalMachine,
        StoreName = "My",
        ProtectionLevel = ProtectionLevel.EncryptAndSign
    };
    x509Credentials.RemoteCommonNames.Add("ServiceFabric-Test-Cert");
    x509Credentials.RemoteCertThumbprints.Add("4FEF3950642138446CC364A396E1E881DB76B48C");
    
    FabricTransportRemotingSettings transportSettings = new FabricTransportRemotingSettings
    {
        SecurityCredentials = x509Credentials,
    };
    
    ServiceProxyFactory serviceProxyFactory = new ServiceProxyFactory(
        (c) => new FabricTransportServiceRemotingClientFactory(transportSettings));
    
    IHelloWorldStateful client = serviceProxyFactory.CreateServiceProxy<IHelloWorldStateful>(
        new Uri("fabric:/MyApplication/MyHelloWorldService"));
    
    string message = await client.GetHelloWorld();
    
    

    إذا كان رمز العميل يعمل كجزء من خدمة، فيمكنك التحميل FabricTransportRemotingSettingsمن ملف إعدادات.xml. إنشاء قسم HelloWorldClientTransportSettings مشابه لرمز الخدمة، كما هو موضح سابقًا. قم بإجراء التغييرات التالية على رمز العميل:

    ServiceProxyFactory serviceProxyFactory = new ServiceProxyFactory(
        (c) => new FabricTransportServiceRemotingClientFactory(FabricTransportRemotingSettings.LoadFrom("HelloWorldClientTransportSettings")));
    
    IHelloWorldStateful client = serviceProxyFactory.CreateServiceProxy<IHelloWorldStateful>(
        new Uri("fabric:/MyApplication/MyHelloWorldService"));
    
    string message = await client.GetHelloWorld();
    
    

    إذا لم يكن العميل قيد التشغيل كجزء من خدمة، فيمكنك إنشاء ملف client_name.settings.xml في نفس الموقع الذي يوجد فيه client_name.exe. ثم أنشئ قسم TransportSettings في هذا الملف.

    على غرار الخدمة، إذا قمت بإضافة TransportSettings قسم في settings.xml/client_name.settings.xml للعميل، فحمل FabricTransportRemotingSettings جميع الإعدادات من هذا القسم بشكل افتراضي.

    تُبسط التعليمة البرمجية السابقة في هذه الحالة بشكل أكبر:

    
    IHelloWorldStateful client = ServiceProxy.Create<IHelloWorldStateful>(
                 new Uri("fabric:/MyApplication/MyHelloWorldService"));
    
    string message = await client.GetHelloWorld();
    
    

كخطوة قادمة، اقرأ واجهة برمجة تطبيقات الويب مع OWIN في الخدمات الموثوقة.