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显示角色列表

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

原文地址:https://www.cnblogs.com/AceZhai/p/5894960.html