BaseController 上的 OWIN Auth HTTPContext NULL

OWIN Auth HTTPContext NULL on BaseController

尝试创建一个在我的整个网站上继承的基本控制器,因为它会根据用户角色动态加载导航栏。

问题是它似乎总是加载并尝试获取用户角色,即使 owin 尚未加载且用户尚未登录也是如此。

下面是名为 LayoutController 的 BaseController

 [Authorize]
public class LayoutController : Controller
{
    public List<NavigationMenuModel> MainLayoutViewModel { get; set; }

    public LayoutController()
    {
        this.MainLayoutViewModel = new List<NavigationMenuModel>();
        using (var context = new OperationalDataContext())
        {
     //The BELOW LINE IS ISSUE
            var username = HttpContext.GetOwinContext().Authentication.User.Identity.Name;
            var pages = context.GET_PAGES_BY_USERNAME(username);
            var pagesTop = pages.Where(x => x.Parent == null);
            foreach (var page in pagesTop)
            {
                var tmpNM = new NavigationMenuModel();
                tmpNM.DisplayName = page.Name;
                tmpNM.RelativeUrl = page.RelativeUrl;
                var children = pages.Where(x => x.Parent != null && x.Parent.Equals(page.Name) && x.Site.Equals("PRODUCT"));
                List<NavigationMenuModel> tmpChildren = new List<NavigationMenuModel>();
                foreach (var child in children)
                {
                    var tmpC = new NavigationMenuModel();
                    tmpC.DisplayName = child.Name;
                    tmpC.RelativeUrl = child.RelativeUrl;
                    var children1 = pages.Where(x => x.Parent != null && x.Parent.Equals(child.Name) && x.Site.Equals("PRODUCT"));
                    List<NavigationMenuModel> tmpChildren1 = new List<NavigationMenuModel>();
                    foreach (var child1 in children)
                    {
                        var tmpC1 = new NavigationMenuModel();
                        tmpC1.DisplayName = child1.Name;
                        tmpC1.RelativeUrl = child1.RelativeUrl;
                        tmpChildren1.Add(tmpC1);
                    }
                    tmpC.Children = tmpChildren1;
                }
                tmpNM.Children = tmpChildren;
                this.MainLayoutViewModel.Add(tmpNM);
            }
        }
        this.ViewBag["MainLayoutViewModel"] = this.MainLayoutViewModel;
    }
}

然后是dashboardController(主页)

 public class DashboardController : LayoutController
{
    // GET: Dashboard
    public ActionResult Index()
    {
        return View("Index");
    }
}

我们有一个简单的基于 cookie 的登录,允许匿名

 public class AccountController : Controller
{
    IAuthenticationManager AuthenticationManager
    {
        get { return HttpContext.GetOwinContext().Authentication; }
    }

    [HttpGet]
    [AllowAnonymous]
    [Route("login")]
    public ActionResult Login()
    {
        return View("Login");
    }
 }
}

在startup.css

public void ConfigureAuthentication(IAppBuilder app)
    {
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Login"),
        });
    }

问题似乎是它在尝试进入布局之前没有重定向到登录。

AccountController 没有引用 LayoutController。

问题是,您正在控制器的构造函数中执行您正在执行的操作。

如果用户已登录,Authorize 属性会检查每个方法,如果没有,则重定向 him/her 到登录页面。构造函数代码在创建控制器时执行 - 在调用任何方法之前执行。

覆盖 LayoutController 上的 OnActionExecuting 并将构造函数代码移到那里。我不太确定 Authorize 属性是否在执行 之前拦截对控制器方法的调用 OnActionExecuting 被执行,但我会试一试。

顺便说一句:AllowAnonymous 用于反转单个方法的控制器 Authorize 属性。所以如果你的 AccountController 没有设置这个属性,那么 AllowAnonymous 就没有用了。但这有点跑题了。

希望对您有所帮助。