基于mvc5+ef6+Bootstrap框架实现身份验证和权限管理
近和朋友完成了一个大单子架构是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框架实现身份验证和权限管理,希望对大家有所帮助