我确实找到了类似的问题,但是所提供的答案都没有帮助我。
我确实按照教程将身份添加到我的ASP.net Core 2.2项目(https://retifrav.github.io/blog/2018/03/20/csharp-dotnet-core-identity-mysql/)
即使SignInManager.PasswordSignInAsync()成功,但_Layout视图中的User.Identity.IsAuthenticated和SignInManager.IsSignedIn(User)均为假。
_Layout.cshtml:
@using Microsoft.AspNetCore.Identity
@inject SignInManager<MySiteUser> SignInManager
@inject UserManager<MysiteUser> UserManager
......................
<div>
@if (SignInManager.IsSignedIn(User))
{
<div>Hello @UserManager.GetUserName(User)!</div>
}
@if (User.Identity.IsAuthenticated)
{
<div>User is authenticated </div>
}
</div>
在Startup.CS的ConfigureServices中,我有:
services.AddIdentity<MySiteUSer, MySiteRole>().AddEntityFrameworkStores<IdentityContext>().AddDefaultTokenProviders();
services.Configure<IdentityOptions>(options =>
{
options.Password.RequireDigit = true;
options.Password.RequiredLength = 8;
options.Password.RequireNonAlphanumeric = true;
options.Password.RequireUppercase = true;
options.Password.RequireLowercase = true;
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
options.Lockout.MaxFailedAccessAttempts = 10;
options.User.RequireUniqueEmail = true;
});
services.ConfigureApplicationCookie(options => options.LoginPath = "/Account/Login");
services.AddMvc();
在Startup.CS的Configure()中,我有:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider services)
{
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication(); ;
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
在AccountController中,我有:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
returnUrl = returnUrl ?? Url.Content("~/");
if (ModelState.IsValid)
{
var result = await _signInManager.PasswordSignInAsync(model.Username, model.Password, model.RememberMe, lockoutOnFailure: false);
if (result.Succeeded)
{
_logger.LogInformation("User logged in.");
var user = await _signInManager.UserManager.FindByNameAsync(model.Username);
var userPrincipal = await _signInManager.CreateUserPrincipalAsync(user);
var identity = userPrincipal.Identity;
if(identity.IsAuthenticated)
return RedirectToAction("Index", "Home");
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View(model);
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
MySiteUser和MySiteRole只是覆盖默认的Identity类
public class MySiteUser : IdentityUser<int>
{
}
public class MySiteRole : IdentityRole<int>
{
}
编辑:
由于所有答复都是关于控制器的,因此在此之前,我在AccountController中使用了以下代码
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
returnUrl = returnUrl ?? Url.Content("~/");
if (ModelState.IsValid)
{
var result = await _signInManager.PasswordSignInAsync(model.Username, model.Password, model.RememberMe, lockoutOnFailure: false);
if (result.Succeeded)
{
return RedirectToAction("Index", "Home");
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View(model);
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
结果相同。
答案 0 :(得分:0)
在将用户重定向到首页之前,您无需检查if(identity.IsAuthenticated)
。如果代码到达(result.Succeeded)
块,则表示用户已通过身份验证。 if(identity.IsAuthenticated)
仅在请求结束时为true,表示您已返回HttpResponse
(或其他内容),它将在客户端创建cookie。
因此解决方案是删除Login
动作中的条件。
/*if(identity.IsAuthenticated) <===== remove this */
return RedirectToAction("Index", "Home");
编辑:请不要忘记,当您使用RedirectToAction
时,它仍然是相同的请求,因此尚未创建cookie。相反,请像往常一样创建和使用临时成功视图。
/*if(identity.IsAuthenticated) <===== remove this */
return RedirectToAction("Index", "Home"); <===== remove this */
/*put url in viewbag or use returnUrl variable*/
@ViewBag.ReturnUrl = Url.Action("index","home"/*,null,Request.Url.Scheme*/);
return View("LoginSuccess");
这是要放入 LoginSuccess.cshtml 视图中的内容
<h2>Authenticated. Wait 2 seconds or click continue</h2>
<p><a href="@ViewBag.ReturnUrl">
Continue</a></p>
<script>
setTimeout(function () {
window.location = "@ViewBag.ReturnUrl";
}, 2000)
</script>
PS:您可能需要使用局部视图,以避免与布局页面标题冲突... return PartialView("LoginSuccess");
答案 1 :(得分:0)
我只是找到了一个解决方案,尽管我不明白它为什么起作用。我已经检查了Chrome开发者工具,看看是否设置了身份验证Cookie。 在删除网站的所有cookie后,该应用程序设置了cookie,并且一切正常。
我还测试了更简单的AccountController
,它也可以正常工作:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
returnUrl = returnUrl ?? Url.Content("~/");
if (ModelState.IsValid)
{
var result = await _signInManager
.PasswordSignInAsync(model.Username, model.Password,
Model.RememberMe, lockoutOnFailure: false);
if (result.Succeeded)
{
return RedirectToAction("Index", "Home");
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View(model);
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
答案 2 :(得分:0)
我相信我已经迷失了这个答案。首先在IE中尝试此方法,它可能在那里工作。显然,Chrome浏览器对于用于身份验证的Cookie非常挑剔,除非您在HTTPS中与之对话。如果您正在开发中,并且正在使用HTTP和Chrome,则IsSignedIn(User) 可能会失败。令人难以置信的是,这令人讨厌,并且会大大降低生产率。 HTH