Adding a user to the log context when using Serilog and Asp.Net Core

I am trying to use Serilog with my ASP.Net Core 1.0 project. I just can't get the current user to log in to the system that is logged.

Has anyone else understood this?

I tried this:

using System.Threading.Tasks; using Serilog.Context; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using System.Security.Claims; using xxx.Models; namespace xxx.Utils { public class EnrichSerilogContextMiddleware { private readonly RequestDelegate _next; public EnrichSerilogContextMiddleware(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext httpContext) { var username = httpContext.User.Identity.Name; if (httpContext.User.Identity.IsAuthenticated) { var userFullName = (((ClaimsIdentity)httpContext.User.Identity).FindFirst(Member.FullnameClaimName).Value); var userName = " anyone@gmail.com "; LoggerEnricher.AddEntryPointContext(userFullName, userName); } else { LoggerEnricher.AddEntryPointContext(); } await _next(httpContext); } } public static class LoggerEnricher { public static void AddEntryPointContext(string userFullName = null, string username = null) { if (!string.IsNullOrWhiteSpace(username) || !string.IsNullOrWhiteSpace(userFullName)) { LogContext.PushProperty("Username", username); LogContext.PushProperty("UserFullename", userFullName); } else { LogContext.PushProperty("Username", "Anonymous"); } } public static void EnrichLogger(this IApplicationBuilder app) { app.UseMiddleware<EnrichSerilogContextMiddleware>(); } } } 

I run this in Startup.cs, adding:

  public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug(); loggerFactory.AddSerilog(); app.EnrichLogger(); ... } 

But it always ends with an anonymous username.

Thank you in advance

Søren rokkedal

+5
source share
2 answers

I was able to get an authenticated Active Directory user with just a few lines of code. I am not very experienced with Core authentication, in particular with statements, but maybe this will lead you to you, or at least help others who come along with a similar problem, but with AD.

The key lines are Enrich.FromLogContext() and app.Use(async...

 public class Startup { public IConfigurationRoot Configuration { get; } public Startup(IHostingEnvironment env) { Log.Logger = new LoggerConfiguration() .Enrich.FromLogContext() // Populates a 'User' property on every log entry .WriteTo.MSSqlServer(Configuration.GetConnectionString("MyDatabase"), "Logs") .CreateLogger(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.WithFilter(new FilterLoggerSettings { { "Default", LogLevel.Information }, { "Microsoft", LogLevel.Warning }, { "System", LogLevel.Warning } }) .AddSerilog(); app.Use(async (httpContext, next) => { var userName = httpContext.User.Identity.IsAuthenticated ? httpContext.User.Identity.Name : "unknown"; LogContext.PushProperty("User", !String.IsNullOrWhiteSpace(userName) ? userName : "unknown"); await next.Invoke(); }); } } 

For AD authentication through IIS / Kestrel for web.config, you need to set forwardWindowsAuthToken as follows:

 <?xml version="1.0" encoding="utf-8"?> <configuration> <system.webServer> <aspNetCore ... forwardWindowsAuthToken="true" /> </system.webServer> </configuration> 
+4
source

You need to call _next in the block as follows:

  public async Task Invoke(HttpContext httpContext) { var username = httpContext.User.Identity.Name; if (httpContext.User.Identity.IsAuthenticated) { var userFullName = (((ClaimsIdentity)httpContext.User.Identity).FindFirst(Member.FullnameClaimName).Value); var userName = " anyone@gmail.com "; using (LogContext.PushProperty("Username", userName) using (LogContext.PushProperty("UserFullName", userFullName) { await _next(httpContext); } } else { await _next(httpContext); } } 
+2
source

Source: https://habr.com/ru/post/1257796/


All Articles