为什么在加载区域控制器时我的BaseController.User值== null?

时间:2019-02-18 10:28:24

标签: c# asp.net-core asp.net-core-mvc

我正在编写一个Asp.Net核心应用程序,在获得导航访问权限之前,我已先让用户向Google进行身份验证。当用户导航到我的“ WorldBuilder”区域并单击WorldController时,BaseController.User对象为null。这是我到目前为止设置的唯一区域/控制器。

登录后该用户有效,因为我可以遍历与该用户关联的Claims。我使用的是默认的Asp.Net核心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

2 个答案:

答案 0 :(得分:1)

您只应在控制器的操作内访问User属性(以及其他HttpContext)。该控制器是在执行身份验证和授权之前构造的,因此属性为null。

如果需要对用户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)
    }

}

答案 1 :(得分:-1)

您可以使用 HttpContextAccessor HttpContext 向下传递到区域,存储库

有关如何使用 HttpContextAccessor 并在此处使用依赖注入进行设置的更多信息

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-context?view=aspnetcore-2.2#use-httpcontext-from-custom-components