mvc5+ef6+Bootstrap 项目心得--身份验证和权限管理
2016-06-30 13:32
447 查看
最近和朋友完成了一个大单子架构是mvc5+ef6+Bootstrap,用的是vs2015,数据库是sqlserver2014。朋友做的架构,项目完成后觉得很多值得我学习,在这里总结下一些心得。
创建项目一开始删掉App_Start目录下的IdentityConfig.cs和Startup.Auth.cs文件;清空Modle文件夹,Controller文件夹和相应的View;删除目录下的ApplicationInsights.config文件和Startup.cs文件。(不使用自带的Identity,太多内容不需要)
修改web.config文件(添加<addkey="owin:AutomaticAppStartup"value="false"/>不使用Startup.cs文件来启动项目)
<appSettings> <addkey="webpages:Version"value="3.0.0.0"/> <addkey="webpages:Enabled"value="false"/> <addkey="ClientValidationEnabled"value="true"/> <addkey="UnobtrusiveJavaScriptEnabled"value="true"/> <addkey="owin:AutomaticAppStartup"value="false"/><!--去掉创建项目初的Startup.cs文件的设置--> </appSettings>
(不用他们是因为自带的这些内容太冗余)
1.首先介绍数据库这一块,数据库我们是配置的可以使用NuGet命令[b]手动生成和修改的。在项目目录想创建Migrations文件夹,里面添加Configuration.cs文件[/b]
internalsealedclassConfiguration:DbMigrationsConfiguration<AccountContext> { publicConfiguration() { AutomaticMigrationsEnabled=true; ContextKey="UserProject.DAL.AccountContext"; } protectedoverridevoidSeed(AccountContextcontext) { //base.Seed(context); } }
在Model文件夹下添加AccountContext.cs文件
publicclassAccountContext:DbContext { publicAccountContext():base("AccountContext"){ } publicDbSet<User>Users{get;set;} protectedoverridevoidOnModelCreating(DbModelBuildermodelBuilder) { modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); } }
<connectionStrings> <addname="AccountContext"connectionString="DataSource=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\UserProject.mdf;InitialCatalog=UserProject;IntegratedSecurity=True"providerName="System.Data.SqlClient"/> </connectionStrings>
然后使用vs2015里面的工具-NuGet包管理器-程序包管理控制平台
输入add-migrationInitial按回车,在输入update-database按回车。在App_Data文件夹下就会看到AccountContext数据库了。
2.创建测试用的Model
在Model文件夹下添加User.css文件
publicclassUser { publicintID{get;set;} publicstringUserName{get;set;} publicstringPassword{get;set;} publicRoleRole{get;set;} }
publicenumRole//角色枚举
{管理员=1,员工=2,经理=3,总经理=4,董事长=5}
在ViewModel文件夹中添加Account.cs文件
publicclassAccount { [Required] publicstringName{get;set;} [Required] publicstringPassword{get;set;} publicstringRePassword{get;set;} }
3.创建测试用到的Controller
这里推荐创建BaseController,之后的Controller就继承它来使用
publicclassBaseController:Controller { publicstringUserName=>User.Identity.Name; publicAccountContextdb=newAccountContext(); privateUser_userInfo=null; publicUserCurrentUserInfo { get { if(_userInfo==null) { varuser=db.Users.SingleOrDefault(u=>u.UserName==UserName);//此处为了不每次访问用户表可以做一个静态类,里面存放用户表信息. _userInfo=user==null?null:newUser() { ID=user.ID, UserName=user.UserName, Role=user.Role }; } return_userInfo; } } //验证角色:获取Action的CustomAttributes,过滤角色 protectedoverridevoidOnActionExecuting(ActionExecutingContextfilterContext) { base.OnActionExecuting(filterContext); varauthRoleAtt=filterContext.ActionDescriptor.GetCustomAttributes(false).SingleOrDefault(att=>attisAuthorizeRoleAttribute)asAuthorizeRoleAttribute; if(authRoleAtt==null&&CurrentUserInfo!=null) return; if(!authRoleAtt.Roles.Contains(CurrentUserInfo.Role)) { filterContext.Result=View("NoPermission","_Layout","您没有权限访问此功能!"); } } //这里是记log用 protectedoverridevoidOnActionExecuted(ActionExecutedContextfilterContext) { base.OnActionExecuted(filterContext); varmsg=$"用户:{CurrentUserInfo?.UserName},链接:{Request.Url}"; if(Request.HttpMethod=="POST") msg+=$",数据:{HttpUtility.UrlDecode(Request.Form.ToString())}"; //Log.Debug(msg); } }
publicclassAuthorizeRoleAttribute:Attribute { publicList<Role>Roles{get;set;} publicAuthorizeRoleAttribute(paramsRole[]roles) { Roles=newList<Role>(roles); } }
AdminController继承BaseController
[Authorize] publicActionResultIndex() { returnView(db.Users.ToList()); } [Authorize,AuthorizeRole(Role.管理员)] publicActionResultDetails(int?id) { if(id==null) { returnnewHttpStatusCodeResult(HttpStatusCode.BadRequest); } Useruser=db.Users.Find(id); if(user==null) { returnHttpNotFound(); } returnView(user); }
4.创建Action和VIew
登录页面:
@modelUserProject.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"}) <divclass="form-group"> @Html.LabelFor(m=>m.Name,new{@class="col-md-2control-label"}) <divclass="col-md-10"> @Html.TextBoxFor(m=>m.Name,new{@class="form-control"}) @Html.ValidationMessageFor(m=>m.Name,"",new{@class="text-danger"}) </div> </div> <divclass="form-group"> @Html.LabelFor(m=>m.Password,new{@class="col-md-2control-label"}) <divclass="col-md-10"> @Html.PasswordFor(m=>m.Password,new{@class="form-control"}) @Html.ValidationMessageFor(m=>m.Password,"",new{@class="text-danger"}) </div> </div> <divclass="form-group"> <divclass="col-md-offset-2col-md-10"> <inputtype="submit"value="登录"class="btnbtn-primary"/> </div> </div> }
登录的Action:
[AllowAnonymous] publicActionResultLogin() { returnView(); } [HttpPost,AllowAnonymous] publicActionResultLogin(Accountmodel) { if(ModelState.IsValid) { varuser=db.Users.SingleOrDefault(t=>t.UserName==model.Name&&t.Password==model.Password); if(user!=null) { FormsAuthentication.SetAuthCookie(model.Name,false);//将用户名放入Cookie中 returnRedirectToAction("Index"); } else { ModelState.AddModelError("Name","用户名不存在!"); } } returnView(model); } publicActionResultLogOff() { FormsAuthentication.SignOut(); returnRedirectToAction("Login"); }
通过以上方式就完成了用户的登录和权限的控制,访问Details这个Action的时候必须是管理员角色。
如果需要多个角色使用Action可以:[Authorize,AuthorizeRole(Role.管理员,Role.经理)]
使用此方法登录的用户保存在Cookie里面:FormsAuthentication.SetAuthCookie(model.Name,false);
在Controller和View里面直接使用User.Identity得到用户名
此仅仅是测试项目,作为完成私活的部分知识点的总结。
相关文章推荐
- freemark和bootstrap中页面布局,页签,左右菜单
- bootstrap 中下拉菜单改为鼠标经过
- bootstrap与模态框
- bootstrap自定义提示框
- 基于bootsrtap的网页开发|慕课网案例
- Bootstrap之Carousel不能自动播放的解决办法
- 关于bootstrap--表格(tr的各种样式)
- 关于bootstrap--表格(table的各种样式)
- 关于bootstrap--列表(ol、ul)
- bootstrap弹窗二次封装成插件
- 基于Metronic的Bootstrap开发框架经验总结(10)--优化Bootstrap图标管理
- Bootstrap幻灯轮播如何支持触屏左右滑动手势?
- bootstrap的@media (min-width: 768px)
- fuel8 生成bootstrap映像
- 免费的Bootstrap管理后台模板集合
- bootstrap2.3.2常用标签的使用
- Bootstrap modal修改宽度
- 关于bootstrap--排版(标题、强调、背景、插入符等)
- BootStrap初学者对弹出框和进度条的使用感觉
- Bootstrap CSS概览代码文字标注篇