近和朋友完成了一個大單子架構是mvc5+ef6+Bootstrap,用的是vs2015,數據庫是sql server2014。朋友做的架構,項目完成后覺得很多值得我學習,在這里總結下一些心得。
創建項目一開始刪掉App_Start目錄下的IdentityConfig.cs和Startup.Auth.cs文件;清空Modle文件夾,Controller文件夾和相應的View; 刪除目錄下的ApplicationInsights.config文件和Startup.cs文件
修改web.config文件(添加<add key="owin:AutomaticAppStartup" value="false"/>不使用Startup.cs文件來啟動項目)
<appSettings><add key="webpages:Version" value="3.0.0.0" /><add key="webpages:Enabled" value="false" /><add key="ClientValidationEnabled" value="true" /><add key="UnobtrusiveJavaScriptEnabled" value="true" /><add key="owin:AutomaticAppStartup" value="false"/> <!--去掉創建項目初的Startup.cs文件的設置--></appSettings>
(不用他們是因為自帶的這些內容太冗余)
去掉冗余內容正式開始,首先介紹數據庫這一塊,數據庫我們是配置的可以手動生成和修改的
1.在項目目錄想創建Migrations文件夾,里面添加Configuration.cs文件
internal sealed class Configuration : DbMigrationsConfiguration<AccountContext>{public Configuration(){AutomaticMigrationsEnabled = true;ContextKey = "UserProject.DAL.AccountContext";}protected override void Seed(AccountContext context){//base.Seed(context);}}
在Modle文件夾下添加AccountContext.cs文件
public class AccountContext:DbContext{public AccountContext():base("AccountContext") {}public DbSet<User> Users { get; set; }protected override void OnModelCreating(DbModelBuilder modelBuilder){modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();}}<connectionStrings><add name="AccountContext" connectionString="Data Source=(LocalDb)/MSSQLLocalDB;AttachDbFilename=|DataDirectory|/UserProject.mdf;Initial Catalog=UserProject;Integrated Security=True" providerName="System.Data.SqlClient" /></connectionStrings>
然后 使用vs2015里面的工具-NuGet包管理器-程序包管理控制平臺
輸入add-migration Initial 按回車,在輸入update-database按回車。在App_Data文件夾下就會看到AccountContext數據庫了。
2.在Modle文件夾下添加User.css文件
public class User{public int ID { get; set; }public string UserName { get; set; }public string Password { get; set; }public Role Role { get; set; }}public enum Role//角色枚舉{ 管理員 = 0, 員工 = 1, 經理 = 2, 總經理 = 3, 董事長 = 4 }
在ViewModle文件夾中添加Account.cs文件
public class Account{[Required]public string Name { get; set; }[Required]public string Password { get; set; }public string RePassword { get; set; }}
這里推薦創建BaseController之后的Controller就繼承它來使用
public class BaseController : Controller{public string UserName => User.Identity.Name;public AccountContext db = new AccountContext();private User _userInfo = null;public User CurrentUserInfo{get{if (_userInfo == null){var user = db.Users.SingleOrDefault(u => u.UserName == UserName);//此處為了不每次訪問用戶表可以做一個靜態類,里面存放用戶表信息._userInfo = user == null ? null : new User(){ID = user.ID,UserName = user.UserName,Role = user.Role};}return _userInfo;}} //驗證角色:獲取Action的CustomAttributes,過濾角色protected override void OnActionExecuting(ActionExecutingContext filterContext){base.OnActionExecuting(filterContext);var authRoleAtt = filterContext.ActionDescriptor.GetCustomAttributes(false).SingleOrDefault(att => att is AuthorizeRoleAttribute) as AuthorizeRoleAttribute;if (authRoleAtt == null && CurrentUserInfo != null)return;if (!authRoleAtt.Roles.Contains(CurrentUserInfo.Role)){filterContext.Result = View("NoPermission", "_Layout", "您沒有權限訪問此功能!");}}//這里是記log用protected override void OnActionExecuted(ActionExecutedContext filterContext){base.OnActionExecuted(filterContext);var msg = $"用戶: {CurrentUserInfo?.UserName}, 鏈接: {Request.Url}";if (Request.HttpMethod == "POST")msg += $", 數據: {HttpUtility.UrlDecode(Request.Form.ToString())}";//Log.Debug(msg);}}
AdminController繼承BaseController
[Authorize]public ActionResult Index(){return View(db.Users.ToList());}[Authorize, AuthorizeRole(Role.管理員)]public ActionResult Details(int? id){if (id == null){return new HttpStatusCodeResult(HttpStatusCode.BadRequest);}User user = db.Users.Find(id);if (user == null){return HttpNotFound();}return View(user);}
登錄頁面:
@model UserProject.ViewModels.Account@{ViewBag.Title = "Login";}@using (Html.BeginForm("Login", "Admin",FormMethod.Post, new { @class = "form-horizontal", role = "form" })) {@Html.AntiForgeryToken()<hr />@Html.ValidationSummary(true, "", new { @class = "text-danger" })<div class="form-group">@Html.LabelFor(m => m.Name, new { @class = "col-md-2 control-label" })<div class="col-md-10">@Html.TextBoxFor(m => m.Name, new { @class = "form-control" })@Html.ValidationMessageFor(m => m.Name, "", new { @class = "text-danger" })</div></div><div class="form-group">@Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })<div class="col-md-10">@Html.PasswordFor(m => m.Password, new { @class = "form-control" })@Html.ValidationMessageFor(m => m.Password, "", new { @class = "text-danger" })</div></div><div class="form-group"><div class="col-md-offset-2 col-md-10"><input type="submit" value="登錄" class="btn btn-primary" /></div></div>}
登錄的Action:
[AllowAnonymous]public ActionResult Login(){return View();}[HttpPost, AllowAnonymous]public ActionResult Login(Account model){if (ModelState.IsValid){var user = db.Users.SingleOrDefault(t => t.UserName == model.Name && t.Password == model.Password);if (user != null){FormsAuthentication.SetAuthCookie(model.Name, false);//將用戶名放入Cookie中return RedirectToAction("Index");}else{ModelState.AddModelError("Name", "用戶名不存在!");}}return View(model);}public ActionResult LogOff(){FormsAuthentication.SignOut();return RedirectToAction("Login");}
按照以上方式 訪問Details這個Action的時候必須是管理員角色。
以上所述是小編給大家介紹的基于mvc5+ef6+Bootstrap框架實現身份驗證和權限管理,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!
新聞熱點
疑難解答