Storing Sitefinity Access Logs to Azure Storage
sitefinity | 2023-05-20
Implementing centralized logging enhances transparency and governance across your CMS applications. This guide walks through setting up Azure Storage to capture Sitefinity CMS logs, using a clean hybrid implementation between .NET Core and MVC architectures.
The setup involves two main components:
- Azure Storage configuration
- Custom code implementation in Sitefinity
⚙️ Prerequisites
Before you begin, ensure you have:
- Sitefinity CMS version 14.4 or later (tested)
- Hybrid Sitefinity project (using both .NET Core Renderer and MVC with Progress.Sitefinity)
- Azure Subscription with appropriate permissions to manage Storage services
☁️ Azure Setup
-
Log into the Azure Portal and navigate to Storage Accounts.
-
Create a new Storage Account under your desired Resource Group.
-
Add a Storage Table to store logs, and save the URL for later use.
-
Generate a Shared Access Signature (SAS) for secure access to the Storage Table. You will need this for connecting Sitefinity to Azure Storage.
🏗️ Sitefinity Setup
-
Install NuGet Package: In your Sitefinity project, install the
Azure.Data.Tables
NuGet package. -
Create Configuration Section: Add a configuration section to store the Azure Storage Table URL and the SAS connection string (generated from Azure steps 3 and 4 above).
-
Create Core Services: Implement the following components in your Sitefinity CMS:
Global.asax.cs
for application-wide settingsUserService.cs
for user-related log processingAuditServices.cs
for storing audit-related logs
-
Test the Log Implementation: Perform a few login attempts to verify that logs are captured and stored in Azure Storage.
-
Create Report View: Develop a reporting view to display logs in the Sitefinity CMS dashboard:
ReportController.cs
for handling the report generationReportModel.cs
to structure the log dataAuditReport.cshtml
for the report's front-end display
-
Configure the Widget: Add the custom widget to the Backend Page of Sitefinity for easy log viewing.
🔗 Sample Code
You can access the complete sample code for this implementation on my GitHub Gist.