Reputation: 5002
I use Identity in core.
in startup.
services.AddSingleton<ICurrentUserService, CurrentUserService>();
services.AddHttpContextAccessor();
and in accountcontroller
[ApiController]
[Route("api/[controller]")]
public class AccountController : Controller
{
private readonly IApplicationUserManager _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
public AccountController
(IApplicationUserManager userManager,
SignInManager<ApplicationUser> signInManager)
{
_userManager = userManager;
//_roleManager = roleManager;
_signInManager = signInManager;
}
[HttpPost("Login")]
[AllowAnonymous]
public async Task<IActionResult> Login(LoginViewModel model)
{
try
{
await _signInManager.SignOutAsync();
var result = await _signInManager.PasswordSignInAsync(model.email, model.password, true, false);
if (result.Succeeded)
{
return Json(new { success = true});
}
var message = string.Join("; ", ModelState.Values
.SelectMany(x => x.Errors)
.Select(x => x.ErrorMessage));
return Json(new
{
success = false,
Message = message
});
}
catch (Exception e)
{
return Json(new
{
success = false,
Message = e.Message
});
}
}
[HttpPost("logout")]
public IActionResult LogOut()
{
try
{
_signInManager.SignOutAsync();
return Ok(new { success = true });
}
catch (Exception e)
{
return Ok(new { success = false, Message = e.Message });
}
}
}
}
and in CurrentUserService
public class CurrentUserService : ICurrentUserService
{
private readonly IHttpContextAccessor _httpContextAccessor;
public CurrentUserService(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public Guid? UserId => Guid.Parse(_httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier) ?? string.Empty);
public string FullName => _httpContextAccessor.HttpContext?.User?.FindFirstValue("FullName") != null
? _httpContextAccessor.HttpContext?.User?.FindFirstValue("FullName")
: _httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.Name);
public string Avatar => _httpContextAccessor.HttpContext?.User?.FindFirstValue("Avatar") != null
? _httpContextAccessor.HttpContext?.User?.FindFirstValue("Avatar")
: "/Themes/img/no_avatar.png";
}
but _httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier)
is null always.
Update :
I add this to startup
. it is ok.
app.UseAuthorization();
app.UseAuthentication();
Upvotes: 2
Views: 912
Reputation: 19136
If you want to access the IHttpContextAccessor
in your DbContext class and its overridden SavingChanges method, don't do it! Instead create a SaveChangesInterceptor
and then inject your services as usual:
public class AuditableEntitiesInterceptor : SaveChangesInterceptor
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly ILogger<AuditableEntitiesInterceptor> _logger;
public AuditableEntitiesInterceptor(
IHttpContextAccessor httpContextAccessor,
ILogger<AuditableEntitiesInterceptor> logger)
{
_httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
Then you should register your new interceptor:
services.AddSingleton<AuditableEntitiesInterceptor>();
And finally add it/introduce it to EF-Core this way:
services.AddDbContextPool<ApplicationDbContext>((serviceProvider, optionsBuilder) =>
optionsBuilder.AddInterceptors(serviceProvider.GetRequiredService<AuditableEntitiesInterceptor>());
Upvotes: 9