我正在使用ASP.NET MVC Core的自定义身份验证,它不使用Identity
。这是Startup.cs
:
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 :(得分:12)
对于ASP.Net Core 2.0,我在Startup.Configure()
中添加了app.UseAuthentication();
,并为我解决了此错误。
参考:Auth 2.0 Migration announcement
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action=Index}/{id?}");
});
}
注意:请务必在Startup.Configure()
中致电UseAuthentication()
之前致电UseMvc()
,如评论中所述。
在Configure方法中添加中间件组件的顺序定义了它们在请求时调用的顺序,以及响应的相反顺序。此排序对于安全性,性能和功能至关重要。
来源ASP.NET Core Docs - &gt; Middleware - &gt; Ordering