ASP.NET MVC 5 中的简单角色管理器和授权,无需使用 Identity(CustomRoleProvider)
Posted
技术标签:
【中文标题】ASP.NET MVC 5 中的简单角色管理器和授权,无需使用 Identity(CustomRoleProvider)【英文标题】:Simple Role Manager and authorization In ASP.NET MVC 5 without using Identity(CustomRoleProvider) 【发布时间】:2018-07-23 11:00:31 【问题描述】:在 ASP.NET MVC 5 中不使用身份的自定义角色提供程序和授权
【问题讨论】:
【参考方案1】:这里是角色控制器
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace SN.Helios.Portal.Controllers
[Authorize(Roles = "Admin")]
public class RolesController : Controller
// GET: Roles
public ActionResult Index()
var context = new ApplicationDbContext();
var rolelist = context.Roles.OrderBy(r => r.RoleName).ToList().Select(rr =>
new SelectListItem Value = rr.RoleName.ToString(), Text = rr.RoleName ).ToList();
ViewBag.Roles = rolelist;
var userlist = context.Employees.OrderBy(u => u.FullName).ToList().Select(uu =>
new SelectListItem Value = uu.FullName.ToString(), Text = uu.FullName ).ToList();
ViewBag.Users = userlist;
ViewBag.Message = "";
return View();
// GET: /Roles/Create
public ActionResult Create()
return View();
//
// POST: /Roles/Create
[HttpPost]
public ActionResult Create(Role role)
try
var context = new ApplicationDbContext();
context.Roles.Add(role);
context.SaveChanges();
ViewBag.Message = "Role created successfully !";
return RedirectToAction("Index");
catch
return View();
public ActionResult Delete(string RoleName)
var context = new ApplicationDbContext();
var thisRole = context.Roles.Where(r => r.RoleName.Equals(RoleName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
context.Roles.Remove(thisRole);
context.SaveChanges();
return RedirectToAction("Index");
//
// GET: /Roles/Edit/5
public ActionResult Edit(string roleName)
var context = new ApplicationDbContext();
var thisRole = context.Roles.Where(r => r.RoleName.Equals(roleName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
return View(thisRole);
//
// POST: /Roles/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Role role)
try
var context = new ApplicationDbContext();
context.Entry(role).State = System.Data.Entity.EntityState.Modified;
context.SaveChanges();
return RedirectToAction("Index");
catch
return View();
// Adding Roles to a user
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult RoleAddToUser(string UserName, string RoleName)
var context = new ApplicationDbContext();
if (context == null)
throw new ArgumentNullException("context", "Context must not be null.");
Employee user = context.Employees.Where(u => u.FullName.Equals(UserName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
Role role = context.Roles.Where(u => u.RoleName.Equals(RoleName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
AssignUserRole assignUserRole = new AssignUserRole
EmployeeId = user.EmployeeID,
RoleId = role.RoleID
;
var EmpRoleToAdd = (from emprole in context.AssignUserRoles
where emprole.EmployeeId == user.EmployeeID && emprole.RoleId == role.RoleID
select emprole).FirstOrDefault();
if (EmpRoleToAdd == null)
context.AssignUserRoles.Add(assignUserRole);
context.SaveChanges();
ViewBag.Message = "Role created successfully !";
else
ViewBag.Message = " This Role already exists for this user !";
// Repopulate Dropdown Lists
var rolelist = context.Roles.OrderBy(r => r.RoleName).ToList().Select(rr => new SelectListItem Value = rr.RoleName.ToString(), Text = rr.RoleName ).ToList();
ViewBag.Roles = rolelist;
var userlist = context.Employees.OrderBy(u => u.FullName).ToList().Select(uu =>
new SelectListItem Value = uu.FullName.ToString(), Text = uu.FullName ).ToList();
ViewBag.Users = userlist;
return View("Index");
//Getting a List of Roles for a User
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult GetRoles(string UserName)
if (!string.IsNullOrWhiteSpace(UserName))
var context = new ApplicationDbContext();
Employee user = context.Employees.Where(u => u.FullName.Equals(UserName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
var roles = user.AssignUserRoles.Select(u => u.Role).Select(u => u.RoleName).ToArray();
ViewBag.RolesForThisUser = roles;
// Repopulate Dropdown Lists
var rolelist = context.Roles.OrderBy(r => r.RoleName).ToList().Select(rr => new SelectListItem Value = rr.RoleName.ToString(), Text = rr.RoleName ).ToList();
ViewBag.Roles = rolelist;
var userlist = context.Employees.OrderBy(u => u.FullName).ToList().Select(uu =>
new SelectListItem Value = uu.FullName.ToString(), Text = uu.FullName ).ToList();
ViewBag.Users = userlist;
ViewBag.Message = "Roles retrieved successfully !";
return View("Index");
//Deleting a User from A Role
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult DeleteRoleForUser(string UserName, string RoleName)
var context = new ApplicationDbContext();
Employee user = context.Employees.Where(u => u.FullName.Equals(UserName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
Role role = context.Roles.Where(u => u.RoleName.Equals(RoleName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
var EmpRoleToDelete = (from emprole in context.AssignUserRoles
where emprole.EmployeeId == user.EmployeeID && emprole.RoleId == role.RoleID
select emprole).FirstOrDefault();
if (EmpRoleToDelete != null)
context.AssignUserRoles.Remove(EmpRoleToDelete);
context.SaveChanges();
ViewBag.Message = "Role removed from this user successfully !";
else
ViewBag.Message = "This user doesn't belong to selected role.";
// Repopulate Dropdown Lists
var rolelist = context.Roles.OrderBy(r => r.RoleName).ToList().Select(rr => new SelectListItem Value = rr.RoleName.ToString(), Text = rr.RoleName ).ToList();
ViewBag.Roles = rolelist;
var userlist = context.Employees.OrderBy(u => u.FullName).ToList().Select(uu =>
new SelectListItem Value = uu.FullName.ToString(), Text = uu.FullName ).ToList();
ViewBag.Users = userlist;
return View("Index");
为角色控制器创建索引视图
@
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_mainView.cshtml";
<div class="row col-sm-12 col-lg-12 col-md-12">
<h1 style="text-align:center">Role Manager</h1>
<br />
</div>
<div class="row col-sm-12 col-lg-12 col-md-12">
<div class="col-sm-6 col-lg-6 col-md-6">
<div class="panel panel-primary">
<div class="panel-heading">
<h4>Role List</h4>
</div>
<div class="panel-body">
<table class="table table-striped table-hover col-sm-6 col-lg-6 col-md-6 ">
@foreach (var role in ViewBag.Roles)
<tr>
<td class="col-sm-1 col-lg-5 col-md-5">
<strong>@role.Text </strong>
</td>
<td class="col-sm-1 col-lg-1 col-md-1">
<span onclick="return confirm('Are you sure to delete?')"><a href="/Roles/Delete?RoleName=@role.Text" class="delLink" style="color:red;">Delete</a></span> |
@Html.ActionLink("Edit", "Edit", new roleName = @role.Text )
</td>
</tr>
</table>
</div> <!-- End Panel Body-->
</div> <!-- End Panel -->
<div class="panel panel-primary">
<div class="panel-heading">
<h4>Create A New Role</h4>
</div>
<div class="panel-body">
@using (Html.BeginForm("Create", "Roles", new @class = "form-horizontal" ))
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<div>
Role name: @Html.TextBox("RoleName")
<input type="submit" value="Save" class="btn-primary" />
</div>
</div> <!--End Panel Body-->
</div> <!--End Panel-->
</div> <!--End First Column-->
<div class="col-sm-6 col-lg-6 col-md-6">
<div class="panel panel-primary">
<div class="panel-heading">
<h4>Add a Role to a User</h4>
</div>
<div class="panel-body">
@using (Html.BeginForm("RoleAddToUser", "Roles"))
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<p>User Name: @Html.DropDownList("UserName", (IEnumerable<SelectListItem>)ViewBag.Users, "Select ...")</p>
<p>Role Name: @Html.DropDownList("RoleName", (IEnumerable<SelectListItem>)ViewBag.Roles, "Select ...")</p>
<p><input type="submit" value="Save" class="btn-primary" /></p>
</div> <!-- End Panel Body-->
</div> <!-- End Panel -->
<div class="panel panel-primary">
<div class="panel-heading">
<h4>List Roles for a User</h4>
</div>
<div class="panel-body">
@using (Html.BeginForm("GetRoles", "Roles"))
@Html.AntiForgeryToken()
<p>
User Name: @Html.DropDownList("UserName", (IEnumerable<SelectListItem>)ViewBag.Users, "Select ...")
<input type="submit" value="Get Roles for this User" class="btn-primary" />
</p>
@if (ViewBag.RolesForThisUser != null)
<div class="alert-info">
<strong>Roles for this user </strong>
<ol>
@foreach (string s in ViewBag.RolesForThisUser)
<li>@s</li>
</ol>
</div>
</div> <!-- End Panel Body-->
</div> <!-- End Panel -->
<div class="panel panel-primary">
<div class="panel-heading">
<h4>Remove Role from User</h4>
</div>
<div class="panel-body">
@using (Html.BeginForm("DeleteRoleForUser", "Roles"))
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<p>User Name: @Html.DropDownList("UserName", (IEnumerable<SelectListItem>)ViewBag.Users, "Select ...")</p>
<p>Role Name: @Html.DropDownList("RoleName", (IEnumerable<SelectListItem>)ViewBag.Roles, "Select ...")</p>
<p><input type="submit" value="Delete this user from Role" class="btn-primary" /></p>
</div> <!-- End Panel Body-->
</div> <!-- End Panel -->
</div> <!--End Second Column-->
</div> <!--Overall Page Wrapper-->
<div class="alert-info col-sm-12 col-lg-12 col-md-12">
@ViewBag.Message
</div>
---------------------------------------------------------------------
为角色控制器创建编辑视图
@model yournamespace.Role
@
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_mainView.cshtml";
<h2>Edit Role</h2>
@Html.ActionLink("Return to Role Manager", "Index")
<hr />
@using (Html.BeginForm())
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
@Html.HiddenFor(model => model.RoleID)
<div>
Role name
</div>
<p>
@Html.TextBoxFor(model => model.RoleName)
</p>
<input type="submit" value="Save" />
创建角色并分配给用户
创建类 CustomRoleProvider
从RoleProvider类继承CustomRoleProvider如下图并实现抽象类。对类进行如下修改
using System;
using System.Linq;
using System.Web.Security;
namespace yournamespace.Models
public class CustomRoleProvider : RoleProvider
public override string ApplicationName get => throw new NotImplementedException(); set => throw new NotImplementedException();
public override void AddUsersToRoles(string[] usernames, string[] roleNames)
throw new NotImplementedException();
public override void CreateRole(string roleName)
throw new NotImplementedException();
public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
throw new NotImplementedException();
public override string[] FindUsersInRole(string roleName, string usernameToMatch)
throw new NotImplementedException();
public override string[] GetAllRoles()
using (var usersContext = new SNHeliosWork2017Entities())
return usersContext.Roles.Select(r => r.RoleName).ToArray();
public override string[] GetRolesForUser(string username)
using (var usersContext = new SNHeliosWork2017Entities())
var user = usersContext.Employees.SingleOrDefault(u => u.FullName == username);
if (user == null)
return new string[] ;
return user.AssignUserRoles == null ? new string[] :
user.AssignUserRoles.Select(u => u.Role).Select(u => u.RoleName).ToArray();
public override string[] GetUsersInRole(string roleName)
throw new NotImplementedException();
public override bool IsUserInRole(string username, string roleName)
using (var usersContext = new SNHeliosWork2017Entities())
var user = usersContext.Employees.SingleOrDefault(u => u.FullName == username);
if (user == null)
return false;
return user.AssignUserRoles != null && user.AssignUserRoles.Select(
u => u.Role).Any(r => r.RoleName == roleName);
public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
throw new NotImplementedException();
public override bool RoleExists(string roleName)
throw new NotImplementedException();
在 web.config 中在 system.web 标签中添加以下代码
<system.web>
<sessionState mode="InProc" timeout="20" cookieless="false"></sessionState>
<authentication mode="Forms">
<forms loginUrl="~/Home/LogIn" defaultUrl="~/" timeout="20" slidingExpiration="true"/>
</authentication>
<roleManager enabled="true" defaultProvider="CustomRoleProvider">
<providers>
<clear/>
<add name="CustomRoleProvider" type="MyProject.Models.CustomRoleProvider" />
</providers>
</roleManager>
</system.web>
首先要注意的是,我已将 enabled 属性设置为 true,以便框架启用角色管理器。然后您必须指定 defaultProvider 属性,如果指定了多个提供程序,则该属性用于标识默认提供程序。但是在这种情况下,我将只有一个提供者 CustomRoleProvider,仍然必须指定默认提供者。这包含在 providers 元素中。 clear 元素用于清除之前为此应用程序存储的所有提供程序,例如默认提供程序。然后,我通过指定名称“CustomRoleProvider”来定义自定义角色提供程序,该名称在 defaultProvider 属性中使用。这包含许多属性。最重要的是 type 属性,其中指定了自定义角色提供程序的完全限定名称 (MyProject.Models.CustomRoleProvider),然后是包含此类型的程序集 (MyProject) 和版本。请注意,如果类型包含在同一个程序集(Web 应用程序本身)中,则只有类型名称是必需的,其他名称是可选的。其他属性是不言自明的,我不会让你厌烦所有这些细节!
使用 authorize 属性来授权控制器 作为,
[Authorize(Roles = "Admin")]
public class RolesController : Controller
【讨论】:
以上是关于ASP.NET MVC 5 中的简单角色管理器和授权,无需使用 Identity(CustomRoleProvider)的主要内容,如果未能解决你的问题,请参考以下文章
如何在asp.net mvc 5身份中的授权属性中使用动态角色