VS2017建立MVC+NetCore2接入現有資料庫
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內新增所有的登入、許可權驗證。