I'm writing an Asp.Net core application and I have the user authenticate with Google prior to gaining navigation access. When the user navigates to my "WorldBuilder" area and hits the WorldController, the BaseController.User object is null. This is the only area/controller I have set up so far.
The user is valid when the log in, as I can iterate over the Claims associated with the user. I am using the default Asp.Net core google authentication, so the user just receives a button on the login page directing them to authenticate with Google.
[Authorize]
[Area("WorldBuilder")]
public class WorldController : Controller
{
private string _userId;
private IWorldService _worldService;
private IUserRepository _userRepository;
public WorldController(IWorldService worldService, IUserRepository userRepository)
{
if (User != null) /* The user object is found to be null here. */
{
var userIdNameClaim = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier);
if (userIdNameClaim != null)
{
_userId = userIdNameClaim.Value;
}
}
_userRepository = userRepository;
_worldService = worldService;
}
I would expect that since the areas are part of the same application that the authenticated user information would be passed between areas, however that does not appear to be the case. The BaseController.User object is null
You should only access the User property (and others such as HttpContext) from within actions of your controller. The controller is constructed before authentication and authorization have been performed, hence the properties are null.
If you need general access to the User ID, you could create a property on the controller where you retrieve the User ID from the user object and use that property from your actions. You can even move this property to a base class and use that class as base controller to have access to the property from each controller.
For example:
public class ControllerBase : Controller
{
public string UserId
{
get
{
if (User != null) /* The user object is found to be null here. */
{
var userIdNameClaim = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier);
if (userIdNameClaim != null)
{
return userIdNameClaim.Value;
}
}
return null;
}
}
}
And your specific controller:
public class WorldController : ControllerBase
{
// Contructor, etc...
public IActionResult Get()
{
var userId = UserId;
// Do something with userId (or use UserId directly)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With