Resolve No owin.Environment item was found in the

2019-07-10 03:59发布

问题:

I have found many threads discussing this problem but getting any of them to work has eluded me so far.

I have been trying to follow ProDinner as a way of learning how to implement role based authentication in my app. But I cannot work out what I am missing. Every time I try to log in I get

No owin.Environment item was found in the context

After a lot of debugging and searching I have found the Startup class is not being called. I've tried to resolve by stepping through the proDinner code to see, how Startup is being called and googled (a lot!). My searches lead me to adding (although neither exist in the proDinner project)

<add key="owin:AutomaticAppStartup" value="Tjs.Startup, Tjs" />

then

<add key="owin:AutomaticAppStartup" value="Tjs.Web.Admin.Startup, Tjs" />

Below I have added all of what I believe is the relevant code, but please let me know if I am missing anything.

The AccountController is a copy paste of ProDinner, with the addition of a parameterless constructor, I was unable to work out how that parameter is being passed in the Prodinner project (could that be the problem?)

Tjs: solution name

Tjs.Web.Admin: namespace

Owin packages

<package id="Microsoft.Owin" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Host.SystemWeb" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Security" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Security.Cookies" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Security.OAuth" version="3.0.1" targetFramework="net45" />

root of project

using Microsoft.Owin;
using Owin;

using Tjs.Web.Admin;
using Tjs.Web.Admin.App_Start;

[assembly: OwinStartup(typeof(Startup))]
namespace Tjs.Web.Admin
{
  public class Startup
  {
    public void Configuration(IAppBuilder app)
    {
        OwinConfig.ConfigureAuth(app);
    }
  }
}

App_Start

using Microsoft.AspNet.Identity;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Owin;
namespace Tjs.Web.Admin.App_Start
{
  public static class OwinConfig
  {
    public static void ConfigureAuth(IAppBuilder app)
    {
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/SignIn")
        });
    }
  }
}

AccountController

    private readonly IUserService userService;
    public AccountController()
    {

    }

    public AccountController(IUserService userService)
    {
        this.userService = userService;
    }

    private IAuthenticationManager Authentication
    {
        get
        {
            return HttpContext.GetOwinContext().Authentication;
        }
    }

    private void SignInOwin(string name, bool rememberMe, string role)
    {
        var identity = new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, name) },
            DefaultAuthenticationTypes.ApplicationCookie,
                ClaimTypes.Name, ClaimTypes.Role);

        //foreach (var role in roles)
        //{
        //    identity.AddClaim(new Claim(ClaimTypes.Role, role));
        //}
        identity.AddClaim(new Claim(ClaimTypes.Role, role));

        Authentication.SignIn(new AuthenticationProperties
        {
            IsPersistent = rememberMe
        }, identity);
    }

    public ActionResult SignIn()
    {
        return View(new SignIn { Email = "o", Password = "1" });
    }

    [HttpPost]
    public ActionResult SignIn(SignIn input)
    {
        if (!ModelState.IsValid)
        {
            input.Password = null;
            input.Email = null;
            return View(input);
        }

        Staff staff;

        //ACHTUNG: remove this in a real app
        if (input.Email == "o" && input.Password == "1")
        {
            staff = new Staff { Email = "o", Role = new Role { Description = "admin" } };
        }
        else
        {
            staff = userService.Get(input.Email, input.Password);
        }

        if (staff == null)
        {
            ModelState.AddModelError("", "Try Login: o and Password: 1");
            return View();
        }

        SignInOwin(staff.Email, input.Remember, staff.Role.Description);


        return RedirectToAction("index", "home");
    }

    public ActionResult SignOff()
    {
        Authentication.SignOut();
        return RedirectToAction("SignIn", "Account");
    }
}

it fails at

private IAuthenticationManager Authentication
{
    get
    {
        return HttpContext.GetOwinContext().Authentication;
    }
}

回答1:

Add this to your web.config <appSettings><add key="owin:AppStartup" value="[Namespace].Startup, [AssemblyName]" /></appSettings>



回答2:

I've added into the "web.config"

<modules runAllManagedModulesForAllRequests="true">


回答3:

I had the same issue and I added a new key owin:AutomaticAppStartup to WebConfig in order to the Startup class to be loaded automatically.

<add key="owin:AppStartup" value="[Namespace].Startup,[AssemblyName]" />
<add key="owin:AutomaticAppStartup" value="true"/>