2017-07-19 172 views
4

我正在使用ASP.NET MVC Core的自定义身份验证,该身份验证未使用Identity。这是Startup.cs用户授权失败:(null)

public class Startup 
{ 
    public IConfiguration Configuration { get; set; } 

    // Configure IoC container 
    // https://docs.asp.net/en/latest/fundamentals/dependency-injection.html 
    public void ConfigureServices(IServiceCollection services) 
    { 
     services.Configure<AppSettings>(options => Configuration.GetSection(nameof(AppSettings)).Bind(options)); 

     // https://docs.asp.net/en/latest/security/anti-request-forgery.html 
     services.AddAntiforgery(options => options.CookieName = options.HeaderName = "X-XSRF-TOKEN"); 

     services.AddDbContext<DbSesamContext>(options => 
     { 
      options.UseSqlServer(Configuration.GetConnectionString("SesamConnection")); 
     }); 

     services.AddDbContext<TerminalDbContext>(options => 
     { 
      options.UseSqlServer(Configuration.GetConnectionString("TerminalConnection")); 
     }); 

     services.AddMvcCore() 
      .AddAuthorization() 
      .AddViews() 
      .AddRazorViewEngine() 
      .AddJsonFormatters(); 
    } 

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory factory) 
    { 
     // Configure logging 
     // https://docs.asp.net/en/latest/fundamentals/logging.html 
     factory.AddConsole(Configuration.GetSection("Logging")); 
     factory.AddDebug(); 

     // Serve static files 
     // https://docs.asp.net/en/latest/fundamentals/static-files.html 
     app.UseStaticFiles(); 

     // Enable external authentication provider(s) 
     // https://docs.asp.net/en/latest/security/authentication/sociallogins.html 
     //app.UseIdentity(); 

     app.UseCookieAuthentication(new CookieAuthenticationOptions() 
     { 
      AuthenticationScheme = "ResWebAuth", 
      LoginPath = new PathString("/login"), 
      AccessDeniedPath = new PathString("/unauthorized/"), 
      AutomaticAuthenticate = true, 
      AutomaticChallenge = true, 
     }); 

     // Configure ASP.NET MVC 
     // https://docs.asp.net/en/latest/mvc/index.html 
     app.UseMvc(routes => 
     { 
      routes.MapRoute("default", "{*url}", new { controller = "Home", action = "Index" }); 
     }); 
    } 

    public static void Main() 
    { 
     var cwd = Directory.GetCurrentDirectory(); 
     var web = Path.GetFileName(cwd) == "server" ? "../public" : "public"; 

     var host = new WebHostBuilder() 
      .UseContentRoot(Directory.GetCurrentDirectory()) 
      .UseWebRoot(web) 
      .UseKestrel() 
      .UseIISIntegration() 
      .UseStartup<Startup>() 
      .Build(); 

     host.Run(); 
    } 
} 

,并在我的控制器:

[Authorize] 
public class HomeController : Controller 
{ 
    public async Task<IActionResult> Index() 
    { 
     ... 

     return View(); 
    } 

    [HttpGet("login")] 
    [AllowAnonymous] 
    public async Task<IActionResult> Login(string ReturnUrl) 
    { 
     ... 

     return View(); 
    } 

    [HttpPost("login")] 
    [AllowAnonymous] 
    public async Task<IActionResult> Login(LoginInfo loginInfo) 
    { 
     if (LoginUser(loginInfo.Username, loginInfo.Password)) 
     { 
      var claims = new List<Claim> 
       { 
        new Claim(ClaimTypes.Name, loginInfo.Username), 
        new Claim("DbVersion", loginInfo.Terminal.SesamDbVersion), 
        new Claim("DbUrl", loginInfo.Terminal.SesamDbUrl), 
        new Claim("DbName", loginInfo.Terminal.SesamDbName), 
        new Claim("DbUsername", loginInfo.Terminal.SesamDbUserName), 
        new Claim("DbPasswordHash", loginInfo.Terminal.SesamDbPasswordHash), 
       }; 

      var userIdentity = new ClaimsIdentity(claims, "login"); 

      ClaimsPrincipal principal = new ClaimsPrincipal(userIdentity); 
      await HttpContext.Authentication.SignInAsync("ResWebAuth", principal); 

      //Just redirect to our index after logging in. 
      return Redirect("/"); 
     } 
     return View(); 
    } 

    [HttpGet("getchartdata")] 
    //[AllowAnonymous] 
    public JsonResult GetChartData() 
    { 
     ... 
    } 

日志:

info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware[3] 
     HttpContext.User merged via AutomaticAuthentication from authenticationScheme: ResWebAuth. 
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[1] 
     Authorization was successful for user: admin. 

... 

info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1] 
     Request starting HTTP/1.1 GET http://localhost:5000/getchartdata/ 
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] 
     Authorization failed for user: (null). 
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1] 
     Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'. 
info: Microsoft.AspNetCore.Mvc.ChallengeResult[1] 
     Executing ChallengeResult with authentication schemes(). 
info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware[12] 
     AuthenticationScheme: ResWebAuth was challenged. 
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2] 
     Executed action Server.Controllers.HomeController.GetChartData (server) in 5.2905ms 
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2] 
     Request finished in 10.1037ms 302 

所以基本上是成功的授权用户在控制器的Index()方法,但不在同一控制器的GetChartData()方法中这样做。

Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[1]Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]之间似乎有区别,我不明白它是什么以及如何解决它。

+0

你为什么不使用'AddMvc',而是调用'AddMvcCore'?下面的调用是做'AddMvc'的,所以没有理由在这里使用'AddMvcCore' –

+0

这是默认从[样板](https://github.com/kriasoft/aspnet-starter-kit)用过的。 –

+0

你可以在没有构造函数的情况下发布完整的启动类吗? –

回答