2016-07-22 13 views
1

TLS 1.2を使用してWCFサービスを作成する必要があります。このセキュリティプロトコルのみを使用する必要があります(他のセキュリティで保護されたプロトコルタイプとの接続を拒否します)。私は証明書を作成しました。ポートにバインドします。 HTTPがうまくいきます。私は私がコードの次の文字列を記述する必要があることをどこにでも読み:wcfサービスで安全なプロトコルを制限する方法

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; 

[OK]を、私はそれを書いたが、効果がなかったです。サービス側のコード:

using System; 
using System.IdentityModel.Selectors; 
using System.IdentityModel.Tokens; 
using System.Net; 
using System.ServiceModel; 
using System.Runtime.Serialization; 
using static System.Console; 

namespace ConsoleHost 
{ 

    public class DistributorValidator : UserNamePasswordValidator 
    { 
     public override void Validate(string userName, string password) 
     { 
      if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password)) 
       throw new SecurityTokenException("Both username and password required"); 
      if (userName != "login" || password != "pass") 
       throw new FaultException($"Wrong username ({userName}) or password "); 
     } 
    } 

    public class Service1 : IService1 
    { 
     public string GetData(int value) 
     { 
      return $"You entered: {value}"; 
     } 

     public CompositeType GetDataUsingDataContract(CompositeType composite) 
     { 
      if (composite == null) 
      { 
       throw new ArgumentNullException(nameof(composite)); 
      } 
      if (composite.BoolValue) 
      { 
       composite.StringValue += "Suffix"; 
      } 
      return composite; 
     } 
    } 

    [ServiceContract] 
    public interface IService1 
    { 
     [OperationContract] 
     string GetData(int value); 

     [OperationContract] 
     CompositeType GetDataUsingDataContract(CompositeType composite); 

    } 

    [DataContract] 
    public class CompositeType 
    { 
     [DataMember] 
     public bool BoolValue { get; set; } = true; 

     [DataMember] 
     public string StringValue { get; set; } = "Hello "; 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; 
      ServiceHost host = new ServiceHost(typeof(Service1)); 
      host.Open(); 
      WriteLine("Press any key to stop server..."); 
      ReadLine(); 
     } 
    } 
} 

App.configファイルが含まれています

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

    <system.serviceModel> 
    <services> 
    <service name="ConsoleHost.Service1"> 
     <host> 
     <baseAddresses> 
      <add baseAddress = "https://localhost:8734/Service1/" /> 
     </baseAddresses> 
     </host> 
     <endpoint address="" binding="wsHttpBinding" contract="ConsoleHost.IService1" bindingConfiguration="securityBinding"> 
     <identity> 
      <dns value="localhost"/> 
     </identity> 
     </endpoint> 
     <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/> 
    </service> 
    </services> 
    <bindings> 
    <wsHttpBinding> 
     <binding name="securityBinding"> 
     <security mode="TransportWithMessageCredential"> 
      <transport clientCredentialType="None" /> 
      <message clientCredentialType="UserName" /> 
      <!--establishSecurityContext="false" />--> 
     </security> 
     </binding> 
    </wsHttpBinding> 
    </bindings> 
    <behaviors> 
    <serviceBehaviors> 
     <behavior> 
     <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/> 
     <serviceDebug includeExceptionDetailInFaults="False" /> 
     <serviceCredentials> 
      <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="ConsoleHost.DistributorValidator,ConsoleHost"/> 
     </serviceCredentials> 
     </behavior> 
    </serviceBehaviors> 
    </behaviors> 
    </system.serviceModel> 

</configuration> 

クライアント側コード:

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      try 
      { 
       ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3; 
       Service1Client client = new Service1Client(); 
       client.ClientCredentials.UserName.UserName = "login"; 
       client.ClientCredentials.UserName.Password = "pass"; 
       Console.WriteLine(client.GetData(10)); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine("Exception: " + ex.Message); 
       if (ex.InnerException != null) 
       { 
        Console.WriteLine("Inner: " + ex.InnerException.Message); 
        if (ex.InnerException.InnerException != null) 
         Console.WriteLine("Inner: " + ex.InnerException.InnerException.Message); 
       } 
      } 
      Console.ReadLine(); 
     } 
    } 
} 

をあなたは私がTLS 1.2にセキュリティプロトコルを設定しているサービス側で見ることができるように。クライアント側では、セキュリティプロトコルをSsl3に設定しています。私は、サーバがTls 1.2セキュリティプロトコルでしか動作しないクライアントを受け入れ、受け入れる必要があるため、そのサービスがクライアント接続を拒否するのを待っています。しかし、私はこの結果を得ていません。クライアントは接続して正常に動作します。どうしたの?

IISでTls 1.2のみを使用するように設定を変更できることを理解します。しかし、私はセルフホスティングのwcfサービスを作っている、それは問題です。

+0

あなた 'ServicePointManager'オブジェクトと私は見ることができますWCFサービス/クライアント間の接続がありません。私はあなたがどのように2つを接続するか分からないが、あなたの現在の投稿コードが示すように、あなたは特定のURIにプロトコルを割り当てていない。 – Tim

+0

@Tim、私はapp.configにbaseaddressを設定しました。このURIを使用してサービスします。 ServicePointManagerとWCFサービスの間の接続を設定するにはどうすればよいですか? ServicePointManagerが現在のAppDomainのすべての接続に影響することはわかっています。違いますか? –

+0

私は同じ問題を見ています。誰もがSystem.Net.ServicePointManager.SecurityProtocolプロパティを設定することをお勧めしますが、WCFサービス(通常のタイプで、コンソールホストではない)でいつどこで実行するのかは明確ではなく、設定ファイルで正しく実行する方法については言及していません。 – PJ7

答えて

1

ServicePointManager.SecurityProtocolオプションを使用しているサーバーでは、特定のセキュリティプロトコルを使用してsthに接続することはできません。別のアプリケーションのセキュリティプロトコルを無効にすることはできません。サーバー全体の接続を許可または拒否できます。

HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\ 

とキー、[サーバー]の各プロトコルについて、次の値を設定します:uはuは、レジストリのウィンドウを開き、次のキーを見つけるために持っているTLS 1.2以外のすべてのプロトコルを無効にしたい場合はDisabledByDefault = 1、0 =有効

How to enable TLS

関連する問題