2016-06-02 71 views
8

Ho un servizio WCF configurato con la sicurezza TransportWithMessageCredential. Tutte e tre le implementazioni per IAuthorizationPolicy, ServiceAuthenticationManager e ServiceAuthorizationManager sono attive ed efficaci.L'eccezione WCF Accesso negato non ritorna mai al client dopo 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() }); 

Per quanto ne so, nella classe ServiceAuthorizationManager ereditata, in CheckAccessCore metodo, una dichiarazione return false indica una Accesso negato. Va bene finché non voglio che il client sappia che ha ottenuto un'eccezione di accesso negata in cui il servizio smette di restituire qualcosa al client e sembra che il thread del servizio sia stato sospeso.

Ho provato tutti i tipi di try catch nel lato client e persino aggiunto un FaultContract all'operazione, ma il problema resiste.

Tutto ciò che posso vedere sono due eventi di errore negli strumenti di diagnostica.

enter image description here

Cosa manca dai miei implementazioni per ottenere il servizio di informare l'utente in materia di accesso negato errore?

Aggiornamento

E 'importante dire che sto usando RoutingService e adesso credo che la vera causa è che sia in qualche modo RoutingService mangiando l'eccezione, ma non so esattamente dove ciò accade. Anche se ho inserito tutti i metodi possibili, ma non sono riuscito a trovarlo.

Update 2

ho IErrorHandler sul posto:

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); 
     } 
    } 

Ma evento con questo client chiamante wont' ottenere l'eccezione e lo stesso 'eccezione non gestita' apparirà in eventi di debug.

Il modo unica che posso fallire il client chiamante è di un'eccezione in BeforeSendReply metodo IDispatchMessageInspector che credo non è il modo di andare come ho un CommunicationException sul lato client, invece di FaultException:

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 Tracing: enter image description here

+0

Potrebbe chiarire esattamente ciò che accade quando ci si aspetta un "Accesso negato" l'errore da restituire? E potresti forse postare qualche codice rilevante sul lato client? Un ultimo pensiero: un thread sospeso quando dovrebbe restituire un errore suggerisce stranezze multi-threading; potrebbe esserci un inosservato deadlock o race condition nel modo in cui l'eccezione viene innescata/gestita? –

+0

Si potrebbe anche voler vedere [questo post StackOverflow] (http://stackoverflow.com/questions/17738305/wcf-routing-service-dynamic-error-handling) –

+0

Hai provato ad attivare la traccia WCF? Questo potrebbe darti maggiori informazioni su cosa sta succedendo sul lato server. – MvdD

risposta

1

non si deve aspettare un FaultException qui, ma invece, un'eccezione di comunicazione, nel tuo caso un SecurityAccessDeniedException. Mi aspetterei che tutte le eccezioni sollevate in questa fase siano comunicative, in quanto riguarda il problema della comunicazione, e la sicurezza ne fa parte.

+0

il problema non è il tipo di eccezione, ma piuttosto è che l'eccezione è ingerita. –

0

prega di provare a cambiare il tipo di codice come segue:

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

Sto usando TCP con Transport + Message security. –

+0

Prova con

Problemi correlati