EF Core: Get Authenticated username in Shadow Properties

.net-core asp.net-web-api c# entity-framework entity-framework-core

Question

As a part of logging who entered/updated the data I am adding 4 common fields (Created By, Created Date, Modified By, Modified Date) in all entities. For this, I am using shadow properties feature suggested in multiple forums including https://dotnetcore.gaprogman.com/2017/01/26/entity-framework-core-shadow-properties/

My question is how do I get information about authenticated user ?. If it was a controller I could access ApplicationUserManager but in this case the shadow properties are in

AppDbContext : IdentityDbContext class.

This is a asp.net core 2 web API project.

Any suggestion is highly appreciated. Thanks

1
8
2/1/2018 2:36:57 AM

Accepted Answer

You can get the current user's name using HttpContext.User.Identity.Name. You can access the HttpContext using IHttpContextAccessor. This interface should already be registered in the service collection. Otherwise, you can register it:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    services.AddDbContext<ApplicationDbContext>(options =>
         options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
    // ...
}

Then, you can use this interface from the DbContext:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, IHttpContextAccessor httpContextAccessor)
        : base(options)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default(CancellationToken))
    {
        var httpContext = _httpContextAccessor.HttpContext;
        if(httpContext != null)
        {
            var authenticatedUserName = httpContext.User.Identity.Name;

            // If it returns null, even when the user was authenticated, you may try to get the value of a specific claim 
            var authenticatedUserId = _httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value
            // var authenticatedUserId = _httpContextAccessor.HttpContext.User.FindFirst("sub").Value

            // TODO use name to set the shadow property value like in the following post: https://www.meziantou.net/2017/07/03/entity-framework-core-generate-tracking-columns
        }

        return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
    }
}
12
3/19/2019 9:15:39 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow