MVC之角色的管理

角色是给用户分配了访问指定资源的权限,保护系统的安全性。
一个用户(User)可能会有多种角色(Role)
在这里插入图片描述
在这里插入图片描述
微软官方关于角色的管理的描述以及具体解决方案
仔细看看,描述的比较详细了

1.在db数据库中,添加role数据表:分配用户具有的角色

CREATE TABLE [dbo].[role] (
    [Id]     INT          IDENTITY (1, 1) NOT NULL,
    [UserId] INT          NOT NULL,
    [Role]   VARCHAR (50) NOT NULL,
    PRIMARY KEY CLUSTERED ([Id] ASC),
    FOREIGN KEY ([UserId]) REFERENCES [dbo].[user] ([Id])
);

添加测试数据:
在这里插入图片描述
更新EF的edmx文件.
2.启用角色管理,以及使用自定义的 Role Management Providers
微软官方Role Management Providers的说明
在web.config配置文件中,添加roleManager节点:

  <system.web>
    <!--配置authentication节点:拒绝匿名用户访问(相对于整个Web应用程序)
      loginUrl:用户如果没有登录,则跳转到登录页面
    -->
    <authentication mode="Forms">
      <forms loginUrl="~/Account/Login"></forms>
    </authentication>
    <!--启用角色管理-->
    <roleManager defaultProvider="myRolePrv" enabled="true">
      <providers>
        <clear/>
        <add name="myRolePrv" type="AuthenticationDemo.MyRoleProvider"/>
      </providers>
    </roleManager>
    <compilation debug="true" targetFramework="4.5.2" />
    <httpRuntime targetFramework="4.5.2" />
  </system.web>

使用defaultProvider节点配置Provider

添加自定义的角色管理提供类MyRoleProvider:
需要继承RoleProvider抽象类,实现一些抽象方法
在当前项目下直接添加:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using AuthenticationDemo.Models;
namespace AuthenticationDemo
{
    public class MyRoleProvider : 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()
        {
            throw new NotImplementedException();
        }
	    
        /// <summary>
        /// 重写GetRolesForUser方法获取当前登录用户的所有角色(role)
        /// </summary>
        /// <param name="username">用户名</param>
        /// <returns></returns>
        public override string[] GetRolesForUser(string username)
        {
            using (var context = new dbEntities())
            {
                //query all roles with current user
                var res = (from user in context.users
                           join role in context.roles on user.Id equals role.UserId
                           where user.username == username
                           select role.Role).ToArray();
                return res;
            }
        
        }

        public override string[] GetUsersInRole(string roleName)
        {
            throw new NotImplementedException();
        }

        public override bool IsUserInRole(string username, string roleName)
        {
            throw new NotImplementedException();
        }
        public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
        {
            throw new NotImplementedException();
        }
        public override bool RoleExists(string roleName)
        {
            throw new NotImplementedException();
        }
    }
}

在重写的GetRolesForUser()方法中,重写了逻辑,获取当前登录用户的角色(角色管理的前提:用户必须先经过认证处理)。
注意:
通过以上方式的实现,那么role management system会自动调用自定义的provider以及其中的方法

3.在Home控制器中的动作方法,添加角色管理:
上一篇已经讲过了,mvc中的注解属性类:AuthorizeAttribute,用来进行授权处理的,此类中两个比较重要的属性:RolesUser,用来限制于只有具有指定的角色和用户才能访问已授权的动作方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using AuthenticationDemo.Models;
namespace AuthenticationDemo.Controllers
{
    [Authorize]  //强制要进行身份验证(拒绝进行匿名访问)
    public class HomeController : Controller
    {
        dbEntities db = new dbEntities();
        // GET: Home
        [AllowAnonymous] //允许进行匿名访问
        public ActionResult Index()
        {
            return View();
        }

        [Authorize(Roles ="Admin,Customer")]
        public ActionResult getUserList()
        {
            var user = db.users.ToList();
            return View(user);
            
        }
        
        [Authorize(Roles = "Admin")]
        public ActionResult About()
        {
            return View();
        }

        [Authorize]
        public ActionResult Service()
        {
            return View();
        }
    }
}

分析:
当已登录的用户通过URL访问有role限制的页面,角色管理系统会自动调用你自定义的provider里的GetRolesForUser(),根据登录用户的username获取当前用户的角色(Role),和Roles属性中的值进行比较,如果有对应的role,允许访问此动作方法,否则不允许访问。

添加getUserList视图:
只有Admin的用户,才能获取所有用户信息

@model IEnumerable<AuthenticationDemo.Models.user>

@{
    ViewBag.Title = "getUserList";
}

<h2>getUserList</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.username)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.password)
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.username)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.password)
        </td>
        <td>
          @*检测当前登录用户是否具有Admin角色*@
            @if (User.IsInRole("Admin"))
            {
                    @Html.ActionLink("Edit", "Edit", new { id=item.Id }) 
                    @Html.ActionLink("Details", "Details", new { id=item.Id }) 
                    @Html.ActionLink("Delete", "Delete", new { id=item.Id })
            }
        </td>
    </tr>
}
</table>

修改_layout 分部视图(主页面的导航部分):
对根据role进行显示/隐藏指定的内容

//检查当前登录用户的Role(根据用户的role 显示 / 隐藏内容

@if (User.Identity.IsAuthenticated)//检查用户是否已登录(登录成功实际上就已经验证了用户)
{
<li><a href="">Dear @User.Identity.Name</a></li>
<li>@Html.ActionLink("Logout", "Logout", "Account")</li>

//检查当前登录用户的Role(根据用户的role 显示 / 隐藏内容
if (User.IsInRole("Admin") || User.IsInRole("Customer")
{
<li> @Html.ActionLink("About us ", "About", "Home")</li>
<li>@Html.ActionLink("User List", "getUserList", "Home")</li>
}
}
else
{
<li>@Html.ActionLink("Login", "Login", "Account")</li>
}

测试案例:
admin用户具有两个role:Admin和Customer
运行程序,发现:
在这里插入图片描述
未登录状态下,导航部分,并没有About Us和User List链接,说明我们设置的role已起作用了。

以admin账号进行登录:
链接也已显示出来了
在这里插入图片描述
点击User List链接:
用户列表也是ok的
在这里插入图片描述
这边是在前台去check用户的角色,然后显示/隐藏指定的页面内容,如果用户是直接使用url去访问,那么就是在动作方法上添加的Role属性去check匹配了,根据是否具有指定role决定是否允许访问。

总结:

角色管理的前提,就是身份的认证,用户处于登录状态才能进行角色管理控制,比如给用户添加或者移除指定的Role等等操作。

具体查询微软文档说明中的这一部分:Role Management,User Identity,and Membership

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值