ASP。NET MVC安全和创建用户角色
介绍 一些成员让我写一篇关于ASP的文章。NET MVC安全等我计划创建的一系列文章。在这个系列中,我们将看到: ASP。NET MVC 5的安全性和创建用户角色NET MVC用户角色基础菜单管理使用WEB API和AngularJS。 在这篇文章中,我们将看到如何使用ASP。NET标识在MVC应用程序中,用于创建用户角色和根据用户角色显示菜单。 下面我们来看看如何: 创建默认的管理角色和其他角色。创建默认的管理用户。为新用户注册添加用户名。在用户注册期间选择用户角色。更改登录电子邮件与用户名。仅为管理用户显示角色创建菜单。为普通用户显示消息。将未经身份验证的用户重定向到默认主页。 身份验证和授权 身份验证 检查有效的用户。这里的问题是如何检查用户是否有效。当用户第一次访问一个网站时,他将注册该网站。他的所有信息,如用户名、密码、电子邮件等,都将存储在网站数据库中。当用户输入他的用户标识和密码时,数据库将检查这些信息。如果用户输入了与数据库中相同的用户id和密码,那么他或她就是一个有效用户,并将被重定向到网站主页。如果用户输入的用户标识和/或密码与数据库不匹配,那么登录页面将给出一条消息,类似于“输入有效的名称或密码”。检查用户访问网站是否有效的整个过程称为认证。 授权 用户通过身份验证后,需要根据其角色将其重定向到适当的页面。例如,当一个管理员登录时,他将被重定向到Admin页面。如果一个会计登录了,那么他将被重定向到他的帐户页面。如果终端用户已经登录,那么他将被重定向到他的页面。 先决条件 Visual Studio 2015:你可以从这里下载。 使用的代码 在Visual Studio 2015中创建您的Web应用程序 在安装Visual Studio 2015之后,单击“开始”,然后单击“程序”并选择Visual Studio 2015——单击Visual Studio 2015。单击新建,然后项目,选择Web,然后选择ASP。净的Web应用程序。输入项目名称并单击OK。 选择MVC并单击OK。 创建一个数据库 首先,我们将创建一个数据库,并在web.config文件中为DefaultConnection设置连接字符串,并使用新的数据库连接。我们将使用这个数据库的ASP。NET标识表的创建,以及我们的示例考勤Web项目。而不是使用两个数据库作为一个默认的ASP。NET用户数据库和另一个用于我们的考勤数据库,在这里我们将使用一个公共数据库用于用户详细信息和我们的示例web项目演示。 创建数据库:运行以下操作并创建数据库脚本,以创建我们的样本测试数据库。 隐藏,复制Code
-- ============================================= -- Author : Shanu -- Create date : 2016-01-17 -- Description : To Create Database -- ============================================= --Script to create DB,Table and sample Insert data USE MASTER; -- 1) Check for the Database Exists .If the database is exist then drop and create new DB IF EXISTS (SELECT [name] FROM sys.databases WHERE [name] = 'AttendanceDB' ) BEGIN ALTER DATABASE AttendanceDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE DROP DATABASE AttendanceDB ; END CREATE DATABASE AttendanceDB GO USE AttendanceDB GO
. config 在网络上。在配置文件中我们可以找到defaultconnection_connection字符串。在默认情况下ASP。NET MVC将使用这个连接字符串来创建所有的asp.net。NET身份相关表,如AspNetUsers等。对于我们的应用程序,我们还需要对其他页面活动使用database,而不是使用两个不同的数据库,一个用于用户详细信息,另一个用于我们自己的功能。这里我将使用一个数据库,所有的ASP。NET标识表将被创建,我们也可以为其他页面创建我们自己的表。 , 这里的连接字符串更改您的SQL服务器名称,UID和PWD,以创建和存储所有用户详细信息在一个数据库。 隐藏,复制Code< connectionStrings> add name="DefaultConnection" connectionString="data source=YOURSERVERNAME;initial catalog=AttendanceDB;user id=UID;password=PWD;Integrated Security=True" providerName="System.Data. "SqlClient”/比; & lt; / connectionStrings> 创建默认角色和管理用户 首先,创建默认的用户角色,如“Admin”,“Manager”等,我们也将创建一个默认的Admin用户。我们将在“start .cs”中创建所有默认角色和用户。 OWIN(为。net开放的WEB接口)定义了。net和WEB服务器之间的标准接口,每个OWIN应用程序都有一个启动类,我们可以在其中指定组件。 参考 OWIN和武士刀 在“启动。文件中可以找到配置方法。从这个方法中,我们将调用ourcreateRolesandUsers()方法来创建一个默认的用户角色,而user. 我们将检查是否已经创建了角色。如果没有创建Admin之类的角色,那么我们将创建一个新角色为“Admin”,并创建一个默认用户,并将用户角色设置为Admin。我们将使用这个用户作为超级用户,用户可以从我们的MVC应用程序创建新的角色。 隐藏,收缩,复制Codepublic void配置(IAppBuilder应用) { ConfigureAuth(应用); createRolesandUsers (); } //在此方法中,我们将创建用于登录的默认用户角色和Admin用户 私人空间createRolesandUsers () { ApplicationDbContext context = new ApplicationDbContext(); var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context))); var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context)); //在启动时,我正在创建第一个管理角色和创建一个默认的管理用户 如果(! roleManager.RoleExists (" Admin ")) { //首先创建Admin rool var role = new Microsoft.AspNet.Identity.EntityFramework.IdentityRole(); 的角色。Name = " Admin "; roleManager.Create(作用); //这里我们创建了一个管理员超级用户谁将维护网站 var user = new ApplicationUser(); 用户。用户名= " shanu”; 用户。电子邮件=“syedshanumcain@gmail.com”; userPWD = "A@Z200711"; var chkUser = UserManager。创建(用户、userPWD); //将默认用户添加到角色管理 如果(chkUser.Succeeded) { var result1 = UserManager.AddToRole(user。Id、“Admin”); } } //创建创建经理角色 如果(! roleManager.RoleExists(经理)){ var role = new Microsoft.AspNet.Identity.EntityFramework.IdentityRole(); 的角色。Name = "经理"; roleManager.Create(作用); } //创建创建员工角色 如果(! roleManager.RoleExists(“雇员”)) { var role = new Microsoft.AspNet.Identity.EntityFramework.IdentityRole(); 的角色。Name = "员工"; roleManager.Create(作用); } } 当我们运行我们的应用程序,我们可以看到新的默认ASP。NET用户相关表将在我们的attendancedb数据库中创建。这里,我们可以看到在下面的图像作为所有ASP。当我们运行我们的应用程序时,NET用户相关的表将被自动创建,并且我们所有的默认用户角色将被插入AspNetRoles表中,默认的管理用户将被创建在AspNetUsers表中。 通过添加用户名和角色自定义用户注册 默认情况下,用户注册在ASP。我们可以使用电子邮件和passoword。在这里,我们将定制默认的用户注册,添加用户名和显示用户角色的组合框。用户可以在注册期间输入他们的用户名并选择那里的用户角色。 查看部分:首先,在Register.cshtml中添加用户名的文本框和显示用户角色的组合框 双击Register.cshtml 更改html代码,如下列添加文本框和组合框的标题。这里我们可以看到,首先我们添加了一个文本框和组合框。我们绑定(SelectList) ViewBag.Name. 隐藏,收缩,复制Code
@model shanuMVCUserRoles.Models.RegisterViewModel @{ ViewBag.Title = "Register"; } <h2>@ViewBag.Title.</h2> @using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) { @Html.AntiForgeryToken() <h4>Create a new account.</h4> <hr/> @Html.ValidationSummary("", new { @class = "text-danger" }) <divclass="form-group"> @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" }) <divclass="col-md-10"> @Html.TextBoxFor(m => m.Email, new { @class = "form-control" }) </div> </div> <divclass="form-group"> @Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" }) <divclass="col-md-10"> @Html.TextBoxFor(m => m.UserName, new { @class = "form-control" }) </div> </div> <divclass="form-group"> @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" }) <divclass="col-md-10"> @Html.PasswordFor(m => m.Password, new { @class = "form-control" }) </div> </div> <divclass="form-group"> @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" }) <divclass="col-md-10"> @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" }) </div> </div> <divclass="form-group"> @Html.Label("user Role", new { @class = "col-md-2 control-label" }) <divclass="col-md-10"> @*@Html.DropDownList("Name")*@ @Html.DropDownList("UserRoles", (SelectList)ViewBag.Name, " ") </div> </div> <divclass="form-group"> <divclass="col-md-offset-2 col-md-10"> <inputtype="submit"class="btn btn-default"value="Register"/> </div> </div> } @section Scripts { @Scripts.Render("~/bundles/jqueryval") }
模型部分 接下来,在AccountViewModel.cs 检查RegisterViewModel并添加UserRoles和用户名属性以进行验证。 双击模型文件夹中的accountviewmodel . css文件,找到RegisterViewModel类,添加用户名和UserRoles属性,如下所示。 隐藏,收缩,复制Code
public class RegisterViewModel { [Required] [Display(Name = "UserRoles")] public string UserRoles { get; set; } [Required] [EmailAddress] [Display(Name = "Email")] public string Email { get; set; } [Required] [Display(Name = "UserName")] public string UserName { get; set; } [Required] [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] [DataType(DataType.Password)] [Display(Name = "Password")] public string Password { get; set; } [DataType(DataType.Password)] [Display(Name = "Confirm password")] [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] public string ConfirmPassword { get; set; } }
控制器部分 接下来在AccountController.cs首先我们得到所有的角色名称绑定在组合框除了管理角色和在注册按钮点击我们将添加功能插入用户名和设置用户选择的角色在ASP。净身份数据库。 首先,为ApplicationDBContext创建一个对象。在这里,ApplicationDBContext是一个用于执行所有ASP的类。NET身份数据库功能,如创建用户,角色等 隐藏,复制Code
ApplicationDbContext context; public AccountController() { context = new ApplicationDbContext(); }
注册ActionResult方法:, 使用applicationdbconterxtt 对象,我们将从数据库中获得所有的角色。对于用户注册,我们将不显示管理角色。用户可以在注册期间选择任何角色类型的rest。 隐藏,复制Code
// GET: /Account/Register [AllowAnonymous] public ActionResult Register() { ViewBag.Name = new SelectList(context.Roles.Where(u => !u.Name.Contains("Admin")) .ToList(), "Name", "Name"); return View(); }
注册用户 默认情况下,用户电子邮件将作为用户名存储在AspNetUsers表中。在这里我们将更改存储用户输入的名称。成功创建用户后,我们将为用户设置用户选择的角色。 隐藏,收缩,复制Code
// POST: /Account/Register [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Register(RegisterViewModel model) { if (ModelState.IsValid) { var user = new ApplicationUser { UserName = model.UserName, Email = model.Email }; var result = await UserManager.CreateAsync(user, model.Password); if (result.Succeeded) { await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771 // Send an email with this link // string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id); // var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme); // await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>"); //Assign Role to user Here await this.UserManager.AddToRoleAsync(user.Id, model.UserRoles); //Ends Here return RedirectToAction("Index", "Users"); } ViewBag.Name = new SelectList(context.Roles.Where(u => !u.Name.Contains("Admin")) .ToList(), "Name", "Name"); AddErrors(result); } // If we got this far, something failed, redisplay form return View(model); }
定制User 登录 与用户注册相同的方式,我们将自定义用户登录更改电子邮件为用户名进入。默认情况下,ASP。NET MVC 5为登录用户需要输入电子邮件和密码。在这里,我们将通过输入用户名和密码来定制用户。在这个演示中,我们不使用任何其他Facebook, Gmail或Twitter登录,所以我们将使用用户名而不是电子邮件。 视图部分 这里我们将更改电子邮件的用户名在Login.cshtml。我们可以在Views/Account/Login.cshtml的文件夹中找到这个Login.cshtml文件 隐藏,收缩,复制Code
@using shanuMVCUserRoles.Models @model LoginViewModel @{ ViewBag.Title = "Log in"; } <h2>@ViewBag.Title</h2> <divclass="row"> <divclass="col-md-8"> <sectionid="loginForm"> @using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" })) { @Html.AntiForgeryToken() <h4>Use a local account to log in.</h4> <hr/> @Html.ValidationSummary(true, "", new { @class = "text-danger" }) <divclass="form-group"> @Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" }) <divclass="col-md-10"> @Html.TextBoxFor(m => m.UserName, new { @class = "form-control" }) @Html.ValidationMessageFor(m => m.UserName, "", new { @class = "text-danger" }) </div> </div> <divclass="form-group"> @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-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-2 col-md-10"> <divclass="checkbox"> @Html.CheckBoxFor(m => m.RememberMe) @Html.LabelFor(m => m.RememberMe) </div> </div> </div> <divclass="form-group"> <divclass="col-md-offset-2 col-md-10"> <inputtype="submit"value="Log in"class="btn btn-default"/> </div> </div> <p> @Html.ActionLink("Register as a new user", "Register") </p> @* Enable this once you have account confirmation enabled for password reset functionality <p> @Html.ActionLink("Forgot your password?", "ForgotPassword") </p>*@ } </section> </div> <divclass="col-md-4"> <sectionid="socialLoginForm"> @Html.Partial("_ExternalLoginsListPartial", new ExternalLoginListViewModel { ReturnUrl = ViewBag.ReturnUrl }) </section> </div> </div> @section Scripts { @Scripts.Render("~/bundles/jqueryval") }
模型部分 , 和在AccountViewModel中注册一样,我们需要找到loginViewModel来更改带有用户名的电子邮件, 在下面的代码中,我们可以看到我们已经将Email属性更改为UserName. 隐藏,复制Code
public class LoginViewModel { [Required] [Display(Name = "UserName")] public string UserName { get; set; } [Required] [DataType(DataType.Password)] [Display(Name = "Password")] public string Password { get; set; } [Display(Name = "Remember me?")] public bool RememberMe { get; set; } }
控制器部分: 在登录按钮点击我们需要改变电子邮件的用户名检查从数据库为用户身份验证。在下面的代码中,我们可以看到,当我们更改了带有用户名的电子邮件后,成功登录后,我们将被重定向到用户页面。接下来,我们将看到如何创建一个用户页面,并根据用户角色显示文本和菜单。 隐藏,收缩,复制Code
// POST: /Account/Login [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) { if (!ModelState.IsValid) { return View(model); } // This doesn't count login failures towards account lockout // To enable password failures to trigger account lockout, change to shouldLockout: true var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false); switch (result) { case SignInStatus.Success: return RedirectToLocal(returnUrl); case SignInStatus.LockedOut: return View("Lockout"); case SignInStatus.RequiresVerification: return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe }); case SignInStatus.Failure: default: ModelState.AddModelError("", "Invalid login attempt."); return View(model); } } // // GET: /Account/VerifyCode [AllowAnonymous] public async Task<ActionResult> VerifyCode(string provider, string returnUrl, bool rememberMe) { // Require that the user has already logged in via username/password or external login if (!await SignInManager.HasBeenVerifiedAsync()) { return View("Error"); } return View(new VerifyCodeViewModel { Provider = provider, ReturnUrl = returnUrl, RememberMe = rememberMe }); }
经过身份验证和授权的用户页面 这里我们创建一个新页面,用于按角色显示经过身份验证和授权的用户的消息。 如果登录的用户角色是Admin,那么我们将显示Admin的欢迎消息,并显示用于创建新角色的菜单。 如果登录的用户角色是经理、员工、帐户等,那么我们将为他们显示一条欢迎消息。 首先,创建一个名为“userscontroller.cs”的新空控制器。在这个控制器中,我们首先在控制器的顶部添加[Authorize],用于检查有效用户。 创建视图:右键单击索引ActionResult并创建视图。 在视图中,我们检查ViewBag.displayMenu 如果值是“Yes”,那么我们将显示Admin欢迎消息和创建新菜单的链接。如果viewbag . displaymenu是“否”,则显示其他用户的姓名和欢迎信息。 隐藏,复制Code
@{ ViewBag.Title = "Index"; } @if (ViewBag.displayMenu == "Yes") { <h1>Welcome Admin. Now you can create user Role.</h1> <h3> <li>@Html.ActionLink("Manage Role", "Index", "Role")</li> </h3> } else { <h2> Welcome <strong>@ViewBag.Name</strong> :) .We will add user module soon </h2> }
控制器部分: 在控制器中,我们将检查用户是否登录到系统。如果他没有登录,那么我们 如果用户已登录,则显示消息为“未登录”,然后检查登录用户角色。如果用户角色是“Admin”,那么我们设置ViewBag。displayMenu = "Yes"否则我们设置ViewBag。displayMenu =“不”。 隐藏,复制Code
public ActionResult Index() { if (User.Identity.IsAuthenticated) { var user = User.Identity; ViewBag.Name = user.Name; ViewBag.displayMenu = "No"; if (isAdminUser()) { ViewBag.displayMenu = "Yes"; } return View(); } else { ViewBag.Name = "Not Logged IN"; } return View(); }
为了检查用户是否登录,我们创建了一个方法并将布尔值返回到我们的主索引方法。 隐藏,复制Code
public Boolean isAdminUser() { if (User.Identity.IsAuthenticated) { var user = User.Identity; ApplicationDbContext context = new ApplicationDbContext(); var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context)); var s = UserManager.GetRoles(user.GetUserId()); if (s[0].ToString() == "Admin") { return true; } else { return false; } } return false; }
管理员用户可以创建角色 我们已经看到,如果Admin用户已经登录,那么我们将显示用于创建新用户的链接。admin登录我们已经创建了一个默认用户,用户名为“shanu”,密码为“A@Z200711”, 为了通过admin创建用户角色,首先我们将添加一个新的空控制器并将其命名为RoleController.cs, 在这个控制器中,我们检查用户角色是否为Admin。如果登录的用户角色是Admin,那么我们将使用applicationdbcontext&object . 获取所有的角色名称。 隐藏,复制Code
public ActionResult Index() { if (User.Identity.IsAuthenticated) { if (!isAdminUser()) { return RedirectToAction("Index", "Home"); } } else { return RedirectToAction("Index", "Home"); } var Roles = context.Roles.ToList(); return View(Roles); }
在view中,我们将所有用户角色绑定在html表中。 隐藏,收缩,复制Code
@model IEnumerable<Microsoft.AspNet.Identity.EntityFramework.IdentityRole> @{ ViewBag.Title = "Add Role"; } <tablestyle=" background-color:#FFFFFF; border: dashed 3px #6D7B8D; padding: 5px;width: 99%;table-layout:fixed;"cellpadding="6"cellspacing="6"> <trstyle="height: 30px; background-color:#336699 ; color:#FFFFFF ;border: solid 1px #659EC7;"> <tdalign="center"colspan="2"> <h2> Create User Roles</h2> </td> </tr> <tr> <td> <tableid="tbrole"style="width:100%; border:dotted 1px; background-color:gainsboro; padding-left:10px;"> @foreach (var item in Model) { <tr> <tdstyle="width:100%; border:dotted 1px;"> @item.Name </td> </tr>} </table> </td> <tdalign="right"style="color:#FFFFFF;padding-right:10;"> <h3> @Html.ActionLink("Click to Create New Role", "Create", "Role") </h3> </td> </tr> </table>
的兴趣点 首先,在SQL服务器中创建一个示例AttendanceDB数据库。在Web。用SQL服务器连接更改DefaultConnection连接字符串。在Startup.cs文件中,我已经创建了默认的Admin用户名“shanu”和密码“A@Z200711”,这个用户名和密码将作为Admin用户登录。您可以随意更改此用户名和密码。出于安全考虑,在以管理员身份登录后,您可以随意更改管理员用户密码 历史 shanuMVCUserRoles.zip - 2016-01-29。 本文转载于:http://www.diyabc.com/frontweb/news17281.html