ASP.NET Core - MVC Authorization
这篇文章介绍 .Net Core 下 Mvc 自带的身份验证和授权的使用方法
1. 有一个基础的 Mvc 框架
2. 有个自定义的 User 模型, 需要继承 Microsoft.AspNetCore.Identity.IdentityUser
public class ApplicationUser : IdentityUser { }
3. 建立数据上下文并链接数据库,
这里的上下文需要继承 Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityDbContext<>
这里的 IdentityDbContext 也是从 DbContext 继承而来, 所以跟原来的一样
public class ApplicationDbContext : IdentityDbContext<ApplicationUser> { public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } }
4. 修改 StartUp
在 ConfigureService 里注册数据库和身份验证
public void ConfigureServices(IServiceCollection services) { services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); services.AddIdentity<ApplicationUser, IdentityRole>() .AddEntityFrameworkStores<ApplicationDbContext>() .AddDefaultTokenProviders(); services.AddMvc(); }
5. 建立 Account 控制器 和 Login, Register 等视图
(这里需要注意的是, 一旦访问需要权限的页面, 会自动跳到登陆界面, 这里登陆界面默认就是 Account/Login, 并不知道在哪里可以修改)
另外, 建立 AccountController 的时候, 需要注入2个管理器
public class AccountController : Controller { private readonly UserManager<ApplicationUser> _userManager; private readonly SignInManager<ApplicationUser> _signInManager; public AccountController( UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager) { _userManager = userManager; _signInManager = signInManager; } }
6. 利用以上2个管理器来实现登陆和注册
public async Task<IActionResult> Login(LoginViewModel model) {if (ModelState.IsValid) { var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false); if (result.Succeeded) { if (Url.IsLocalUrl(returnUrl)) { return Redirect(returnUrl); } else { return RedirectToAction(nameof(HomeController.Index), "Home"); } } else { ModelState.AddModelError(string.Empty, "Invalid login attempt."); return View(model); } } return View(model); }
public async Task<IActionResult> Register(RegisterViewModel model) {if (ModelState.IsValid) { var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; var result = await _userManager.CreateAsync(user, model.Password); if (result.Succeeded) { await _signInManager.SignInAsync(user, isPersistent: false); if (Url.IsLocalUrl(returnUrl)) { return Redirect(returnUrl); } else { return RedirectToAction(nameof(HomeController.Index), "Home"); } } foreach (var error in result.Errors) { ModelState.AddModelError(string.Empty, error.Description); } } return View(model); }
public async Task<IActionResult> Logout() { await _signInManager.SignOutAsync(); return RedirectToAction(nameof(HomeController.Index), "Home"); }
还有一种轻量级自定义的验证方式
[HttpGet] [AllowAnonymous] public IActionResult SignIn() { var output = new LoginInput(); return View(output); } /// <summary> /// 登录 /// </summary> /// <param name="input"></param> /// <returns></returns> [HttpPost] [AllowAnonymous] public async Task<IActionResult> SignIn(LoginInput input) { var context = new ExPlatDbContext(); var user = context.User.SingleOrDefault(d => d.Name == input.Username); if (user == null || user.Password != input.Password || user.Role != 0) { input.Password = ""; ModelState.AddModelError("", "用户名或密码错误"); return View(input); } var claimIdentity = new ClaimsIdentity("Cookie"); claimIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString())); claimIdentity.AddClaim(new Claim(ClaimTypes.Name, user.Name)); var claimsPrincipal = new ClaimsPrincipal(claimIdentity); await HttpContext.SignInAsync(claimsPrincipal); return RedirectToAction("Index", "Home"); } /// <summary> /// 登出 /// </summary> /// <returns></returns> [HttpPost] public async Task<IActionResult> SignOut() { await HttpContext.SignOutAsync(); return Ok(Success()); }
在 BaseController 里
public static UserInfo CurrentUser { get { var user = System.Web.HttpContext.Current.User; // 取上下文中的用户信息 return (user as CurrentUserCookie)?.CurrentUser; } }
Starup 里面
services.AddAuthentication(options => { options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; }) .AddCookie(options => { options.LoginPath = "/main/user/signin"; });
app.UseAuthentication();