您的位置:首页 > Web前端 > BootStrap

mvc5+ef6+Bootstrap 项目心得--身份验证和权限管理

2016-06-30 13:32 447 查看
1.mvc5+ef6+Bootstrap项目心得--身份验证和权限管理

2.mvc5+ef6+Bootstrap项目心得--WebGrid

最近和朋友完成了一个大单子架构是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得到用户名

此仅仅是测试项目,作为完成私活的部分知识点的总结。


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: