• ABP Zero 导航菜单之角色权限


    本文的项目是官网生成,项目名称为XX,WEB为MVC,以Users权限模块为例解说文章。

    1.定义PermissionNames

    PermissionNames是一个静态类,它在/XX.Core/Authorization之下

    public const string Pages_Users = "Pages.Users";
    // 子权限名称
    // public const string Pages_Users_Create = "Pages.Users.Create";

    2.添加权限控制

    XXAuthorizationProvider.cs,修改SetPermissions方法

    public override void SetPermissions(IPermissionDefinitionContext context)
            {
                //Common permissions
                var pages = context.GetPermissionOrNull(PermissionNames.Pages);
                if (pages == null)
                {
                    pages = context.CreatePermission(PermissionNames.Pages, L("Pages"));
                }
    
                var users = pages.CreateChildPermission(PermissionNames.Pages_Users, L("Users"));//这里是自定义的权限
           //users.CreateChildPermission(PermissionNames.Pages_Users_Create, L("Users_Create"));//这里是自定义的子权限
    }

    3.添加菜单权限

    在web项目下的App_Start中有一个XXNavigationProvider类,它在XXWebModule类的PreInitialize配置

    在XXNavigationProvider类的SetNavigation方法中进行添加菜单,且控制配置权限

     context.Manager.MainMenu
                    .AddItem(
                        new MenuItemDefinition(
                            "Home",
                            L("HomePage"),
                            url: "",
                            icon: "fa fa-home",
                            requiresAuthentication: true
                            )
                    ).AddItem(
                        new MenuItemDefinition(
                            "Tenants",
                            L("Tenants"),
                            url: "Tenants",
                            icon: "fa fa-globe",
                            requiredPermissionName: PermissionNames.Pages_Tenants
                            )
                    ).AddItem(
                        new MenuItemDefinition(
                            "Users",
                            L("Users"),
                            url: "Users",
                            icon: "fa fa-users",
                            requiredPermissionName: PermissionNames.Pages_Users  //这是自定义的权限
                            )
                    ).AddItem(
                        new MenuItemDefinition(
                            "About",
                            L("About"),
                            url: "About",
                            icon: "fa fa-info"
                            )
                    );
            }

    4.展示菜单

    在Layout控制器中,使用局部视图TopMenu进行展示,到这里已经完成

    @using Abp.Collections.Extensions
    @using Zmcor.Web.Views
    @model Zmcor.Web.Models.Layout.TopMenuViewModel
    @{
        var calculateMenuUrl = new Func<string, string>((url) =>
        {
            if (string.IsNullOrEmpty(url))
            {
                return ApplicationPath;
            }
    
            if (UrlChecker.IsRooted(url))
            {
                return url;
            }
    
            return ApplicationPath + url;
        });
    }
    @foreach (var menuItem in Model.MainMenu.Items)
    {
        <li class="@(Model.ActiveMenuItemName == menuItem.Name ? "active" : "")">
            @if (menuItem.Items.IsNullOrEmpty())
            {
                <a href="@calculateMenuUrl(menuItem.Url)">
                    @if (!string.IsNullOrWhiteSpace(menuItem.Icon))
                    {
                        <i class="@menuItem.Icon"></i>
                    }
                    @menuItem.DisplayName
                </a>
            }
            else
            {
                <a href="" data-toggle="dropdown">
                    @if (!string.IsNullOrWhiteSpace(menuItem.Icon))
                    {
                        <i class="@menuItem.Icon"></i>
                    }
                    @menuItem.DisplayName
                </a>
                <ul class="dropdown-menu">
                    @foreach (var subMenuItem in menuItem.Items)
                    {
                        <li>
                            <a href="@calculateMenuUrl(subMenuItem.Url)">
                                @if (!string.IsNullOrWhiteSpace(subMenuItem.Icon))
                                {
                                    <i class="@subMenuItem.Icon"></i>
                                }
                                @subMenuItem.DisplayName
                            </a>
                        </li>
                    }
                </ul>
            }
        </li>
    }

    5.角色和权限的关联

    为用户添加角色

    在UserAppService注入UserManager

     private readonly UserManager _userManager;

    设置角色代码

            /// <summary>
            /// 设置用户角色
            /// </summary> 
            /// <returns></returns>
            public async Task SetUserRole(long currentUserId, long userId, string[] roleName)
            {
                 //权限判断...
                var user = _userRepository.FirstOrDefault(s => s.Id == userId);
                await _userManager.SetRoles(user, roleName);
            }    

    在abp中,默认有Admin角色,如果需要创建自己的角色,如下

    var myRole = new Role(null,"roleName", "我的角色名称");
    await _roleManager.CreateAsync(myRole); 

    为角色分配权限

    控制器

    //视图显示
    [HttpGet]
    public async Task<ActionResult> SetRoleMenu(int Id) { var role = _roleAppService.GetRolesById(Id); var myPermissions = await _roleAppService.GetGrantedPermissionsAsync(Id);//数据库中角色对应的权限 ViewBag.MyPermissions = myPermissions; var rolePermissions = _roleAppService.GetRolePermissionsForManage(); var dictList = new Dictionary<string, string>(); foreach (var item in rolePermissions) { dictList.Add(item.Name, item.DisplayName.ToString().Split(' ')[1].Trim(',')); } ViewBag.RoleList = dictList;//步骤2所定义的权限 return View(role); }
    //提交
    [HttpPost]
    public async Task<JsonNetResult> SetRoleMenu(int Id, string PermissionNames) { try { PermissionNames = Request.Form["PermissionNames"]; if (string.IsNullOrWhiteSpace(PermissionNames)) { return new JsonNetErrorResult("请至少选择一个角色!"); } var roleNames = PermissionNames.Split(',').ToList(); var input = new UpdateRolePermissionsInput() { RoleId = Id, GrantedPermissionNames = roleNames }; var userInfo = GetCurrentUserInfo(); await _roleAppService.UpdateRolePermissions(userInfo.UserId,input); return new JsonNetSuccessResult(); } catch (Exception ex) { return new JsonNetErrorResult("更新出错" + ex.Message); } }

    应用层

      public async Task<List<string>> GetGrantedPermissionsAsync(int roleId)
            {
                List<string> grantedList = new List<string>();
                var grantedPermissions = await _roleManager.GetGrantedPermissionsAsync(roleId);
                foreach (var item in grantedPermissions)
                {
                    grantedList.Add(item.Name);
                }
    
                return grantedList;
            }
      public List<Permission> GetRolePermissionsForManage()
            {
                var grantedPermissions = _permissionManager
                    .GetAllPermissions()
                    .Where(s => s.Name.Contains("Pages."))
                    .ToList();
    
                return grantedPermissions;
            }
     public async Task UpdateRolePermissions(long userId, UpdateRolePermissionsInput input)
            {
                var userAndRole = _userRepository.GetUserAndRolesById(userId);
                if (userAndRole == null || userAndRole.IsAdmin()))
                {
                    throw new UserFriendlyException("您无权限进行该操作");
                } 
                var role = await _roleManager.GetRoleByIdAsync(input.RoleId);
                // 如果有子权限,只要添加父权限,会自动添加子权限
                //var grantedPermission = _permissionManager
                //    .GetAllPermissions()
                //    .Where(p => input.GrantedPermissionNames.Any(s=> p.Name.Contains(s)))
                //    .ToList();
                var grantedPermissions = _permissionManager
                    .GetAllPermissions()
                    .Where(p => input.GrantedPermissionNames.Contains(p.Name))
                    .ToList();
    
                await _roleManager.SetGrantedPermissionsAsync(role, grantedPermissions);
            }

    IPermissionManager使用_permissionManager.GetAllPermissions() 可以获取到在步骤2所添加的权限

    获取当前角色的权限:RoleManager => GetGrantedPermissionsAsync(roleId)
    获取所有权限:IPermissionManager=> GetAllPermissions()

    更新权限:RoleAppService=> UpdateRolePermissions(UpdateRolePermissionsInput input)  

        input.GrantedPermissionNames为需授权的权限列表

     扩展:授权验证

    控制器授权

     [AbpMvcAuthorize(PermissionNames.Pages_Users)]
     public class UsersController : XXControllerBase

    Action授权

    [AbpMvcAuthorize(PermissionNames.Companys)]
            [HttpGet]
            public async Task<ActionResult> Main()
            {
                return View();
            }

    应用层的授权

        [AbpAuthorize(PermissionNames.Pages_Users)]
        public class UserAppService : ZmcorAppServiceBase, IUserAppService

    总结:角色权限这个模块,整体使用的还是比较简单、畅通的,注意还需要配置相关的本地化语言文件。如果存在比较复杂的角色和权限,还需要经过一定的设计才能获得良好的体验

  • 相关阅读:
    Eureka集群----SpringCloud 微服务
    Eureka----SpringCloud 微服务
    SpringCloud 微服务
    yml在线格式转换工具(properties)
    Spring与Mybatis三种整合方法
    Spring缓存注解@CachePut , @CacheEvict,@CacheConfig使用
    Spring事务配置的五种方式
    Spring -- <tx:annotation-driven>注解基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)的区别。
    Spring -- <context:component-scan>使用说明
    web.xml执行顺序
  • 原文地址:https://www.cnblogs.com/xcsn/p/6293125.html
Copyright © 2020-2023  润新知