1、 新建项目“eco”,选择“web应用程序(模型视图控制器)”,身份验证为:不进行身份验证。
2、 在程序包管理控制台执行命令:
Scaffold-DbContext "Data Source=127.0.0.1;Initial Catalog=eco;Persist Security Info=True;User ID=sa;Password=abc123456" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models –Force注意其中的数据库连接的地址与账户、名称等,-Force 是覆盖旧版本的意思,更多附加指令需要百度,此时已经自动生成Models。
3、 修改Models中的ecoContext.cs:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { if (!optionsBuilder.IsConfigured) { #warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings. optionsBuilder.UseSqlServer(@"Data Source=127.0.0.1;Initial Catalog=eco;Persist Security Info=True;User ID=sa;Password=abc123456"); } }这段删掉或者注释掉,修改为如下代码:
public ecoContext(DbContextOptions<ecoContext> options) : base(options) { }4、 修改配置文件appsettings.json,增加数据库连接内容:
"ConnectionStrings": { "DefaultConnection": "Data Source=127.0.0.1;Initial Catalog=eco;Persist Security Info=True;User ID=sa;Password=abc123456" }5、 修改Startup.cs,启用项目中的数据库连接,在ConfigureServices内加入:
services.AddDbContext<ecoContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));==========到此,没有登录认证、权限等高级功能的项目基本要求完毕,下面增加高级功能配置==========
6、 修改Startup.cs,加入验证过滤:
在ConfigureServices函数中加入:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { //自定义登陆地址,不配置的话则默认为http://localhost:xxxx/Account/Login options.LoginPath = new PathString("/Tlogintokens/Login"); options.AccessDeniedPath = new PathString("/Error/Forbidden"); //options.ExpireTimeSpan = System.TimeSpan.FromDays(10); //options.Cookie.Domain = ""; }); 在Configure函数中加入: app.UseAuthentication();特别注意,app.UseAuthentication();一定要放在 app.UseMvc 的前面,否则失效,好大的一个坑,百度一天,偶尔发现这个问题
==========此时,在action头上或者controller头上加上[Authorize]或者[Authorize(Roles ="xx")],那么该action或者controller必须经过cookie认证,认证不通过,则跳转到"/Tlogintokens/Login",login的写cookie代码:
var claims = new List<Claim>(){ new Claim(ClaimTypes.Name,"admin"), new Claim(ClaimTypes.Hash,"password") }; var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), new AuthenticationProperties { IsPersistent = true, ExpiresUtc=DateTimeOffset.Now.Add(TimeSpan.FromDays(10)) }); ViewData["ReturnUrl"] = returnUrl;
读取该cookie内容代码:
ViewData["username"] = User.FindFirst(ClaimTypes.Name).Value; ViewData["password"] = User.FindFirst(ClaimTypes.Hash).Value;在此别被User坑到了,此User非那User,引入using System.Security.Claims;就有User了。
此时,已经能实现简单的登录验证,需要强悍的权限验证,需要自定义Authorize:
新建类:MyAuthorizeAttribute,继承ActionFilterAttribute :
public class MyAuthorize: ActionFilterAttribute { public string Roles { get; set; } public override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { //var a = context.HttpContext.User.FindFirst(c => c.Type == ClaimTypes.Name)?.Value.ToString(); //var a = context.HttpContext.User.HasClaim(c => c.Type == ClaimTypes. Hash).ToString(); context.Result = new RedirectResult("~/Admin/Account/Login" + Roles); return base.OnActionExecutionAsync(context, next); } }注意:context.HttpContext.User.FindFirst(c => c.Type == ClaimTypes.Name)?.Value.ToString(); 里面有个问号,如果没有这个问号,遇到空值会出现系统错误(NullReferenceException: Object reference not set to an instance of an object.)。
注意注释,均是可用的代码,此时,可以在这个OnActionExecutionAsync内添加所有的登录、权限验证。
