我正在一个实践项目,这个项目采用struts框架,这个项目一个核心的部分是权限控制的问题,我们的设想是,每个用户进入主界面的时候都能看到相同的东西,但有些链接对某些不具有相应权限的用户来说,他可以看到链接,但链接是不可以点击的(相当于只是普通的文字),而有权限的人,这是一个有效的链接,它可以点击.请问怎么写自定义标签,谢谢

解决方案 »

  1.   

    不必这么费事用tag
    可以写个filter,根据用户权限限定访问
    效果是访问越权页面得到缺陷不够的提示
      

  2.   

    比如系统管理的权限标示是1,普通管理的权限标示是2,一般用户的权限标示是3,
    那么你主页面上有个链接是“系统管理”,可以这样写     <a <%=biaoshi==1?"href=xxx.jsp":""%>>系统管理</a>     这样当系统管理员进入时就显示系统管理的链接,而其它用户进入时就只显示系统管理的字了,
      

  3.   

    谢谢大家 的 热心帮忙 。楼上 的 关于写一个 Filter的解决方法 我想过了,但是我们不想这样去实现,因为点击后给出权限不够提示,这会导致用户操作的效率问题,因为他要点击后才能制定有没有权限,这样浪费时间,利用标签可以控制得更好,标签控制有一种方式是不具有权限就不显示相关链接,但是我们不采用这样的 方式,因为我们想让所有用户看到统一的界面。
    还有的 是,我们这个系统,权限的划分很细致,后台可以定制角色,而角色的权限是 可以后台分配的,也就是说角色是 不固定的 ,角色对应的 权限也是 不 固定的。因此小菜的方法不是很合适。
    我昨天晚上临时看了一下标签方面的内容,有点眉目。但是还希望大家能帮忙想个方法,如果能 给个简单的范例更好,因为我们的项目时间不多,现在学的话,可能要花满多时间。谢谢,再次谢谢大家的参与,谢谢大家的无私奉献!
      

  4.   

    向liaohaiying(小菜)学习
    另外LZ怎么解决的 我也想知道哈
      

  5.   

    楼主,如果我说的这种方法不行的话,那我还真的想不出什么方法解决你的问题了,你说权限划分的分细致,而且还经常更改,那行,我再做个例子
    比如系统管理的权限标示是1,普通管理的权限标示是2,一般用户的权限标示是3,不管你的权限怎么更改,在你的数据库中的用户表中的权限字段肯定写的是用户的当前权限对吧
    那么你主页面上有三个链接是“管理”(系统管理和普通管理可点),“新建”(普通管理和一般用户可点),“编辑”(就普通管理可点),
    可以这样写     <a <%if(biaoshi==1 || biaoshi==2){%>href=xxx.jsp<%}%>>系统管理</a>
    <a <%if(biaoshi==2 || biaoshi==3){%>href=xxx.jsp<%}%>>新建</a><a <%if(biaoshi==2){%>href=xxx.jsp<%}%>>编辑</a>,这样就OK了,因为每个按钮它所需要的权限是一定的,不可能说系统管理这个链接今天可被系统管理级别的点,明天又可被一般用户级别的点吧,
      

  6.   

    我还不知道你的权限到底是怎么控制的,那你看看我做的,给你参考参考
    <input name="Purview" type="hidden" id="Purview">
    <input name="selectAll" value=1 type="checkbox">全部
    <input name="select1" value=1 type="checkbox" >用户管理
    <input name="select2" value=1 type="checkbox" >客户管理
    <input name="select3" value=1 type="checkbox" >商品管理
    <input name="select4" value=1 type="checkbox" >销售管理
    <input name="select5" value=1 type="checkbox" >入库管理
    <input name="select6" value=1 type="checkbox" >新建销售
    <input name="select7" value=1 type="checkbox" >新建入库
    <input name="Submit" type="button" onclick="return check()" value="提 交">
    <script language="JavaScript">   
    <!--
    function check()  
    {
        var strRelationType1="";
        var strRelationType="";
        for(var i=0;i<form1.elements.length;i++)
        {
            if(form1.elements[i].type=="checkbox")
            {
                if(form1.elements[i].checked)
                {
                    strRelationType = form1.elements[i].value;
                }
                else
                {
                    strRelationType = 0;
                }
                strRelationType1 = strRelationType1 + "/" + strRelationType;
            }         
        }
        document.form1.Purview.value=strRelationType1;
    if(!form1.select1.checked && !form1.select2.checked && !form1.select3.checked && !form1.select4.checked && !form1.select5.checked && !form1.select6.checked)
        {
        alert("权限不能为空!");
        return false;
    }
    form1.submit();
    }
    //-->
    </script>
    这是权限写入页面,比如你选择了第1、3、4、5的权限,那么存入数据库的是1/0/1/1/1/0/0/0这样的
      

  7.   

    这是显示页面,希望对你有点帮助,把权限取出分开,为1的就显示,为0的不显示
    <%
       int pintsysuserid = 0;
       if(session.getAttribute("SysUserID")!=null)
       {
           pintsysuserid = Integer.parseInt(session.getAttribute("SysUserID").toString());
       } 
       SysUserServices pobjSysUserServices = new SysUserServices();
       SysUser pobjSysUser = pobjSysUserServices.getuserdetail(pintsysuserid);
        String[] parrsplit=null;
       if(pobjSysUser!=null)
       {
        if(pobjSysUser.getPurview()!=null)
        {
            parrsplit=pobjSysUser.getPurview().split("/");
            
         }
       }
    %>
    <%
                if(parrsplit[1].equals("1") || parrsplit[2].equals("1"))
                {
                %>
                <input style="cursor:hand" type="button" name="Submit5"class="button1" value="用户管理" onclick="window.parent.main.location.href('yhgl/yhgl.jsp')">
                <%
                }
                if(parrsplit[1].equals("1") || parrsplit[3].equals("1"))
                {
                %>
                <input style="cursor:hand" type="button" name="Submit5"class="button1" value="客户管理" onclick="window.parent.main.location.href('khgl/khgl.jsp')">
                <%
                }
                if(parrsplit[1].equals("1") || parrsplit[4].equals("1"))
                {
                %>
                <input style="cursor:hand" type="button" name="Submit5"class="button1" value="商品管理" onclick="window.parent.main.location.href('spgl/spgl.jsp')">
                <%
                }
                if(parrsplit[1].equals("1") || parrsplit[5].equals("1"))
                {
                %>
                <input style="cursor:hand" type="button" name="Submit5"class="button1" value="销售管理" onclick="window.parent.main.location.href('xsgl/xsgl.jsp')">
                <%
                }
                if(parrsplit[1].equals("1") || parrsplit[6].equals("1"))
                {
                %>
                <input style="cursor:hand" type="button" name="Submit5"class="button1" value="入库管理" onclick="window.parent.main.location.href('rkgl/rkgl.jsp')">
                <%
                }
                if(parrsplit[1].equals("1") || parrsplit[7].equals("1"))
                {
                %>
                <input style="cursor:hand" type="button" name="Submit5"class="button1" value="新建销售" onclick="window.parent.main.location.href('xsgl/xsadd.jsp')">
                <%
                }
                if(parrsplit[1].equals("1") || parrsplit[8].equals("1"))
                {
                %>
                <input style="cursor:hand" type="button" name="Submit5"class="button1" value="新建入库" onclick="window.parent.main.location.href('rkgl/rkadd.jsp')">
                <%
                }
                if(parrsplit[1].equals("1") || parrsplit[2].equals("1"))
                {
                %>
                <input style="cursor:hand" type="button" name="Submit5"class="button1" value="新建用户" onclick="window.parent.main.location.href('yhgl/yhadd.jsp')">
                <%
                }
                if(parrsplit[1].equals("1") || parrsplit[3].equals("1"))
                {
                %>
                <input style="cursor:hand" type="button" name="Submit5"class="button1" value="新建客户" onclick="window.parent.main.location.href('khgl/khadd.jsp')">
                <%
                }
                %>
      

  8.   

    呵呵,多谢小菜,你做的很好,达到实现的效果,非常感谢!
    我们这个系统的权限是可定制的,是根据资源的URI来标识的.因此在判断的时候可能要做得比较复杂一点.即使权限是固定的,不允许定制,那么有时候判断也是比较复杂.比如删除权限,我们首先要判断他是否有删除权限,再要看看这项资源是否在他删除权限可支配的资源范围内,这样有可能就要访问数据库资源来确定,因为你不可能把所有的信息放在session里面,有些东西还有可能要到数据库去验证的.当然小菜的方法也是可以解决这样的问题,但问题是,在一个大的系统里面,JSP页面内嵌入太多的Java 代码不是一个好方法,这样会造成维护的困难以及重用性降低.
    在MVC模式里面,我们强调视图,控制,和模型层分开,在这样的情况下,采用filter或者自定义标签是一个非常好的方法,我现在就是写自定义标签来实现的,页面上的代码几乎没有.我觉得这样很好,不知道大家的意见如何,不如大家一起来讨论一下,一起学习.
    最后,非常感谢小菜,感谢 你的热心帮忙和分享你的想法,非常感谢,交个朋友如何?
      

  9.   

    呵呵,11点多了,睡觉前上来溜达溜达.忽然想到权限控制这个问题,有点想法和大家交流一下.
    小菜在上面提到:
    ====================================================
    比如系统管理的权限标示是1,普通管理的权限标示是2,一般用户的权限标示是3,不管你的权限怎么更改,在你的数据库中的用户表中的权限字段肯定写的是用户的当前权限对吧
    那么你主页面上有三个链接是“管理”(系统管理和普通管理可点),“新建”(普通管理和一般用户可点),“编辑”(就普通管理可点),
    可以这样写     <a <%if(biaoshi==1 || biaoshi==2){%>href=xxx.jsp<%}%>>系统管理</a>
    <a <%if(biaoshi==2 || biaoshi==3){%>href=xxx.jsp<%}%>>新建</a><a <%if(biaoshi==2){%>href=xxx.jsp<%}%>>编辑</a>,这样就OK了,因为每个按钮它所需要的权限是一定的,不可能说系统管理这个链接今天可被系统管理级别的点,明天又可被一般用户级别的点吧,
    ====================================================我觉得这会造成一点问题,问题在于<a <%if(biaoshi==1 || biaoshi==2){%>href=xxx.jsp<%}%>>系统管理</a>,这显然是把一项资源用2个权限标示,就是说这项资源可以被系统管理级别和普通管理级别这2个权限访问,这会产生问题.假设我有100项不同的资源,原来这个资源可以被 系统管理级别 或者 普通管理级别的人访问,那么也许有一天我不想把其中80项资源给普通管理级别
    访问了,那么我就要修改这80个连接,注意这是是不能通过删除权限来实现,因为如果你删除了2,那么另外20项连接你必须修改,因为这20项资源我并不想禁止普通管理级别的来访问.那么怎么解决呢?我想问题出在把某项资源用多个权限标示.如果某项资源只用一个权限标示(不同资源对应不同权限),就不会产生这样的问题,因为不管你是谁,我想让你访问,就分配给你权限,不想你访问就删除你权限,因为不同资源的权限是不一样的,这样就不会影响到其他的了.还有权限不直接分配给用户,而是先分配给角色,然后把角色分配给用户,这样有更高的灵活性和效率,这是RBAC的控制方式.
      

  10.   

    我想用自定义标签的方式来实现小菜上面的解决方案,原理和小菜的一样,只是更体现了MVC模式而已.由于时间比较晚,我用伪代码描述一下.
    标签:<app:createLink rightId=" " url=" " showName="" />
    rightId表示该资源对应的权限,url表示该资源的地址,showName表示显示的名字,就是<a ...>名字</a>中的名字.
    .tld文件中:
    <tag>
    <name>createLink</name>
    <tagclass>taglib.CreateLink</tagclass>
    <bodycontent>empty</bodycontent>
    <attribute>
    <name>rightId</name>
    <required>true</required>
    <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
    <name>url</name>
    <required>true</required>
    <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
    <name>showName</name>
    <required>true</required>
    <rtexprvalue>true</rtexprvalue>
    </attribute> </tag>对应的CreateLink.class里实现:
    通过DAO取得用户的权限集allRights,然后判断allRights里是否包含有rightId,如果有,则:
    out.print("<a href='" + url + "'>");
    out.print(showName);
    out.println("</a>");
    如果没有则:
    out.print(showName);这样,拥有该权限的产生的是一个有效的链接,否则只是普通的文字,无法点击.
      

  11.   

    哈哈,很高兴我说的对你有所帮助,你的解决方法非常不错,不过你前面并没有提到资源权限可改变的问题,用户—角色—权限—资源,这个模式是大型管理系统中最完善的机制了,我给你的例子只是我做的一个小型进销存系统中用的,用这个模式就更明了,更简单了,首先资源有建改删的权限控制,再将这个权限给特定的角色,再为不同的用户赋于不同的角色,这样进入系统中不是判断用户的权限,而是判断用户所属角色的权限,再把有这些权限的资源显示出来,原理一样,不过你的解决方法是我以前没有用过的,顶了!
    关于说“交个朋友如何?”,哈哈,我真是受宠若惊啊,http://baby.mob8.cn 上面有我的Q号,要不你留下联系方式我加你也行