I am using a WCF Service and I have implemented IErrorHandler. In the HandleError method, I want to retrieve the caller's username in order to set a ThreadContext property for Log4Net (to save the username along with the exception details in SQL Server)

My code is working well if I avoid trying to retrieve the caller's username.

This is the line of code inside the HandleError method which is returning a NullReferenceException:

string username = ServiceSecurityContext.Current.WindowsIdentity.Name;

It seems that at the point the HandleError method of IErrorHandler kicks in, the original caller information has been disposed.

Does anyone have any idea how I can retrieve the caller's username inside the HandlerError method of IErrorHandler?

Thanks for your help!

3

There are 3 answers

0
Craig On BEST ANSWER

Thanks to those who responded to help. My security appears to be configured correctly but I cannot retrieve the username in the HandleError method of the IErrorHandler interface in the WCF service. However, I am able to retrieve the username in the ProvideFault method. So, I declared a class level variable in the ErrorHandler (IErrorHandler) class which is set during the ProvideFault method and then read and logged with the exception in the ErrorHandler method. This is a "workaround" and not my preference, but unfortunately I cannot seem to access the security context inside the HandleError method.

Here is a sample of the code:

public class ErrorHandler : IErrorHandler, IServiceBehavior
{
    private string username = null;

    public bool HandleError(Exception error)
    {
        //Log the exception along with the username.
        //...logging call including the username class member string...

        //Return true to indicate we have performed our behaviour.
        return true;
    }

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
            //Retrieve the username.
            username = ServiceSecurityContext.Current.WindowsIdentity.Name;
    }
}
0
Stefan Egli On

If you get this exception then you probably do not have security configured correctly. See also this answer: https://stackoverflow.com/a/2869481/106567

0
Croco64 On

Using a Class Level variable seems to have a side effect. The same instance of the handler seems to be used for every error handled (to be confirmed). So if 2 errors are raised at the exact same time, I don't know how it will react. So instead, in ProvideFault, I used the exception received as argument to transport the username to the HandleError method. An exception has a «Data» property which is a dictionary. I just add two key-value pairs (one for PrimaryIdentity and one for WindowsIdentity). In HandleError, I retrieved the information in the Data property of the exception received as argument.