Implementing Audit Logging with Custom Attribute in .NET Core
In the fast-paced world of .NET Core development, ensuring the security and accountability of your applications is paramount. One effective strategy to achieve this is through audit logging. By leveraging custom attributes, developers can seamlessly integrate audit logging into their .NET Core applications, providing invaluable insights into user interactions and system activities.Understanding Audit Logging in .NET Core
Audit logging serves as a robust security measure, allowing developers to track and record user actions within their applications. With the help of custom attributes, such as theAuditLogAttribute
, developers can capture essential information like user sessions, IP addresses, and request details, empowering them to monitor and analyze system behavior effectively.Implementation Example
Let's consider a simple implementation example using theAuditLogAttribute
in an ASP.NET Core API controller:public class AuditLogAttribute : ActionFilterAttribute { private readonly IHttpContextAccessor _httpContextAccessor; public AuditLogAttribute(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; } public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { var auditLog = new AuditLogModel(); var controllerName = ((ControllerBase)context.Controller).ControllerContext.ActionDescriptor.ControllerName; var actionName = ((ControllerBase)context.Controller).ControllerContext.ActionDescriptor.ActionName; var actionDescriptorRouteValues = ((ControllerBase)context.Controller).ControllerContext.ActionDescriptor.RouteValues; if (actionDescriptorRouteValues.ContainsKey("area")) { var area = actionDescriptorRouteValues["area"]; // Do something with 'area' if needed } auditLog.SessionId = context.HttpContext.Session.Id; if (_httpContextAccessor.HttpContext != null) { auditLog.IpAddress = _httpContextAccessor.HttpContext.Connection.RemoteIpAddress?.ToString(); } auditLog.PageURL = context.HttpContext.Request.Path; auditLog.ControllerName = controllerName; auditLog.ActionName = actionName; auditLog.UserId = _httpContextAccessor.HttpContext.Session.GetInt32("UserId") ?? 0; var request = context.HttpContext.Request; var header = request.GetTypedHeaders(); Uri uriReferer = header.Referer; if (uriReferer != null) { auditLog.Url = uriReferer.AbsoluteUri + context.HttpContext.Request.Path; } auditLog.BrowserInformation = context.HttpContext.Request.Headers["User-Agent"].ToString(); using (var repo = new AuditLogRepository()) { await repo.InsertAuditLogAsync(auditLog); } await next(); } }
Controller Implementation
Apply the AuditLogAttribute
to your controller to enable audit logging for all actions within it:
[ApiController] [Route("api/[controller]")] [AuditLog] // Applying the AuditLogAttribute at the controller level public class StudentController : ControllerBase { private readonly IStudentRepository _studentRepository; public StudentController(IStudentRepository studentRepository) { _studentRepository = studentRepository; } [HttpGet("{id}")] public async Task<ActionResult<Student>> GetStudent(int id) { var student = await _studentRepository.GetStudentByIdAsync(id); if (student == null) { return NotFound(); } return student; } [HttpPost] public async Task<ActionResult<Student>> CreateStudent(Student student) { await _studentRepository.CreateStudentAsync(student); return CreatedAtAction(nameof(GetStudent), new { id = student.Id }, student); } [HttpPut("{id}")] public async Task<IActionResult> UpdateStudent(int id, Student student) { if (id != student.Id) { return BadRequest(); } await _studentRepository.UpdateStudentAsync(student); return NoContent(); } [HttpDelete("{id}")] public async Task<IActionResult> DeleteStudent(int id) { var studentToDelete = await _studentRepository.GetStudentByIdAsync(id); if (studentToDelete == null) { return NotFound(); } await _studentRepository.DeleteStudentAsync(studentToDelete); return NoContent(); } }
0 Comments