如何在ASP.NET Core 2.0中实现每次请求校验认证并跳转登录页
嘿,我来帮你搞定这个问题!在ASP.NET Core 2.0里,实现全局身份认证检查并自动跳转到登录页的方案其实很清晰,和早期MVC的思路类似,但配置方式更标准化了。下面给你一步步拆解具体做法:
首先在Startup.cs的ConfigureServices方法中,你需要先配置好认证相关的服务,最常用的是Cookie认证(绝大多数场景都适用):
using Microsoft.AspNetCore.Authentication.Cookies; public void ConfigureServices(IServiceCollection services) { // 添加MVC核心服务 services.AddMvc(); // 配置Cookie认证方案 services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { // 设置未认证时跳转的登录页路径 options.LoginPath = "/Account/Login"; // 可选:设置权限不足时的跳转页 options.AccessDeniedPath = "/Account/AccessDenied"; }); }
如果你的项目还没引入Microsoft.AspNetCore.Authentication.Cookies包,记得通过NuGet安装它。
接下来在Configure方法里,要把认证中间件加入到请求管道中,注意必须放在UseMvc之前,不然认证逻辑不会生效:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseCookiePolicy(); // 启用身份认证中间件,这一步很关键 app.UseAuthentication(); // 配置MVC路由 app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); }
现在有两种方式实现“每次请求检查认证状态”的需求:
方式一:全局强制所有页面需要认证
如果你想让整个应用的所有控制器/Action都默认要求用户认证,可以在ConfigureServices的AddMvc中添加全局授权过滤器:
services.AddMvc(options => { // 创建一个要求用户必须认证的授权策略 var authPolicy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .Build(); // 把这个策略添加为全局过滤器 options.Filters.Add(new AuthorizeFilter(authPolicy)); });
这样配置后,任何未认证的请求都会自动跳转到你之前设置的LoginPath(也就是/Account/Login),而且会自动带上ReturnUrl参数,方便登录成功后跳转回用户原本想访问的页面。
方式二:针对特定控制器/Action设置认证要求
如果你不想全局强制,只想给部分页面加认证限制,直接在对应的控制器或Action上标记[Authorize]特性即可:
[Authorize] public class DashboardController : Controller { // 这个控制器下的所有Action都需要认证才能访问 public IActionResult Index() { return View(); } }
另外,像登录页本身肯定不能要求认证,你可以用[AllowAnonymous]特性来豁免:
[AllowAnonymous] public class AccountController : Controller { public IActionResult Login(string returnUrl = null) { ViewData["ReturnUrl"] = returnUrl; return View(); } }
最后,在你的登录逻辑里,验证用户信息通过后,需要创建认证会话,这样后续请求才会被识别为已认证:
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null) { ViewData["ReturnUrl"] = returnUrl; if (ModelState.IsValid) { // 这里替换成你的实际用户验证逻辑,比如从数据库校验用户名密码 bool isUserValid = ValidateUser(model.UserName, model.Password); if (isUserValid) { // 创建用户身份凭证 var claims = new List<Claim> { new Claim(ClaimTypes.Name, model.UserName) }; var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); var principal = new ClaimsPrincipal(identity); // 登录用户,生成认证Cookie await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal); // 跳转回用户原本想访问的页面,没有的话就跳首页 return RedirectToLocal(returnUrl); } ModelState.AddModelError(string.Empty, "用户名或密码错误"); } // 验证失败,返回登录页 return View(model); } // 辅助方法:安全处理跳转URL private IActionResult RedirectToLocal(string returnUrl) { if (Url.IsLocalUrl(returnUrl)) { return Redirect(returnUrl); } return RedirectToAction(nameof(HomeController.Index), "Home"); }
这样一套配置下来,就能实现你想要的效果:每次请求页面时自动检查认证状态,未认证的用户会被自动引导到登录页,登录成功后还能回到原来的页面。
内容的提问来源于stack exchange,提问作者DomBurf

