简单角色管理器和授权在ASP.NET MVC 5中不使用Identity(CustomRoleProvider)

时间:2018-02-13 06:22:13

标签: authentication asp.net-mvc-5 authorization roles

自定义角色提供程序和授权,不使用ASP.NET MVC 5中的标识

1 个答案:

答案 0 :(得分: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
{
}