如何解决Cookie 身份验证失败 ASP.NET Core 3.1
我没有将现有的 ASP.NET Core 2.1 项目迁移到 3.1,而是创建了一个新项目。在新项目中,SignIn(...) 控制器方法执行没有错误,但随后无法重定向到指定的操作。相反,它重定向到 AccessDeniedpath。
我的环境是使用 Chrome 的 Win10 VS 2019 IIS Express。
谁能告诉我是什么原因造成的?我在 3.1 中有什么遗漏或做错了吗?
PROGRAM.CS
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
//webBuilder.UseIISIntegration();
//webBuilder.UseKestrel();
//webBuilder.CaptureStartupErrors(true);
//webBuilder.UseEnvironment(Environments.Development);
});
STARTUP.CS
public void ConfigureServices(IServiceCollection services)
{
try
{
services.AddRazorPages()
.AddRazorRuntimeCompilation();
services.AddControllersWithViews();
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,options =>
{
options.ExpireTimeSpan = new TimeSpan(30,0);
options.LoginPath = new PathString("/Home/Index/");
options.AccessDeniedpath = new PathString("/Home/Index/");
options.logoutPath = new PathString("/Home/Index/");
options.Validate();
});
services.Configure<Microsoft.AspNetCore.Identity.IdentityOptions>(options =>
{
options.Password.requiredigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireNonAlphanumeric = true;
options.Password.RequireUppercase = true;
options.Password.requiredLength = 8;
options.Password.requiredUniqueChars = 1;
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
options.Lockout.MaxFailedAccessAttempts = 5;
options.Lockout.AllowedForNewUsers = true;
options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMnopQRSTUVWXYZ0123456789-._@+";
});
services.AddDetectionCore()
.AddDevice();
services.AddMvc();
services.AddAntiforgery();
services.Configure<Mvcoptions>(options =>
{
options.Filters.Add(new RequireHttpsAttribute());
});
}
catch (Exception ex)
{
gFunc.ProcessError(ex);
}
}
public void Configure(IApplicationBuilder app,IWebHostEnvironment env)
{
try
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseStaticFiles();
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseAuthentication();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
catch (Exception ex)
{
gFunc.ProcessError(ex);
}
}
CONTROLLER.CS
[HttpPost()]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> SignIn(SignIn sin)
{
bool is_err = false;
try
{
// check data
if (string.IsNullOrEmpty(sin.EmailAddress))
{
is_err = true;
ModelState.AddModelError("Samadhi","Missing email address.");
}
if (string.IsNullOrEmpty(sin.Password))
{
is_err = true;
ModelState.AddModelError("Samadhi","Missing password.");
}
// check authorisation
if (ModelState.IsValid && !is_err)
{
sin = await RepoSamadhi.ShopSignIn(sin);
if (sin.ShopID == 0 || sin.IsValidationFail || string.IsNullOrEmpty(sin.ShopToken))
{
is_err = true;
ModelState.AddModelError("Samadhi","Account not found. Check your credentials.");
}
}
// check model state
if (!ModelState.IsValid || is_err)
{
sin.IsSignInFailed = true;
return View("SignIn",sin);
}
// create claims
var claims = new List<Claim>
{
new Claim(ClaimTypes.Sid,sin.ShopToken),new Claim(ClaimTypes.NameIdentifier,sin.ShopID.ToString()),new Claim(ClaimTypes.Email,sin.EmailAddress.ToLower()),new Claim(ClaimTypes.Role,"SamadhiShop")
};
// create identity
var identity = new ClaimsIdentity(claims,CookieAuthenticationDefaults.AuthenticationScheme);
// create principal
ClaimsPrincipal principal = new ClaimsPrincipal(new ClaimsIdentity(claims,CookieAuthenticationDefaults.AuthenticationScheme));
var authProperties = new AuthenticationProperties
{
IsPersistent = true // sin.RememberMe
};
// sign-in
await HttpContext.SignInAsync(scheme: CookieAuthenticationDefaults.AuthenticationScheme,principal: principal,properties: authProperties);
}
catch (Exception ex)
{
gFunc.ProcessError(ex);
}
return RedirectToAction("Console",new { date = DateTime.Today.ToString("d MMM yyyy"),timer = false });
}
[HttpGet]
[Authorize]
public async Task<ActionResult> Console(string date,bool timer)
{
int shop_id = int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value);
string token = User.FindFirst(ClaimTypes.Sid).Value;
DateTime dt = DateTime.Parse(date);
Shop ss = await RepoSamadhi.GetShop(shop_id,token,dt);
ss.IsTimerOn = timer;
return View((_device.Type == DeviceType.Mobile) ? "ConsoleM" : "ConsoleM",ss);
}
解决方法
你中间件的顺序不对,正确的应该是
app.UseAuthentication();
app.UseAuthorization();
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。