2016-06-02 11 views
8

TransportWithMessageCredentialセキュリティで構成されたWCFサービスがあります。 IAuthorizationPolicyServiceAuthenticationManager、およびServiceAuthorizationManagerの3つの実装はすべて有効であり、有効です。私が知っているようにWCFアクセス拒否例外は、CheckAccessCoreの後にクライアントに返されません。

serviceHost.Credentials.ServiceCertificate.SetCertificate("CN=localhost"); 
serviceHost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new CustomValidator(); 
serviceHost.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = System.ServiceModel.Security.UserNamePasswordValidationMode.Custom; 

serviceHost.Authorization.PrincipalPermissionMode = PrincipalPermissionMode.Custom; 
serviceHost.Authorization.ServiceAuthorizationManager = new MyServiceAuthorizationManager(); 
serviceHost.Authentication.ServiceAuthenticationManager = new MyServiceAuthenticationManager(); 
serviceHost.Authorization.ExternalAuthorizationPolicies = 
    new System.Collections.ObjectModel.ReadOnlyCollection<System.IdentityModel.Policy.IAuthorizationPolicy>(
     new MyAuthorizationPolicy[] { new MyAuthorizationPolicy() }); 

は、ServiceAuthorizationManager継承されたクラスでは、CheckAccessCore方法では、return false文は拒否されましたアクセスを示します。それは、サービスがクライアントに何かを返すことを止め、サービススレッドがハングアップしているようなアクセス拒否例外を持っていることをクライアント側に知らせたい時までは、すべて良いことです。

クライアント側ですべての種類のtry catchを試してみましたが、操作にはFaultContractを追加しましたが、問題は解決します。

診断ツールで2つのエラーイベントが表示されます。

enter image description here

サービスを得るために、私の実装から欠落しているかアクセス拒否エラーにユーザに通知しますか?

更新

それは私がRoutingServiceを使用していますし、今、私は本当の原因はRoutingServiceは何とか例外を食べているが、それが起こる場所を正確に私にはわからないということです推測と言うことは注目すべきです。すべての可能な方法に踏み込んだが、私はそれを見つけることができなかった。

アップデート2

私は場所にIErrorHandlerを持っています。これで

public class ServiceErrorHandler : IErrorHandler 
    { 
     public bool HandleError(Exception error) 
     { 
      //You can log th message if you want.    
      return true; 
     } 

     public void ProvideFault(Exception error, MessageVersion version, ref Message msg) 
     { 
      if (error is FaultException) 
       return; 

      FaultException faultException = new FaultException(error.Message); 
      MessageFault messageFault = faultException.CreateMessageFault(); 
      msg = Message.CreateMessage(version, messageFault, faultException.Action); 
     } 
    } 

しかし、イベントは呼び出し側クライアントが文句を言わないのデバッグイベントに表示されます未処理の例外」例外と同じを取得します "。

私が呼び出し側クライアントに失敗することができます唯一の方法は、私が代わりにFaultExceptionのクライアント側のCommunicationExceptionを得るように移動するための方法はないと思うどのIDispatchMessageInspectorBeforeSendReply方法で例外をスローすることによってである:

public void BeforeSendReply(ref Message reply, object correlationState) 
    {       
     if (reply != null && reply.IsFault) 
     { 
      var messageFault = MessageFault.CreateFault(reply, Int32.MaxValue); 
      throw new FaultException("Access was denied", messageFault.Code); 
     } 
    } 

WCFトレース: enter image description here

+0

あなたが期待しているときに起こるまさに明確でしたエラーが返される「アクセスが拒否されましたか」?そしておそらく関連するクライアント側のコードのいくつかを投稿することができますか? 1つの最終的な考え:エラーを返すべきときにスレッドがハングすると、マルチスレッドの奇妙さが示唆されます。例外がどのようにトリガされ/処理されているかに目立たないデッドロックや競合状態が存在する可能性がありますか? –

+0

また、[this StackOverflow post](http://stackoverflow.com/questions/17738305/wcf-routing-service-dynamic-error-handling) –

+0

を参照してください。WCFトレースを有効にしましたか?これは、サーバー側で何が起こっているのかについてより多くの情報を提供するかもしれません。 – MvdD

答えて

1

あなたはあなたのケースSecurityAccessDeniedExceptionには、ここではなく、通信例外をFaultExceptionを期待すべきではありません。この段階で提起されたすべての例外は、通信上の問題のように通信の1つになると期待します。セキュリティの問題もその一部です。

+0

問題例外の型ではなく、むしろ例外が飲み込まれているということです。 –

0

次のようにコードタイプを変更してみてください:

<bindings> 
    <wsHttpBinding> 
     <binding name="NoSecurityBinding" > 
      <security mode="None"> 
       <transport clientCredentialType="None"/> 
       <message clientCredentialType="None"/> 
      </security> 
     </binding> 
     <binding name="DefaultBinding" /> 
    </wsHttpBinding> 
</bindings> 
+0

私はトランスポート+メッセージセキュリティでTCPを使用しています。 –

+0

を試してください –

関連する問題