我正在编写一个 Asp.Net 核心应用程序,并且在获得导航访问权限之前让用户通过 Google 进行身份验证。当用户导航到我的“WorldBuilder”区域并点击 WorldController 时,BaseController.User 对象为 null。这是迄今为止我设置的唯一区域/控制器。
用户在登录时有效,因为我可以迭代与用户关联的声明。我使用默认的 Asp.Net core google 身份验证,因此用户只会在登录页面上收到一个按钮,指示他们通过 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;
}
我希望由于这些区域是同一应用程序的一部分,因此经过身份验证的用户信息将在区域之间传递,但情况似乎并非如此。 BaseController.User 对象为 null
您应该只访问User
财产(以及其他,例如HttpContext
)从您的控制器的操作中。控制器是在执行身份验证和授权之前构建的,因此属性为空。
如果您需要对用户 ID 进行常规访问,您可以在控制器上创建一个属性,您可以在其中从用户对象检索用户 ID,并在操作中使用该属性。您甚至可以将此属性移至基类,并使用该类作为基控制器,以便从每个控制器访问该属性。
例如:
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;
}
}
}
以及您的特定控制器:
public class WorldController : ControllerBase
{
// Contructor, etc...
public IActionResult Get()
{
var userId = UserId;
// Do something with userId (or use UserId directly)
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)