Appfuse的权限控制依赖于Struts的Menu机制,common下的menu.jsp是对菜单顺序的定义,详细的菜单项和菜单链接及权限再menu-config.xml中控制,如下:

<Menu name="Logout" title="user.logout" page="/logout" roles="ROLE_ADMIN,ROLE_USER,ROLE_PRODUCT" />

roles中的值即是role表中的name,给那个角色分配菜单的权限,则把角色的name加入到菜单定义的roles中即可。

但使用过程中会发现,这样定义好之后菜单出来是乱的,源自appfuse中的一个Bug,修改文件navbarMenu.vm即可,如下:

 #macro( displayNavbarMenu $menu $count)
   #if ($displayer.isAllowed($menu))
     #set ($count = $count + 1)
     ## set menu title
     #set ($title = $displayer.getMessage($menu.title))
     #if (!$menu.url) #set ($url="javascript:void(0)") #else #set ($url=$menu.url) #end

     ## create a single menu item
     #if ($menu.components.size() == 0)
         <li class="#if ($menu.name == $currentMenu)active#end">
         <a href="$url" title="$title" #if($menu.target)target="$menu.target" #end#if($menu.width)style="width: ${menu.width}px"#end>${title}</a>
     #else ## create multiple menu items in a menu
         #if ($menu.components.size() > 0)
             #set ($hasViewableChildren = false)
             #set ($renderedChildren = 0)
             #foreach ($menuIt in $menu.components)
                 #if ($displayer.isAllowed($menuIt))
                     #set($hasViewableChildren = true)
                     #set($renderedChildren = $renderedChildren + 1)
                 #end
             #end
         #end

         <li#if ($hasViewableChildren) class="dropdown#if ($menu.name == $currentMenu) active#end"#end>
           <a href="#" title="$title"
              #if($menu.target)target="$menu.target" #end
              #if($menu.width)style="width: ${menu.width}px"#end
              class="dropdown-toggle" data-toggle="dropdown">${title}</a>
     #end

     #if ($menu.components.size() > 0)
         #if ($hasViewableChildren)
           <ul class="dropdown-menu">
         #end

         #set ($count = 0)
         #foreach ($menuIt in $menu.components)
             #displayNavbarMenu($menuIt, $count)
         #end

         #if ($hasViewableChildren && ($count == $renderedChildren))
           </ul></li>
         #else
           </ul>
           #if ($count > $renderedChildren)
           </li>
           #end
         #end
     #else
       </li>
       #if ($menu.parent && $count == $menu.parent.components.size())
       ##</ul>
       #end
     #end
   #end
 #end

 #displayNavbarMenu($menu, 0)

navbarMenu.vm

使用Menu控制权限只能控制到菜单的可见性,如果想深入到数据控制需要自己再处理。下面是通过切入OnSubmit方法做的操作控制:

1. 首先定义切面,切入OnSubmit方法

 /**
      * 做权限验证,如果用户无权限,则拒绝请求
      */
     @Override
     public Object invoke(MethodInvocation invocation) throws Throwable {
         try {
             Boolean allow = false;
             // 当前执行的操作
             String action = "";
             // 获取当前操作的用户的角色
             User user = userManager.get(getCurrentUserID());
             Set<Role> roleList = user.getRoles();
             // 当前执行的操作,从Request中获取
             // 基于OnSubmit的签名获取RequestString onSubmit(Greatplace greatplace,
             // BindingResult errors, HttpServletRequest request,
             // HttpServletResponse response)
             if (invocation.getArguments().length == 4
                     && invocation.getArguments()[2].getClass() == HttpServletRequest.class) {
                 HttpServletRequest request = (HttpServletRequest) invocation
                         .getArguments()[2];
                 if (request.getParameter("save") != null) {
                     action = RolePermissionManager.PERMISSION_SAVE;
                 } else if (request.getParameter("delete") != null) {
                     action = RolePermissionManager.PERMISSION_DELETE;
                 } else if (request.getParameter("approve") != null
                         || request.getParameter("unapprove") != null) {
                     action = RolePermissionManager.PERMISSION_APPROVE;
                 }
                 for (Role r : roleList) {
                     allow = RolePermissionManager.hasPermission(r.getName(),
                             action);
                     if (allow)
                         break;
                 }
                 if (!allow) {
                     request.getSession().setAttribute("successMessages",
                             "对不起,您无权执行该操作!");
                     return request.getPathInfo().replace("/", "");
                 }
             }
             Object result = invocation.proceed();
             return result;

         } catch (IllegalArgumentException ex) {
             log.error(ex);
             throw ex;
         }
     }

SubmitAdvice

2. 定义自己的权限验证方法,下面是个简单的示例

public class RolePermissionManager {
    /**
     * 权限项:保存
     */
    public static final String PERMISSION_SAVE = "save";
    /**
     * 权限项:审批
     */
    public static final String PERMISSION_APPROVE = "approve";
    /**
     * 权限项:删除
     */
    public static final String PERMISSION_DELETE = "delete";

    /**
     * 角色:管理员
     */
    public static final String ROLE_ADMIN = "ROLE_ADMIN";
    /**
     * 角色:普通用户
     */
    public static final String ROLE_USER = "ROLE_USER";

    /**
     * 基于角色的权限矩阵
     */
    private static Map<String,List<String>> permissionList;

    /**
     * 初始化角色的权限项
     */
    public  RolePermissionManager(){
    }
    /**
     * 判断当前角色是否有指定的权限项
     * @param roleName 角色名称
     * @param permissionName 权限项名称
     * @return
     */
    public static Boolean hasPermission(String roleName,String permissionName){
        return getPermissionList().get(roleName).contains(permissionName);
    }
    /**
     * 定义角色和权限项的规则
     * @return
     */
    public static Map<String,List<String>> getPermissionList(){
        if(permissionList == null){
            permissionList = new HashMap<String,List<String>>();
            //定义管理员的权限
            List<String> adminPermissionList = new ArrayList<String>();
            adminPermissionList.add(PERMISSION_SAVE);
            adminPermissionList.add(PERMISSION_APPROVE);
            adminPermissionList.add(PERMISSION_DELETE);
            permissionList.put(ROLE_ADMIN, adminPermissionList);
            //定义普通用户的权限
            List<String> userPermissionList = new ArrayList<String>();
            permissionList.put(ROLE_USER, userPermissionList);
        }
        return permissionList;
    }
}

RolePermissionManager

这样基本的权限控制目的就能达到。

关于用户看到的数据权限我通过url中的参数,结合search来控制,但这样只要修改url中的参数就可越过数据权限,有待优化。

Appfuse:权限控制的更多相关文章

  1. 尝试asp.net mvc 基于controller action 方式权限控制方案可行性

    微软在推出mvc框架不久,短短几年里,版本更新之快,真是大快人心,微软在这种优秀的框架上做了大量的精力投入,是值得赞同的,毕竟程序员驾驭在这种框架上,能够强力的精化代码,代码层次也更加优雅,扩展较为方 ...

  2. MongoDB 安全和访问权限控制

    MongoDB的访问控制能够有效保证数据库的安全,访问控制是指绑定Application监听的IP地址,设置监听端口,使用账户和密码登录 一,访问控制的参数 1,绑定IP地址 mongod 参数:-- ...

  3. WebGIS中快速整合管理多源矢量服务以及服务权限控制的一种设计思路

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 在真实项目中,往往GIS服务数据源被其他多个信息中心或者第三方 ...

  4. ASP.NET MVC实现权限控制

    这篇分享一下 ASP.NET MVC权限控制.也就是说某一用户登录之后,某一个用户是否有权限访问Controller,Action(操作),视图等 想实现这些功能,需要在数据库创建好几个表:[User ...

  5. springmvc+spring+mybatis+maven项目集成shiro进行用户权限控制【转】

    项目结构:   1.maven项目的pom中引入shiro所需的jar包依赖关系 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ...

  6. .NET WebAPI 用ActionFilterAttribute实现token令牌验证与对Action的权限控制

    项目背景是一个社区类的APP(求轻吐...),博主主要负责后台业务及接口.以前没玩过webAPI,但是领导要求必须用这个(具体原因鬼知道),只好硬着头皮上了. 最近刚做完权限这一块,分享出来给大家.欢 ...

  7. 浅谈Yii-admin的权限控制

    说到CMS,最需要有的东西就是权限控制,特别是一些复杂的场景,多用户,多角色,多部门,子父级查看等等.最近在开发一个线下销售的东东,这个系统分为管理员端,省代端,客户端,门店端,销售端, 部门端,部门 ...

  8. Go语言实战 - revel框架教程之权限控制

    一个站点上面最基本都会有三种用户角色,未登录用户.已登录用户和管理员.这一次我们就来看看在revel框架下如何进行权限控制. 因为revel是MVC结构的,每一个url其实都会映射到一个具体的Cont ...

  9. Lind.DDD.ExpressionExtensions动态构建表达式树,实现对数据集的权限控制

    回到目录 Lind.DDD框架里提出了对数据集的控制,某些权限的用户为某些表添加某些数据集的权限,具体实现是在一张表中存储用户ID,表名,检索字段,检索值和检索操作符,然后用户登陆后,通过自己权限来构 ...

随机推荐

  1. virtualBox安装Centos7之后

    之前用vmware装虚拟机的时候,直接配置好网卡就可以ping通,可以用ssh登录,然后配置yum源,万事大吉. 但是virtualBox配置却有不同,需要按下面的方法配置: 选中虚拟机->设置 ...

  2. Java中9种IO的读取方式

    数据的读写,按照数据类型可以分为两种:字符流和字节流(二者区别?).所以数据读取方式按照数据类型也可以分为两类:字节流的读取和字符流的读取. 一.字节流读取操作: |  | |-----1.FileI ...

  3. MySQL数据库设置远程访问权限方法总结

    1,设置访问单个数据库权限 mysql>grant all privileges on test.* to 'root'@'%'; 说明:设置用户名为root,密码为空,可访问数据库test 2 ...

  4. 【原创】还原Hyper-V 到一个新的虚拟机

    Context: I need to restore VM31 backup (via 'Windows Server Backup' tool) as another new Hyper-V mac ...

  5. PHP获取IP地址

    获取客户端IP地址:: function getIp(){ if(!empty($_SERVER['HTTP_CLIENT_IP'])){ return $_SERVER['HTTP_CLIENT_I ...

  6. mysql 源码安装

    yum install -y gcc gcc-c++ autoconf libjpeg libjpeg-devel perl perl-CPAN libpng libpng-devel freetyp ...

  7. 超链接的那些事(二): 属性href

    a标签的属性之一 href 1. 定义 href 属性用于指定超链接目标的 URL. 2. 用法     ①. 锚点 同一页面添加锚点 (1)<a href="#test"& ...

  8. bzoj 3118: Orz the MST(单纯形)

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3118 题意:给出一个图以及图中指定的n-1条边组成的生成树.每条边权值加1或者减去 ...

  9. Spring MVC 基础注解之@RequestMapping、@Controller、(二)

    我现在学的是spring4.2 今天主要学习了Spring MVC注解 引入注解可以减少我们的代码量,优化我们的代码. @Controller:用于标识是处理器类: @RequestMapping:请 ...

  10. IPv6 相关的工作简介

    这里说明下,仅仅是IPv6在开发板上的相关的工作简介,没有很详细,都是自己一边积累,一边实践的.能帮助其他人最好,也算是给自己做个备忘录. 一.首先说下DHCPv6相关的.这里我使用的是DHCP6s. ...