Ho molti controller come questo:
public class EntityController : Controller
{
private readonly IEntityRepository _entity;
public EntityController(IEntityRepository entity)
{
_entity = entity;
}
[Authorize]
[HttpPut("{id}")]
public async ValueTask<IActionResult> Put(int id, [FromBody] Entity entity)
{
if (entity == null || entity.Id != id) return BadRequest();
var updated = await _entity.Update(entity);
if (updated == null) return NotFound();
return Ok(updated);
}
}
Devo implementare la cronologia di modifica delle entità (audit).
E, poiché il metodo è contrassegnato come [Authorize]
, devo accedere da quale utente è stato modificato. Sto guardando Audit.NET
, ma non ho trovato il modo di farlo.
Il provider EF Audit.NET consente di personalizzare l'entità di controllo prima di salvarla. Questo deve essere fatto all'avvio con una cosiddetta azione AuditEntity : un'azione che viene attivata per ogni entità modificata.
Quindi, puoi fare in modo che questa azione recuperi il nome utente dall'attuale HttpContext
e lo memorizzi in una proprietà UserName
sulle entità di controllo.
Sul tuo codice di avvio asp net, imposta un modo per ottenere l' HttpContext
corrente e configura l'azione per recuperare il nome utente dal contesto:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Add the HttpContextAccessor if needed.
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
// Get the service provider to access the http context
var svcProvider = services.BuildServiceProvider();
// Configure Audit.NET
Audit.Core.Configuration.Setup()
.UseEntityFramework(x => x
.AuditTypeNameMapper(typeName => "Audit_" + typeName)
.AuditEntityAction((evt, ent, auditEntity) =>
{
// Get the current HttpContext
var httpContext = svcProvider.GetService<IHttpContextAccessor>().HttpContext;
// Store the identity name on the "UserName" property of the audit entity
((dynamic)auditEntity).UserName = httpContext.User?.Identity.Name;
}));
}
}
Ciò presuppone che le entità di controllo abbiano una proprietà UserName
comune.
Se le entità di controllo ereditano già da un'interfaccia o una classe di base incluso UserName, è possibile utilizzare invece AuditEntityAction<T>
generico AuditEntityAction<T>
.
Audit.Core.Configuration.Setup()
.UseEntityFramework(x => x
.AuditTypeNameMapper(typeName => "Audit_" + typeName)
.AuditEntityAction<IUserName>((evt, ent, auditEntity) =>
{
var httpContext = svcProvider.GetService<IHttpContextAccessor>().HttpContext;
auditEntity.UserName = httpContext.User?.Identity.Name;
}));
Per ottenere UserID in IOC:
var userId = httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value