WCF - IErrorHandler против аутентификации - PullRequest
2 голосов
/ 08 августа 2011

Я пишу сервис WCF с некоторой аутентификацией и пользовательским обработчиком ошибок.Однако я сталкиваюсь с этой проблемой: моя реализация IErrorHandler не срабатывает, когда аутентификация генерирует исключение, но прекрасно работает с другими исключениями.

Работает ли аутентификация до того, как IErrorHandler получаетпостроен?Я лаю не на том дереве, пытаясь заставить его перехватить эти ошибки?

Да, я пытался (и я) выбрасываю FaultException в моей аутентификации, а не SecurityTokenException.

1 Ответ

2 голосов
/ 26 июня 2012

Итак, во-первых, убедитесь, что ваш собственный обработчик ошибок также реализует IServiceBehavior.IServiceBehavior требует, чтобы вы реализовали пару других методов, но важным из них является «ApplyDispatchBehavior», в котором вы должны добавить ErrorHandler в диспетчеры каналов.

C #

public class CustomErrorHandler: IServiceBehavior, IErrorHandler
{
    public bool HandleError(Exception error)
    {
        //Return True here if you want the service to continue on as if
        //  the error was handled

        return true;
    }

    public void ProvideFault(Exception error,
                             MessageVersion version,
                             ref Message fault)
    {
        FaultException fe = new FaultException(
            new FaultReason(error.Message),
            new FaultCode("Service Error"));

        MessageFault mf = fe.CreateMessageFault();
        fault = Message.CreateMessage(version, mf, fe.Action);
    }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, 
                                      ServiceHostBase serviceHostBase)
    {

        IErrorHandler eh = new CustomErrorHandler();

        foreach (ChannelDsipatcherBase cdb in serviceHostBase.ChannelDispatchers)
        {
            ChannelDispatcher cd = cdb as ChannelDispatcher;
            cd.ErrorHandlers.Add(eh);
        }

    }

    public void AddBindingParameters(ServiceDescription serviceDescription,
                                     ServiceHostBase serviceHostBase, 
                                     Collection<ServiceEndpoint> endpoints, 
                                     BindingParameterCollection bindingParameters)
    {
        //Add binding parameters if you want, I am not
    }

    public void Validate(ServiceDescription serviceDescription,
                         ServiceHostBase serviceHostBase)
    {
        //Add custom fault validation here if you want
    }
}

Затем вам нужнодобавьте CustomErrorHandler в качестве служебного поведения и добавьте поведение

web.config

<system.serviceModel>
    <extensions>
        <behaviorExtensions>
            <add name="ErrorHandler"
                 type="ServiceNamespace.CustomErrorHandler, ServiceNamespace, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
        </behaviorExtensions>
    </extensions>
    <behaviors>
        <serviceBehaviors>
            <behavior name="MyBehavior1">
                <!--Put other behaviors for your service here then add the next line-->
                <ErrorHandler />
            </behavior>
        </serviceBehaviors>
    </behaviors>
</system.serviceModel>

Таким образом все ваши сгенерированные исключения будут преобразованы в ошибки для возврата клиенту.

В случае SecurityTokenExceptions вы не хотите сразу преобразовывать их в Fault Exceptions.Вы действительно хотите выбросить их как SecurityTokenExceptions в пользовательской проверке, чтобы служба / сервер распознала, что авторизация безопасности не удалась, и автоматически возвращается как эквивалент ошибки «403: доступ запрещен».Я не на 100%, но я думаю, что части пользовательской аутентификации и проверки происходят до того, как загружаются пользовательские поведения служб, такие как обработчик ошибок.К сожалению, если вам нужно устранить неполадки в вашей аутентификации, вам нужно будет включить трассировку WCF в службе, см. Эту статью под названием " Как включить трассировку WCF ".

Есливам нужно регистрировать неудачные попытки аутентификации, вам, вероятно, нужно будет поместить его непосредственно в ваш пользовательский валидатор.

...