首页 > 代码库 > asp.net identity 学习1

asp.net identity 学习1

前段时间在用ABP的登陆功能时接触到了identity,总是不太懂User和Role等,想直接了解一下Asp.Net Identity

参考了一些园子里的资料

MVC5 - ASP.NET Identity登录原理 - Claims-based认证和OWIN

还有张善友大大的资料传送门

跟着大手的思路写了点代码,虽然还不是很明白,但也快有思路了~

新建的MVC5项目里面已经内置了identity,有User的管理功能,可以登录,但是角色管理需要我们去写,今天完成的也就是在MVC中对角色的管理

首先,新建一个MVC5项目,若启用角色管理,需要在web.config中配置,如下所示:

  <system.web>    <roleManager enabled="true"/><!--添加-->    <authentication mode="None" />    <compilation debug="true" targetFramework="4.6.1" />    <httpRuntime targetFramework="4.6.1" />    <httpModules>      <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" />    </httpModules>  </system.web>

在App_Start中的IdentityConfig.cs文件中添加RoleManager

public class ApplicationRoleManager : RoleManager<IdentityRole>    {        public ApplicationRoleManager(IRoleStore<IdentityRole, string> roleStore):base(roleStore)        {        }        public static ApplicationRoleManager Create(IdentityFactoryOptions<ApplicationRoleManager> options,IOwinContext context)        {            return new ApplicationRoleManager(new RoleStore<IdentityRole>(context.Get<ApplicationDbContext>()));        }    }

在Startup.Auth.cs中的ConfigureAuth方法添加角色管理器

app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);

这样就启用了角色的管理。
可以在项目初始化的时候添加默认的管理员角色,在IdentityModels中有ApplicationDbContext的定义,可以在下面添加类

public class ApplicationDbInitializer : DropCreateDatabaseIfModelChanges<ApplicationDbContext>    {        protected override void Seed(ApplicationDbContext context)        {            InitializeIdentityForEF(context);            base.Seed(context);        }        public static void InitializeIdentityForEF(ApplicationDbContext context)        {            var userManager = HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>();            var roleManager = HttpContext.Current.GetOwinContext().Get<ApplicationRoleManager>();            const string name = "admin@123.com";            const string password = "Admin@123.com";            const string rolename = "Admin";            var role = roleManager.FindByName(rolename);            if (role == null)            {                role = new IdentityRole(rolename);                var roleresult = roleManager.Create(role);            }            var user = userManager.FindByName(name);            if (user == null)            {                user = new ApplicationUser { UserName = name, Email = name };                var result = userManager.Create(user, password);                result = userManager.SetLockoutEnabled(user.Id, false);            }            var userRole = userManager.GetRoles(user.Id);            if (!userRole.Contains(role.Name))            {                var result = userManager.AddToRole(user.Id, role.Name);            }        }    }

在ApplicationDbContext中添加静态构造函数(静态构造函数会先执行)

static ApplicationDbContext()        {            Database.SetInitializer<ApplicationDbContext>(new ApplicationDbInitializer());        }

这样会在初次执行数据库任务时,创建Admin的角色~
接着在项目中添加实现角色管理的控制器和页面

在Model中添加AdminViewModels

 public class AdminViewModels    {        public class RoleViewModel        {            public string Id { get; set; }            [Required(AllowEmptyStrings =false)]            [Display(Name="角色名称")]            public string Name { get; set; }        }        public class EditUserViewModel        {            public string Id { get; set; }            [Required(AllowEmptyStrings =false)]            [Display(Name ="电子邮件")]            [EmailAddress]            public string Email { get; set; }            public IEnumerable<SelectListItem> RolesList { get; set; }        }    }

在Controller中添加RolesAdminController,在类中添加代码

     private ApplicationUserManager _userManager;        public ApplicationUserManager UserManager        {            get {                return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();            }            set            {                _userManager = value;            }        }        private ApplicationRoleManager _roleManager;        public ApplicationRoleManager RoleManager        {            get {                return _roleManager ?? HttpContext.GetOwinContext().Get<ApplicationRoleManager>();            }            private set {                _roleManager = value;            }        }        public RolesAdminController(ApplicationUserManager userManager, ApplicationRoleManager roleManager)        {            UserManager = userManager;            RoleManager = roleManager;        }

默认的Index页面用来显示角色列表,修改Index的action,如下所示

return View(RoleManager.Roles);

接着添加CRUD代码
Create页面的action

public ActionResult Create()        {            return View();        }

实现添加角色的action

[HttpPost]        public async Task<ActionResult> Create(RoleViewModel roleViewModel)        {            if (ModelState.IsValid)            {                var role = new IdentityRole(roleViewModel.Name);                var roleResult = await RoleManager.CreateAsync(role);                if (!roleResult.Succeeded)                {                    ModelState.AddModelError("", roleResult.Errors.First());                    return View();                }                return RedirectToAction("Index");            }            return View();        }

Details页面的action

 public async Task<ActionResult> Details(string id)        {            if (id == null)                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);            var role = await RoleManager.FindByIdAsync(id);            var users = new List<ApplicationUser>();            foreach (var item in UserManager.Users.ToList())            {                if (await UserManager.IsInRoleAsync(item.Id, role.Name))                {                    users.Add(item);                }            }            ViewBag.Users = users;            ViewBag.UserCount = users.Count;            return View(role);        }

Edit页面的action

public async Task<ActionResult> Edit(string id)        {            if (id == null)                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);            var role = await RoleManager.FindByIdAsync(id);            if (role == null)                return HttpNotFound();            RoleViewModel roleModel = new RoleViewModel { Id = role.Id, Name = role.Name };            return View(roleModel);        }

实现Edit的action

[HttpPost]        [ValidateAntiForgeryToken]        public async Task<ActionResult> Edit([Bind(Include = "Name,Id")]RoleViewModel roleModel)        {            if (ModelState.IsValid)            {                var role = await RoleManager.FindByIdAsync(roleModel.Id);                role.Name = roleModel.Name;                await RoleManager.UpdateAsync(role);                return RedirectToAction("Index");            }            return View();        }

Delete的页面

public async Task<ActionResult> Delete(string id)        {            if (id == null)                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);            var role = await RoleManager.FindByIdAsync(id);            if (role == null)                return HttpNotFound();            return View(role);        }

实现Delete的action

[HttpPost, ActionName("Delete")]        [ValidateAntiForgeryToken]        public async Task<ActionResult> DeleteConfirmed(string id, string deleteUser)        {            if (ModelState.IsValid)            {                if (id == null)                    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);                var role = await RoleManager.FindByIdAsync(id);                if (role == null)                    return HttpNotFound();                IdentityResult result;                if (deleteUser != null)                    result = await RoleManager.DeleteAsync(role);                else                    result = await RoleManager.DeleteAsync(role);                if (!result.Succeeded)                {                    ModelState.AddModelError("", result.Errors.First());                    return View();                }                return RedirectToAction("Index");            }            return View();        }

接着添加CRUD的页面
Index页面如下所示

@model IEnumerable<Microsoft.AspNet.Identity.EntityFramework.IdentityRole>@{    ViewBag.Title = "Index";}<h2>角色列表</h2><p>    @Html.ActionLink("新建角色","Create")</p><table class="table">    <tr>        <th>            @Html.Label("角色名称")        </th>        <th></th>    </tr>    @foreach (var item in Model)    {        <tr>            <td>                @Html.DisplayFor(modelItem=>item.Name)            </td>            <td>                @Html.ActionLink("编辑角色","Edit",new { id=item.Id})                @Html.ActionLink("角色详情","Details",new { id=item.Id})                @Html.ActionLink("删除角色","Delete",new { id=item.Id})            </td>        </tr>    }</table>

Create页面如下所示

@model IdentityLearning_01 .Models.AdminViewModels.RoleViewModel@{    ViewBag.Title = "Create";}<h2>创建角色</h2>@using (Html.BeginForm()){    @Html.AntiForgeryToken()    <div class="form-horizontal">        <h4>创建角色</h4>        <hr/>        @Html.ValidationSummary(true)        <div class="form-group">            @Html.LabelFor(model=>model.Name,new { @class="control-label col-md-2"})            <div class="col-md-10">                @Html.TextBoxFor(model=>model.Name,new {@class="form-control" })                @Html.ValidationMessageFor(model=>model.Name)            </div>        </div>        <div class="form-group">            <div class="col-md-offset-2 col-md-10">                <input type="submit" value="创建角色" class="btn btn-default"/>            </div>        </div>    </div>}<div >    @Html.ActionLink("返回角色列表","Index")</div>@section Scripts{    @Scripts.Render("~bundles/jqueryval")    }

Detail的页面如下所示

@model Microsoft.AspNet.Identity.EntityFramework.IdentityRole@{    ViewBag.Title = "Details";}<h2>角色详情</h2><div >    <h4>角色用户</h4>    <hr/>    <dl class="dl-horizontal">        <dt>            @Html.Label("目前所属角色:")        </dt>        <dd>            @Html.DisplayFor(model=>model.Name)        </dd>    </dl></div><h4>目前在该角色内的用户清单</h4>@if (ViewBag.UserCount == 0){    <hr/>    <p>该角色内暂时没有用户</p>}<table class="table">    @foreach (var item in ViewBag.Users)    {        <tr>            <td>@item.UserName</td>        </tr>    }</table><p>    @Html.ActionLink("编辑角色","Edit",new { id=Model.Id})    @Html.ActionLink("返回角色列表","Index")</p>

Edit的页面如下所示

@model IdentityLearning_01.Models.AdminViewModels.RoleViewModel@{    ViewBag.Title = "Edit";}<h2>编辑角色</h2>@using (Html.BeginForm()){    @Html.AntiForgeryToken()    <div class="form-horizontal">        <h4>角色修改</h4>        <hr/>        @Html.ValidationSummary(true)        @Html.HiddenFor(model=>model.Id)        <div class="form-group">            @Html.LabelFor(model=>model.Name,new { @class="control-label col-md-2"})            <div class="col-md-10">                @Html.TextBoxFor(model=>model.Name,new {@class="form-control"})                @Html.ValidationMessageFor(model=>model.Name)           </div>        </div>    </div>    <div class="form-group">        <div class="col-md-offset-2 col-md-10">            <input type="submit" value="保存修改" class="btn btn-default"/>        </div>    </div>}<div>    @Html.ActionLink("返回角色列表","Index")</div>@section Scripts{        @Scripts.Render("~/bundles/jqueryval")}

Delete的页面如下所示

@model Microsoft.AspNet.Identity.EntityFramework.IdentityRole@{    ViewBag.Title = "DeleteConfirmed";}<h2>删除角色</h2><h3>你确认要删除此角色??</h3><p>该操作只能删除角色,但不能删除角色内的用户</p><div>    <h4>Role</h4>    <hr />    <dl class="dl-horizontal">        <dt>            @Html.Label("将要删除的角色名称")        </dt>        <dd>            @Html.DisplayFor(model=>model.Name)        </dd>    </dl>    @using (Html.BeginForm())    {        @Html.AntiForgeryToken()        <div class="form-actions no-color">            <input type="submit" value="删除角色" class="btn btn-default" />            @Html.ActionLink("返回角色列表","Index")        </div>    }</div>

运行项目,可以在浏览器中查看~/RolesAdmin/index显示角色列表

至此结束~还需要继续学习~

asp.net identity 学习1