How to: Audit Windows Communication Foundation Security Events

Windows Communication Foundation (WCF) allows you to log security events to the Windows event log, which can be viewed using the Windows Event Viewer. This topic explains how to set up an application so that it logs security events. For more information about WCF auditing, see Auditing.

To audit security events in code

  1. Specify the audit log location. To do this, set the AuditLogLocation property of the ServiceSecurityAuditBehavior class to one of the AuditLogLocation enumeration values, as shown in the following code.

    // Create a new auditing behavior and set the log location.
    ServiceSecurityAuditBehavior newAudit =
        new ServiceSecurityAuditBehavior();
    newAudit.AuditLogLocation =
        AuditLogLocation.Application;
    
    ' Create a new auditing behavior and set the log location.
    Dim newAudit As New ServiceSecurityAuditBehavior()
    newAudit.AuditLogLocation = AuditLogLocation.Application
    

    The AuditLogLocation enumeration has three values: Application, Security, or Default. The value specifies one of the logs visible in the Event Viewer, either the Security log or the Application log. If you use the Default value, the actual log will depend on the operating system the application is running on. If auditing is enabled and the log location is not specified, the default is the Security log for platforms that support writing to the Security log; otherwise, it will write to the Application log. Only Windows Server 2003 and Windows Vista support writing to the Security log by default.

  2. Set up the types of events to audit. You can simultaneously audit service-level events or message-level authorization events. To do this, set the ServiceAuthorizationAuditLevel property or the MessageAuthenticationAuditLevel property to one of the AuditLevel enumeration values, as shown in the following code.

    // Create a new auditing behavior and set the log location.
    ServiceSecurityAuditBehavior newAudit =
        new ServiceSecurityAuditBehavior();
    newAudit.AuditLogLocation =
        AuditLogLocation.Application;
    newAudit.MessageAuthenticationAuditLevel =
        AuditLevel.SuccessOrFailure;
    newAudit.ServiceAuthorizationAuditLevel =
        AuditLevel.SuccessOrFailure;
    
    newAudit.MessageAuthenticationAuditLevel = _
        AuditLevel.SuccessOrFailure
    newAudit.ServiceAuthorizationAuditLevel = _
        AuditLevel.SuccessOrFailure
    
  3. Specify whether to suppress or expose failures to the application regarding log audit events. Set the SuppressAuditFailure property to either true or false, as shown in the following code.

    // Create a new auditing behavior and set the log location.
    ServiceSecurityAuditBehavior newAudit =
        new ServiceSecurityAuditBehavior();
    newAudit.AuditLogLocation =
        AuditLogLocation.Application;
    newAudit.MessageAuthenticationAuditLevel =
        AuditLevel.SuccessOrFailure;
    newAudit.ServiceAuthorizationAuditLevel =
        AuditLevel.SuccessOrFailure;
    newAudit.SuppressAuditFailure = false;
    
    newAudit.SuppressAuditFailure = False
    

    The default SuppressAuditFailure property is true, so that the failure to audit does not affect the application. Otherwise, an exception is thrown. For any successful audit, a verbose trace is written. For any failure to audit, the trace is written at the Error level.

  4. Delete the existing ServiceSecurityAuditBehavior from the collection of behaviors found in the description of a ServiceHost. The behavior collection is accessed by the Behaviors property, which in turn is accessed from the Description property. Then add the new ServiceSecurityAuditBehavior to the same collection, as shown in the following code.

    // Remove the old behavior and add the new.
    serviceHost.Description.
        Behaviors.Remove<ServiceSecurityAuditBehavior>();
    serviceHost.Description.Behaviors.Add(newAudit);
    
    ' Remove the old behavior and add the new.
    serviceHost.Description.Behaviors.Remove(Of ServiceSecurityAuditBehavior)
    serviceHost.Description.Behaviors.Add(newAudit)
    

To set up auditing in configuration

  1. To set up auditing in configuration, add a <behavior> element to the <behaviors> section of the web.config file. Then add a <serviceSecurityAudit> element and set the various attributes, as shown in the following example.

    <behaviors>  
       <behavior name="myAuditBehavior">  
          <serviceSecurityAudit auditLogLocation="Application"  
                suppressAuditFailure="false"
                serviceAuthorizationAuditLevel="None"
                messageAuthenticationAuditLevel="SuccessOrFailure" />  
          </behavior>  
    </behaviors>  
    
  2. You must specify the behavior for the service, as shown in the following example.

    <services>  
        <service type="WCS.Samples.Service.Echo"
        behaviorConfiguration=" myAuditBehavior">  
           <endpoint address=""  
                    binding="wsHttpBinding"  
                    bindingConfiguration="CertificateDefault"
                    contract="WCS.Samples.Service.IEcho" />  
        </service>  
    </services>  
    

Example

The following code creates an instance of the ServiceHost class and adds a new ServiceSecurityAuditBehavior to its collection of behaviors.

public static void Main()
{
    // Get base address from appsettings in configuration.
    Uri baseAddress = new Uri(ConfigurationManager.
        AppSettings["baseAddress"]);

    // Create a ServiceHost for the CalculatorService type
    // and provide the base address.
    using (ServiceHost serviceHost = new
        ServiceHost(typeof(CalculatorService), baseAddress))
    {
        // Create a new auditing behavior and set the log location.
        ServiceSecurityAuditBehavior newAudit =
            new ServiceSecurityAuditBehavior();
        newAudit.AuditLogLocation =
            AuditLogLocation.Application;
        newAudit.MessageAuthenticationAuditLevel =
            AuditLevel.SuccessOrFailure;
        newAudit.ServiceAuthorizationAuditLevel =
            AuditLevel.SuccessOrFailure;
        newAudit.SuppressAuditFailure = false;
        // Remove the old behavior and add the new.
        serviceHost.Description.
            Behaviors.Remove<ServiceSecurityAuditBehavior>();
        serviceHost.Description.Behaviors.Add(newAudit);
        // Open the ServiceHostBase to create listeners
        // and start listening for messages.
        serviceHost.Open();

        // The service can now be accessed.
        Console.WriteLine("The service is ready.");
        Console.WriteLine("Press <ENTER> to terminate service.");
        Console.WriteLine();
        Console.ReadLine();

        // Close the ServiceHostBase to shutdown the service.
        serviceHost.Close();
    }
}
Public Shared Sub Main()
    ' Get base address from appsettings in configuration.
    Dim baseAddress As New Uri(ConfigurationManager.AppSettings("baseAddress"))

    ' Create a ServiceHost for the CalculatorService type 
    ' and provide the base address.
    Dim serviceHost As New ServiceHost(GetType(CalculatorService), baseAddress)
    Try
        ' Create a new auditing behavior and set the log location.
        Dim newAudit As New ServiceSecurityAuditBehavior()
        newAudit.AuditLogLocation = AuditLogLocation.Application
        newAudit.MessageAuthenticationAuditLevel = _
            AuditLevel.SuccessOrFailure
        newAudit.ServiceAuthorizationAuditLevel = _
            AuditLevel.SuccessOrFailure
        newAudit.SuppressAuditFailure = False
        ' Remove the old behavior and add the new.
        serviceHost.Description.Behaviors.Remove(Of ServiceSecurityAuditBehavior)
        serviceHost.Description.Behaviors.Add(newAudit)
        ' Open the ServiceHostBase to create listeners 
        ' and start listening for messages.
        serviceHost.Open()

        ' The service can now be accessed.
        Console.WriteLine("The service is ready.")
        Console.WriteLine("Press <ENTER> to terminate service.")
        Console.WriteLine()
        Console.ReadLine()

        ' Close the ServiceHostBase to shutdown the service.
        serviceHost.Close()
    Finally
    End Try

End Sub

.NET Framework Security

Setting the SuppressAuditFailure property to true, suppresses any failure to generate security audits (if set to false, an exception is thrown). However, if you enable the following Windows Local Security Setting property, a failure to generate audit events will cause Windows to shut down immediately:

Audit: Shut down system immediately if unable to log security audits

To set the property, open the Local Security Settings dialog box. Under Security Settings, click Local Policies. Then click Security Options.

If the AuditLogLocation property is set to Security and Audit Object Access is not set in the Local Security Policy, audit events will not be written to the Security log. Note that no failure is returned, but audit entries are not written to the Security log.

See also