Вопрос или проблема
Требование: Я работаю над ASP.NET Core 8 Web API и мне нужно реализовать аудит для определённых действий в моём приложении. Данные аудита должны храниться в таблице базы данных со структурой, аналогичной следующей:
CREATE TABLE [Audit_User_Actions]
(
[id] UNIQUEIDENTIFIER PRIMARY KEY,
[company_id] UNIQUEIDENTIFIER,
[user_id] UNIQUEIDENTIFIER,
[action] INT,
[entity_affected] NVARCHAR(100) NULL,
[data_before_action] NVARCHAR(400) NULL,
[data_after_action] NVARCHAR(400) NULL,
[action_date_time] DATETIME,
[ip_address] NVARCHAR(50) NOT NULL,
[browser_name] NVARCHAR(50) NOT NULL
);
Цель: захватить детализированные журналы аудита для различных действий сервиса, таких как вход пользователя (который создает токены и обновляет попытки входа в базу данных) и операции CRUD над другими сущностями, не создавая чрезмерной привязки между сервисами.
Что я попробовал: вот подходы, которые я рассматривал, и сложности, с которыми я столкнулся с каждым из них:
-
Промежуточное ПО: использование промежуточного ПО для регистрации журналов аудита для каждого действия конечной точки (
POST
,PUT
,DELETE
). Однако этот подход ограничивает аудит на уровне конечной точки и не захватывает действия внутри слоев сервиса, такие как генерация токенов или дополнительные операции с базой данных во время входа. -
Централизованный сервис: реализация централизованного сервиса аудита с репозиторием для обработки регистрации аудитов. Недостатком является то, что этот подход требует внедрения и вызова этого сервиса во всех других сервисах, что увеличивает связанность и влияет на масштабируемость.
-
Пакет Audit.NET: я исследовал Audit.NET, который, похоже, предлагает обширные возможности аудита, но меня беспокоят потенциальные ограничения или проблемы совместимости при использовании с .NET Core 8. Кроме того, мне интересно, есть ли другие популярные или рекомендуемые пакеты для аудита в .NET Core, которые могут решить эту задачу.
-
Шаблоны декоратора и перехватчика: эти шаблоны также рассматривались, но они привнесли слишком много сложности и создали значительную связанность между сервисами.
Вопрос
Кто-нибудь реализовал надежное решение для аудита в ASP.NET Core, которое эффективно захватывает действия как на уровне конечной точки, так и на уровне сервиса? Какой подход сработал хорошо для вас в плане минимизации связанности и поддержания масштабируемости? В частности, меня интересуют решения, которые хорошо интегрируются с ASP.NET Core 8 Web APIs и минимизируют воздействие на существующую структуру сервиса.
Любые идеи по оптимизации этих подходов или альтернативным стратегиям будут очень признательны. Спасибо!
Примечание: У меня уже есть столбцы created_at
, created_by
, updated_at
и т. д. в каждой другой таблице, которые используются для минимальной аудиторной информации.
Ответ или решение
Реализация аудита с помощью Dapper в ASP.NET Core 8 Web API
Введение
В условиях современного программирования, особенно в разработке веб-приложений, выполнение аудита действий пользователей является важной частью для обеспечения безопасности и отслеживания изменений данных. В этой статье мы рассмотрим, как организовать аудирование в ASP.NET Core 8 Web API, используя библиотеку Dapper, что позволит нам эффективно работать с базой данных и избегать чрезмерного связывания компонентов системы.
Структура таблицы аудита
Для начала нам необходимо создать таблицу в базе данных, где будут храниться записи аудита. Структура таблицы может выглядеть следующим образом:
CREATE TABLE [Audit_User_Actions]
(
[id] UNIQUEIDENTIFIER PRIMARY KEY,
[company_id] UNIQUEIDENTIFIER,
[user_id] UNIQUEIDENTIFIER,
[action] INT,
[entity_affected] NVARCHAR(100) NULL,
[data_before_action] NVARCHAR(400) NULL,
[data_after_action] NVARCHAR(400) NULL,
[action_date_time] DATETIME,
[ip_address] NVARCHAR(50) NOT NULL,
[browser_name] NVARCHAR(50) NOT NULL
);
Подход к аудиту
Мы можем использовать несколько подходов для реализации аудита, но я предлагаю комбинировать несколько стратегий для достижения оптимального результата.
1. Настройка модели аудита
Создайте модель для представления аудиторской записи:
public class AuditUserAction
{
public Guid Id { get; set; }
public Guid CompanyId { get; set; }
public Guid UserId { get; set; }
public int Action { get; set; }
public string EntityAffected { get; set; }
public string DataBeforeAction { get; set; }
public string DataAfterAction { get; set; }
public DateTime ActionDateTime { get; set; }
public string IpAddress { get; set; }
public string BrowserName { get; set; }
}
2. Создание сервиса аудита
Создайте интерфейс и реализацию сервиса для аудита:
public interface IAuditService
{
Task LogAuditAction(AuditUserAction auditUserAction);
}
public class AuditService : IAuditService
{
private readonly IDbConnection _dbConnection;
public AuditService(IDbConnection dbConnection)
{
_dbConnection = dbConnection;
}
public async Task LogAuditAction(AuditUserAction auditUserAction)
{
var query = @"INSERT INTO Audit_User_Actions (id, company_id, user_id, action,
entity_affected, data_before_action, data_after_action,
action_date_time, ip_address, browser_name)
VALUES (@Id, @CompanyId, @UserId, @Action,
@EntityAffected, @DataBeforeAction,
@DataAfterAction, @ActionDateTime,
@IpAddress, @BrowserName)";
await _dbConnection.ExecuteAsync(query, auditUserAction);
}
}
3. Отправка данных аудита в сервисе
Вы можете вызывать метод LogAuditAction
в различных частях вашего приложения, как в контроллерах, так и в сервисах, чтобы сохранить записи аудита. Например, при выполнении действия логина:
public class UserService
{
private readonly IAuditService _auditService;
public UserService(IAuditService auditService)
{
_auditService = auditService;
}
public async Task Login(LoginRequest request)
{
// Логика аутентификации пользователя
var audit = new AuditUserAction
{
Id = Guid.NewGuid(),
CompanyId = /* Получаем id компании */,
UserId = /* Получаем id пользователя */,
Action = /* Код действия (например, логин) */,
EntityAffected = "User",
DataBeforeAction = null, // Можно сохранить информацию перед действием
DataAfterAction = /* Состояние данных после действия */,
ActionDateTime = DateTime.UtcNow,
IpAddress = /* Получаем IP адрес */,
BrowserName = /* Получаем имя браузера */
};
await _auditService.LogAuditAction(audit);
}
}
4. Инъекция зависимостей
Не забудьте зарегистрировать ваш сервис в контейнере зависимостей в Startup.cs
или программе конфигурации:
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IAuditService, AuditService>();
services.AddTransient<IDbConnection>(sp => new SqlConnection(Configuration.GetConnectionString("DefaultConnection")));
}
Заключение
В этой статье мы рассмотрели, как реализовать эффективную систему аудита в ASP.NET Core 8 Web API с использованием Dapper. Этот подход позволяет сохранить низкую степень связывания компонентов и обеспечить простоту масштабирования системы.
Таким образом, независимо от того, какие операции вы выполняете — от CRUD до комплексного управления пользователями — вы сможете отслеживать каждое действие и сохранять соответствующие записи в вашей базе данных. Это не только улучшит безопасность вашего приложения, но и обеспечит более высокий уровень контроля над изменениями, происходящими в нем.