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.
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);
}
}
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? –
Si potrebbe anche voler vedere [questo post StackOverflow] (http://stackoverflow.com/questions/17738305/wcf-routing-service-dynamic-error-handling) –
Hai provato ad attivare la traccia WCF? Questo potrebbe darti maggiori informazioni su cosa sta succedendo sul lato server. – MvdD