In this article, you will learn how to reduce the number of audit events to login attempts and then store them safely in a database.
Introduction
Some time ago, I wrote about ASP.NET Health Monitoring – a logging infrastructure provided by the .NET framework, easily configurable through web.config. In that post, I was presenting heart beat and error events. Today, I would like to show you how to collect ASP.NET authentication audit logs. There are special events groups registered in the global web.config for this purpose:
<healthMonitoring>
...
<eventMappings>
...
<add name="All Audits"
type="System.Web.Management.WebAuditEvent,
System.Web,Version=4.0.0.0,Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"
startEventCode="0" endEventCode="2147483647" />
<add name="Failure Audits"
type="System.Web.Management.WebFailureAuditEvent,
System.Web,Version=4.0.0.0,Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"
startEventCode="0" endEventCode="2147483647" />
<add name="Success Audits"
type="System.Web.Management.WebSuccessAuditEvent,
System.Web,Version=4.0.0.0,Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"
startEventCode="0" endEventCode="2147483647" />
</eventMappings>
</healthMonitoring>
Though, using the All Audits set will cause your application to generate an audit event for each served request. If we then would store those events in a SQL Server database, we might put a heavy load on the server. In this post, I will show you how to reduce the number of audit events to login attempts and then store them safely in a database.
Configuration
First, let’s create a necessary tables:
aspnet_regsql -A w -d Logowanie -S db-master.srv.trader.pl
-sqlexportonly c:\temp\forms-audit-schema.sql
Then, we need to add healthMonitoring
section to our web.config and enable it. We will also create event mappings for success and error authentication events:
<healthMonitoring enabled="true">
...
<eventMappings>
<add name="AuthenticationSuccess"
type="System.Web.Management.WebAuthenticationSuccessAuditEvent,System.Web,
Version=4.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" />
<add name="AuthenticationFailure"
type="System.Web.Management.WebAuthenticationFailureAuditEvent,System.Web,
Version=4.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" />
</eventMappings>
...
</healthMonitoring>
The next step is to create a connection string for our log database (or use an existing one) and add a provider for our log events:
<healthMonitoring enabled="true">
<providers>
<add connectionStringName="DB_Logowanie" buffer="false"
name="MsSqlAuditWebEventProvider" type="System.Web.Management.SqlWebEventProvider,
System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
...
</healthMonitoring>
In the above configuration, I deliberately disabled buffering in order to be sure that all events will be stored in the database. For really heavy loads, you may enable buffering and set bufferMode
to Critical Notification.
Finally, we need to bind events with our provider:
<healthMonitoring enabled="true">
...
<rules>
<add name="MsSql Auth Success Critical" eventName="AuthenticationSuccess"
provider="MsSqlAuditWebEventProvider" profile="Critical" />
<add name="MsSql Auth Failure Critical" eventName="AuthenticationFailure"
provider="MsSqlAuditWebEventProvider" profile="Critical" />
</rules>
...
</healthMonitoring>
Examining the Authentication Log Content
After applying the above settings to your application, audit events should start appearing in the aspnet_WebEvent_Events
table. Have a look at what kind of information they reveal:
Example success authentication event:
Event code: 4002
Event message: Membership credential verification succeeded.
Event time: 11/20/2013 2:13:55 PM
Event time (UTC): 11/20/2013 1:13:55 PM
Event ID: c7096dc16a26445cba2b6f67919c0a1a
Event sequence: 2300
Event occurrence: 1
Event detail code: 0
Application information:
Application domain: /LM/W3SVC/1693641394/ROOT/logowanie-4-130294218493519428
Trust level: Full
Application Virtual Path: /logowanie
Application Path: \\ASP.Net\TestApp\logowanie\
Machine name: WEB-02
Process information:
Process ID: 6920
Process name: w3wp.exe
Account name:TEST\iis_zrodla
Request information:
Request URL: http://localhost/logowanie/logon
Request path: /logowanie/logon
User host address: 172.20.11.150
User:
Is authenticated: False
Authentication Type:
Thread account name: TEST\iis_zrodla
Name to authenticate: peter.null@test.pl
Example authentication failure event:
Event code: 4006
Event message: Membership credential verification failed.
Event time: 11/20/2013 2:20:23 PM
Event time (UTC): 11/20/2013 1:20:23 PM
Event ID: 8e1a137591ad43feb596f00a23bf5ec7
Event sequence: 4706
Event occurrence: 12
Event detail code: 0
Application information:
Application domain: /LM/W3SVC/1693641394/ROOT/logowanie-3-130294169828149952
Trust level: Full
Application Virtual Path: /logowanie
Application Path: \\ASP.Net\TestApp\logowanie\
Machine name: WEB-17
Process information:
Process ID: 3584
Process name: w3wp.exe
Account name: TEST\iis_zrodla
Request information:
Request URL: http://localhost/logowanie/logon
Request path: /logowanie/logon
User host address: 172.20.11.150
User:
Is authenticated: False
Authentication Type:
Thread account name: TEST\iis_zrodla
Name to authenticate: peter.notnull@test.pl
History
- 21st November, 2013: Initial version