ASP.NET Core中IIS托管Windows认证的会话创建事件日志实现
Absolutely! When using Windows Authentication with IIS hosting in ASP.NET Core, you can absolutely hook into authentication events to log when a user creates a session. Here's a step-by-step breakdown of how to do it:
1. Understand the Windows Authentication Events
Windows Authentication in ASP.NET Core exposes a set of events via the WindowsAuthenticationEvents class. The key event you'll care about for logging session creation is OnAuthenticated—this fires immediately after a user successfully authenticates (and thus, when their session is initialized).
2. Configure the Events (Two Approaches)
Approach 1: Inline Event Handler (Quick & Simple)
If you don't need dependency injection for your logging logic, you can define the event handler directly in your Program.cs:
var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllersWithViews(); // Configure Windows Authentication with event logging builder.Services.AddAuthentication(IISDefaults.AuthenticationScheme) .AddWindows(options => { options.Events = new WindowsAuthenticationEvents { OnAuthenticated = context => { // Get a logger instance var logger = context.HttpContext.RequestServices.GetRequiredService<ILogger<Program>>(); logger.LogInformation($"User {context.Principal.Identity.Name} has authenticated and created a session at {DateTime.UtcNow:yyyy-MM-dd HH:mm:ss}"); // Add any additional logic here (e.g., write to a database, update user last login time) return Task.CompletedTask; } }; }); builder.Services.AddAuthorization(options => { options.FallbackPolicy = options.DefaultPolicy; }); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); // Important: Ensure authentication and authorization middleware are added in order app.UseAuthentication(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run();
Approach 2: Custom Event Class (Dependency Injection Friendly)
For cleaner code and proper dependency injection (e.g., injecting a logger or database context), create a custom class that inherits from WindowsAuthenticationEvents:
public class CustomWindowsAuthEvents : WindowsAuthenticationEvents { private readonly ILogger<CustomWindowsAuthEvents> _logger; // Inject other services here (e.g., your database context) public CustomWindowsAuthEvents(ILogger<CustomWindowsAuthEvents> logger) { _logger = logger; } public override Task Authenticated(WindowsAuthenticatedContext context) { _logger.LogInformation($"User {context.Principal.Identity.Name} created a new session at {DateTime.UtcNow:yyyy-MM-dd HH:mm:ss}"); // Example: Update user's last login time in your database // var dbContext = context.HttpContext.RequestServices.GetRequiredService<YourDbContext>(); // var user = dbContext.Users.FirstOrDefault(u => u.Username == context.Principal.Identity.Name); // if (user != null) // { // user.LastLoginTime = DateTime.UtcNow; // await dbContext.SaveChangesAsync(); // } return base.Authenticated(context); } }
Then register this class in your Program.cs:
builder.Services.AddAuthentication(IISDefaults.AuthenticationScheme) .AddWindows(options => { // Tell Windows Auth to use your custom event class options.EventsType = typeof(CustomWindowsAuthEvents); }); // Register your custom event class with DI builder.Services.AddScoped<CustomWindowsAuthEvents>();
3. Key Notes
- IIS Configuration: Ensure Windows Authentication is enabled for your app in IIS (go to your site's Authentication settings, disable Anonymous Authentication, enable Windows Authentication).
- Event Timing: The
OnAuthenticatedevent fires once per user session (when they first access a protected resource). This aligns perfectly with logging when a session is created. - Additional Events: If you need to handle failed authentication or challenges, you can also hook into
OnAuthenticationFailedorOnChallengein the same way.
内容的提问来源于stack exchange,提问作者BioData41

