我有一个使用2.1版的简单asp.net-core应用程序。 HomeController的页面具有授权属性。当我单击需要授权的关于页面时,进入登录页面,输入用户名和密码后,将发生以下情况:
我也尝试过使用Chrome和Edge。我可以在两个浏览器上重现该错误。
我创建了一个小型repro项目,该项目可以在机器和设置上重现该问题。
我用来重现该问题的步骤如下:
我想知道为什么会发生这种情况以及如何纠正这种情况?谢谢你帮我欢迎所有反馈。
HomeController:
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
[Authorize]
public IActionResult About()
{
ViewData["Message"] = "Your application description page.";
return View();
}
}
我的Startup.cs看起来如下:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
// services.AddAuthentication();
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.LoginPath = "/Account/LogIn";
options.LogoutPath = "/Account/LogOff";
});
// Add application services.
services.AddTransient<IEmailSender, EmailSender>();
services.AddMvc()
.AddFeatureFolders(); // .SetCompatibilityVersion(CompatibilityVersion.Version_2_1); ;
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseBrowserLink();
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
这是我在Visual Studio的输出窗口中看到的日志:
Microsoft.EntityFrameworkCore.Database.Command:Information: Executed DbCommand (1ms) [Parameters=[@__normalizedUserName_0='?' (Size = 256)], CommandType='Text', CommandTimeout='30']
SELECT TOP(1) [u].[Id], [u].[AccessFailedCount], [u].[ConcurrencyStamp], [u].[Email], [u].[EmailConfirmed], [u].[LockoutEnabled], [u].[LockoutEnd], [u].[NormalizedEmail], [u].[NormalizedUserName], [u].[PasswordHash], [u].[PhoneNumber], [u].[PhoneNumberConfirmed], [u].[SecurityStamp], [u].[TwoFactorEnabled], [u].[UserName]
FROM [AspNetUsers] AS [u]
WHERE [u].[NormalizedUserName] = @__normalizedUserName_0
Microsoft.EntityFrameworkCore.Database.Command:Information: Executed DbCommand (2ms) [Parameters=[@__user_Id_0='?' (Size = 450)], CommandType='Text', CommandTimeout='30']
SELECT [uc].[Id], [uc].[ClaimType], [uc].[ClaimValue], [uc].[UserId]
FROM [AspNetUserClaims] AS [uc]
WHERE [uc].[UserId] = @__user_Id_0
Microsoft.EntityFrameworkCore.Database.Command:Information: Executed DbCommand (1ms) [Parameters=[@__userId_0='?' (Size = 450)], CommandType='Text', CommandTimeout='30']
SELECT [role].[Name]
FROM [AspNetUserRoles] AS [userRole]
INNER JOIN [AspNetRoles] AS [role] ON [userRole].[RoleId] = [role].[Id]
WHERE [userRole].[UserId] = @__userId_0
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler:Information: AuthenticationScheme: Identity.Application signed in.
Portfolio.Features.Account.AccountController:Information: User logged in.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action method Portfolio.Features.Account.AccountController.Login (Portfolio), returned result Microsoft.AspNetCore.Mvc.RedirectResult in 32.6215ms.
Microsoft.AspNetCore.Mvc.Infrastructure.RedirectResultExecutor:Information: Executing RedirectResult, redirecting to /Home/About.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action Portfolio.Features.Account.AccountController.Login (Portfolio) in 41.5571ms
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 49.3022ms 302
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:44392/Home/About
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Route matched with {action = "About", controller = "Home"}. Executing action Portfolio.Features.Home.HomeController.About (Portfolio)
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Information: Authorization was successful.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executing action method Portfolio.Features.Home.HomeController.About (Portfolio) - Validation state: Valid
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action method Portfolio.Features.Home.HomeController.About (Portfolio), returned result Microsoft.AspNetCore.Mvc.ViewResult in 2212.7896ms.
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor:Information: Executing ViewResult, running view About.
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor:Information: Executed ViewResult - view About executed in 3.1424ms.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action Portfolio.Features.Home.HomeController.About (Portfolio) in 2225.297ms
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 2233.0907ms 200 text/html; charset=utf-8
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:44392/Account/Login?ReturnUrl=%2FHome%2FAbout
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Route matched with {action = "Login", controller = "Account"}. Executing action Portfolio.Features.Account.AccountController.Login (Portfolio)
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executing action method Portfolio.Features.Account.AccountController.Login (Portfolio) with arguments (/Home/About) - Validation state: Valid
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler:Information: AuthenticationScheme: Identity.External signed out.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action method Portfolio.Features.Account.AccountController.Login (Portfolio), returned result Microsoft.AspNetCore.Mvc.ViewResult in 1528.1878ms.
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor:Information: Executing ViewResult, running view Login.
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor:Information: Executed ViewResult - view Login executed in 5.8984ms.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action Portfolio.Features.Account.AccountController.Login (Portfolio) in 1543.8386ms
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 1553.3133ms 200 text/html; charset=utf-8
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:44392/lib/bootstrap/dist/css/bootstrap.css
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:44392/css/site.css
Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware:Information: Sending file. Request path: '/css/site.css'. Physical path: 'C:\dev\web\portfolio-variants\Portfolio_Controller_V2\Portfolio\wwwroot\css\site.css'
Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware:Information: Sending file. Request path: '/lib/bootstrap/dist/css/bootstrap.css'. Physical path: 'C:\dev\web\portfolio-variants\Portfolio_Controller_V2\Portfolio\wwwroot\lib\bootstrap\dist\css\bootstrap.css'
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 28.4192ms 200 text/css
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 41.4384ms 200 text/css
答案 0 :(得分:2)
在您的Github项目中,您有一个site.js
文件,其中包含(除其他事项外)以下jQuery事件处理程序:
$('form[method=post]').not('.no-ajax').on('submit', function () {
...
$.ajax({
url: $this.attr('action'),
...
statusCode: {
200: redirect
},
...
}).error(highlightErrors);
return false;
}
提交登录表单时,最终将运行上述代码块,然后为redirect
中的statusCode
调用200
回调函数,如下所示:< / p>
var redirect = function (data) {
if (data.redirect) {
window.location = data.redirect;
} else {
window.scrollTo(0, 0);
window.location.reload();
}
};
在您描述的场景中,data.redirect
是undefined
。在这种情况下,您最终会调用window.location.reload()
,它当然会重新加载登录页面并明确说明您遇到的问题。
这是发生的情况的分步细分:
/Home/About
。/Home/About
页拉出HTML。redirect
回调被调用,其中data
代表对/Home/About
页面的响应(text/html
响应)。/Account/Login
页面上,如上所述,页面已重新加载。由于如何设置第一个代码段中显示的jQuery选择器,您可以简单地将no-ajax
类添加到您的登录表单中,即可正常工作。
答案 1 :(得分:1)
您还应该在启动文件的services.AddAuthentication
方法中调用ConfigureServices
。
对AddAuthentication
的调用应根据您的应用程序需求进行配置。 (Cookie,外部登录名等)
即使您没有从1.x迁移到2.x,以下文章我也认为它非常有用:Migrate authentication and Identity to ASP.NET Core 2.0。
答案 2 :(得分:1)
答案 3 :(得分:0)
您没有在启动类的Configure方法中使用此中间件。
app.UseAuthorization();
将此中间件放在app.UseAuthentication();
之后