??xml version="1.0" encoding="utf-8" standalone="yes"?>欧美在线一二三区,九九九九久久久久,h视频在线免费http://www.aygfsteel.com/RongHao/category/20773.html心有多大Q舞台就有多?/description>zh-cnWed, 06 Jun 2007 17:27:43 GMTWed, 06 Jun 2007 17:27:43 GMT60关于权限pȝ设计的一些问与答http://www.aygfsteel.com/RongHao/archive/2007/06/05/122191.htmlronghaoronghaoTue, 05 Jun 2007 09:36:00 GMThttp://www.aygfsteel.com/RongHao/archive/2007/06/05/122191.htmlhttp://www.aygfsteel.com/RongHao/comments/122191.htmlhttp://www.aygfsteel.com/RongHao/archive/2007/06/05/122191.html#Feedback0http://www.aygfsteel.com/RongHao/comments/commentRss/122191.htmlhttp://www.aygfsteel.com/RongHao/services/trackbacks/122191.html
问题Q?/span>数据范围的控Ӟ(x)“事实上不是每个用户都可以看到所有记录的。以财务理ZQ部门经理只能查看金额小?W的数据;而ȝ理则没有限制”。象q样要根据数据的某个字段Ҏ(gu)据范围进行控Ӟ应该实现呢,是通过AOP动态改变执行的SQL吗?q样g不太可行Q如果要执行的SQL特别复杂Q那动态改变SQL 更难了。现在的应用中一般用hibernateQ这L(fng)话就变成了动态改变HQLQ也是难的?br>回答Q?/span>目前在我的代码里是通过AOP动态改变执行的SQLQ改变HQL实很困难,但是改变criteria比较简单了。对于特别复杂的sqlQ我的徏议是把这些SQL直接写到你的业务E序里去Q或者单独配|出来,和ibatis比较cM?br>
问题Q?/span>单条数据ACL权限Q由于数据是不断增加的,所以要对单条数据的ACL权限Q不应该是数据已存在Q然后再对存在的数据授权Q应该是Ҏ(gu)U规则进行授权。以你D的个人通讯录ؓ(f)例,各h自己l护自己的通讯记录Q数据只对自己可见,要想实现对自q数据的可再授权,应该是对W合某个规则的数据进行授权,也就是说 “要执行授权操作的人就是数据的拥有?#8221;q是个规则,那是不是应该对这个规则授权呢?br>回答Q?/span>我理解的和你不一栗我的理解是q样的,实际中我把单条数据的权限划分为拥有、浏览、修攏V删除四U权限,用户拥有哪种权限可以对数据q行相应哪种操作?#8220;要执行授权操作的人就是数据的拥有?#8221;也可以理解ؓ(f)“要执行授权操作的人就必须有该数据的拥有权?#8221;Q这可以理解ZU规则,但我更愿意把它理解ؓ(f)一U习(fn)惯,很显然对?fn)惯授权是没有意义的。当然这里是存在规则的,q种规则单的说是q样Q当我新增一条数据时Q哪些h对该条数据拥有拥有的权限Q哪些h对该条数据拥有浏览的权限Q哪些h对该条数据拥有修改的权限Q哪些h对该条数据拥有删除的权限。权限相兌录会(x)在新增这条数据时Ҏ(gu)该规则生成。在上面的例子里Q这一规则体现在:(x)各h自己l护自己的通讯记录Q数据只对自己可见。也是说在用户新增自己的通讯记录Ӟpȝ同时往权限表里插入了该用户对该记录的一个拥有权限记录?br>
问题Q?/span>数据字段权限Q要实现Ҏ(gu)个字D늚权限控制Q那是不是应该所有字D应该有个默认的操作呢,或者默认就是只可以查看Q要q行修改的话必L权。但是通常整个应用中的字段非常多,q样是乎不太合理。那是不是可以做成所有字D默认就是可以CRUD的,只有要控制的字段才进行权限判断。同P׃使用 Hibernate来进行持久化Q那对字D늚控制是不是就变成了对cM属性的控制?br>回答Q?/span>数据字段权限一直是一个很隑֊的事情,实际上我很們֐于把q个问题推到面来解冟뀂其实所有的权限控制最后都是要通过面来表现的。其实对字段来说Q所需要的权限也很单:(x)可见/不可?只读/可修攏V这L(fng)话,通过标签的Ş式来控制字段的显C、只d昑־很自然。对字段的权限记录可以放入到数据库,或者xml中,与具体的pojocL有关p,当渲染页面的时候,由标{来d相关权限记录q控制显C?br>
问题Q?/span>角色权限的承:(x)角色权限的扉K过规则来做Q这个规则应该怎么设计呢?br>回答Q?/span>q个问题其实是一个分d注点的问题。你可以抽象Z个规则接口,q个接口定义了对部门、角色下的用戯(g)言Q哪些权限是可以从部门角色承的Q承几U,哪些是不可以的。然后再具体实现。更灉|的方式是定义Z个配|文Ӟq行时可以灵zM攏V?br>



ronghao 2007-06-05 17:36 发表评论
]]>
Ҏ(gu)据权限控制的实验http://www.aygfsteel.com/RongHao/archive/2007/03/23/105948.htmlronghaoronghaoFri, 23 Mar 2007 10:35:00 GMThttp://www.aygfsteel.com/RongHao/archive/2007/03/23/105948.htmlhttp://www.aygfsteel.com/RongHao/comments/105948.htmlhttp://www.aygfsteel.com/RongHao/archive/2007/03/23/105948.html#Feedback3http://www.aygfsteel.com/RongHao/comments/commentRss/105948.htmlhttp://www.aygfsteel.com/RongHao/services/trackbacks/105948.html
   List getOrders(String userId){
             String sql;
             Role role
=orgService.getRoleForUser(userId);
             
if(("admin").equals(role.getName()))
                   sql
="select * from order";
             
else
                   sql
="select * from order where author="+userId;
             Object o
=excuteSql(sql);
             
return excute(o);
        }

恩,不错Q很好的完成了权限控制。过了没多久Q公司发展了Q老板增加了h手,老板发话了,我要讄区域理员分不同区域的订单。管理员分ؓ(f)北京地区理员,上v地区理员,其他地区理员和ȝ理员。怎么办?修改代码?br />
    List getOrders(String userId){
             String sql;
             Role role
=orgService.getRoleForUser(userId);
             
if(("admin").equals(role.getName()))
                  sql
="select * from order";
             
else if("bjadmin").equals(role.getName()))
                         sql
="select * from order where area='beijing'";
             
else if("shadmin").equals(role.getName()))
                         sql
="select * from order where area='shanghai'";
             
else if("qtadmin").equals(role.getName()))
                         sql
="select * from order where area='qita'";
             
else
                   sql
="select * from order where author="+userId;
             Object o
=excuteSql(sql);
             
return excute(o);
        }

恩恩Q这搞定了Q可怎么也感觉不爽,也许该做点什么。一堆if/else权限判断让h心烦Q再写个cLq些sql理h好了Q那动手吧
  public class SqlManager{
          String getSql(String userId){
                  String sql;
          Role role
=orgService.getRoleForUser(userId);
          
if(("admin").equals(role.getName()))
              sql
="select * from order";
          
else if("bjadmin").equals(role.getName()))
                   sql
="select * from order where area='beijing'";
          
else if("shadmin").equals(role.getName()))
                   sql
="select * from order where area='shanghai'";
          
else if("qtadmin").equals(role.getName()))
                   sql
="select * from order where area='qita'";
          
else
            sql
="select * from order where author="+userId;
          
return sql;
          }
  }

q样把权限判断移到SqlManager里,业务代码清爽了很多,再增加管理员׃改SqlManager好了
    List getOrders(String userId){
             String sql
=sqlManager.getSql(userId);
             Object o
=excuteSql(sql);
             
return excute(o);
        }

呵呵Q看hq不错。但是等{,我们的业务方法ؓ(f)什么需要userIdq个参数呢,是啊是啊Q权限判断用C它,但是那和我业务又有什么关pdQ不爽。现在AOP不是很流行吗Q你不用AOP怎么能说明你技术高呢?快用吧快用吧Q用不着也要想着Ҏ(gu)用?br />业务Ҏ(gu)化ؓ(f)
    List getOrders(){
             String sql
="";
             Object o
=excuteSql(sql);
             
return excute(o);
        }

对excuteSqlҎ(gu)我们来AOP一下,注入权限判断q的sql.嘿嘿Q技术水q_一ơ得C昄。业务方法是单了Q可我的SqlManager倒是复杂了,q是很不q福。咋办?用个配置文g吧,hibernate不是老鼓励我们把sql写在配置文g里吗Q?br />
    <xml>
        <sql role
="admin">select * from order</sql>
        <sql role
="bjadmin">select * from order where area='beijing'</sql>
        <sql role
="shadmin">select * from order where area='shanghai'</sql>
        <sql role
="qtadmin">select * from order where area='qita'</sql>
        <sql role
="none">select * from order where author=?</sql>
    </xml>

q样SqlManager可以把行数~小了,可以敏捷一点了?br />
    public class SqlManager{
          String getSql(String userId){
                  String sql;
          Role role
=orgService.getRoleForUser(userId);
          sql
=getSqlfromXml(role.getName());
          
return sql;
          }
          
          String getSqlfromXml(String rolename){
                  .
          }
  }

以后再增加权限连c都不用修改了,改xml好了。等{,你是不是把问题太单化了。现在不仅仅是订单,货物也要q么分区域管理?br />不错Q我们应该想着通用一下了。这P把SqlManager抽象一?br />
        String abstract getSqlfromXml(String rolename);

然后做几个子cd?OrderSqlManager, GoodsSqlManager .
可是Q哥们,书上_(d)要面向接口编E,你这样不太好吧。没事,再接口一下:(x)
   public interface SqlManagerInterface{
           String getSql(String userId);
   }

q是没法用啊。也许现在可以看看acegi的provider机制了,把这一大堆SqlManager全部作ؓ(f)providerQ根据不同的模块选择不同的providerQ统一拦截excuteSqlҎ(gu)Q生成不同的sql到数据库执行。xml不爽Qdb也可以。然后,再然后呢Q改你的cdQ重构,和acegi整合一下?br />呵呵Q完全是个h的一些想法,希望多批评提提意见。我惌辄意思是Q也许把数据权限再抽象一些,以组件的形式来减R入是可以做到的?img src ="http://www.aygfsteel.com/RongHao/aggbug/105948.html" width = "1" height = "1" />

ronghao 2007-03-23 18:35 发表评论
]]>
Ҏ(gu)限系l设计的再思?/title><link>http://www.aygfsteel.com/RongHao/archive/2007/03/21/105345.html</link><dc:creator>ronghao</dc:creator><author>ronghao</author><pubDate>Wed, 21 Mar 2007 11:04:00 GMT</pubDate><guid>http://www.aygfsteel.com/RongHao/archive/2007/03/21/105345.html</guid><wfw:comment>http://www.aygfsteel.com/RongHao/comments/105345.html</wfw:comment><comments>http://www.aygfsteel.com/RongHao/archive/2007/03/21/105345.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.aygfsteel.com/RongHao/comments/commentRss/105345.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/RongHao/services/trackbacks/105345.html</trackback:ping><description><![CDATA[什么是权限pȝQ权限系l究竟在整个pȝ中vC么作用,或者说权限pȝ必须提供哪些功能Q?br />谈谈个h的看法,我认为授权和验证是一个权限系l最基本的功能,而一个更完善的权限系l会(x)增加上如何验证和验证后如何处理这两种功能?br />对于一个权限系l的基本元素Q我觉得只有两个QPrincipal(权限M)Q权限。用P用户l,角色{都可以抽象为权限主体这个概念;而权限则是资?操作的抽象。权限可分ؓ(f)两种Q一U纯_就是资源,没有操作Q也可以认ؓ(f)是默认操作;另外一U就是带操作的资源。授权本w没有什么说的,赋予权限M权限Q验证简单的说就是传入权限主体和当前操作需要的权限Q然后验证返回说可以操作或是不可以操作yes/no。同时要注意的是验证的时候需要一个类Q接口)来返回用户当前所拥有的权限,然后与当前操作需要的权限q行比对Q最后返回比对结果?br />以acegiZQ下面分开来说明:(x)<br />首先Qacegi是没有授权功能的Q它单把权限M与资源配|在了xml里,当然q也带来了可扩展性,可以看一个配|:(x)<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">                /index.jsp=ROLE_ANONYMOUS,ROLE_USER<br />                /hello.htm=ROLE_ANONYMOUS,ROLE_USER<br />                /logoff.jsp=ROLE_ANONYMOUS,ROLE_USER<br />                /switchuser.jsp=ROLE_SUPERVISOR<br />                /j_acegi_switch_user=ROLE_SUPERVISOR<br />                /acegilogin.jsp*=ROLE_ANONYMOUS,ROLE_USER<br />                /**=ROLE_USER</span></div><br />/index.jspQ?hello.htmq些URL都是资源Q因为它默认的操作就是访问,所以访问特定URL成了一个权限,ROLE_ANONYMOUS,ROLE_USER无疑是权限M?br />AcegiҎ(gu)法访问权限的配置也是和上面一L(fng)?br />然后Q看看acegi的验证,其实它的验证是一个个的VoterQ当你访问一个方法时Q由它获得当前用户和需要的权限Q就是该Ҏ(gu)Q,然后q回yes/no?br />OKQ这是一个完整的权限pȝ了。当然acegi如果仅仅提供上面两个基本功能Q它是不?x)向现在q样成功的,它最大的亮点是提供了如何验证和验证后如何处理这两种功能。对url它提供了filterQ方法也一h供了InterceptorQ这是如何验证Q和我们在action里验证没有Q何区别,只是换了一U方式而已。然后它验证后的处理方式Qyesql往下执?no抛出异常最后再处理q个异常。我们在执行每个action前同样也可以做到q一炏V?br />q里着重要提到的是数据权限。比如说A只能寚w门A下的数据有查看权限,B可以寚w门A的数据有修改权限和对部门B的数据的查看权限?br />看v来这个需求是比较ȝ的,但是我们可以按上面说的拆分以下:(x)<br />资源1Q部门A下的数据  Q资?Q部门B下的数据<br />操作1Q查看;    操作2Q修?br />产生四种权限Q?br />权限1Q资?+操作1 Q权?Q资?+操作2Q权?Q资?+操作1Q权?Q资?+操作2<br />权限MA拥有权限Q? Q?权限MB拥有权限Q?Q?<br />q样非常清C?br />ȝQ我始终认ؓ(f)拥有授权和验证功能就完成了一个完整的权限pȝ。至于如何去校验权限Q不你是filterq是aop那是具体实现时的l节Q采取的不同{略。而验证后的处理则是和不同{略相对应的。在你考虑设计一个权限系l时首先考虑的是如何实现授权和验证,而不是一开始就考虑我是采取filterQ还是aopQ还是动态改变sql?br />谢谢wolfsquareQ它?a href="/wolfsquare/archive/2006/07/04/56606.html">blog相关</a><img src ="http://www.aygfsteel.com/RongHao/aggbug/105345.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/RongHao/" target="_blank">ronghao</a> 2007-03-21 19:04 <a href="http://www.aygfsteel.com/RongHao/archive/2007/03/21/105345.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Acegi ACL使用说明http://www.aygfsteel.com/RongHao/archive/2007/03/20/105069.htmlronghaoronghaoTue, 20 Mar 2007 11:07:00 GMThttp://www.aygfsteel.com/RongHao/archive/2007/03/20/105069.htmlhttp://www.aygfsteel.com/RongHao/comments/105069.htmlhttp://www.aygfsteel.com/RongHao/archive/2007/03/20/105069.html#Feedback0http://www.aygfsteel.com/RongHao/comments/commentRss/105069.htmlhttp://www.aygfsteel.com/RongHao/services/trackbacks/105069.html
先看看ȝ配置Q?br />
<bean id="contactManagerSecurity" class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
      
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
      
<property name="accessDecisionManager"><ref local="businessAccessDecisionManager"/></property>
      
<property name="afterInvocationManager"><ref local="afterInvocationManager"/></property>
      
<property name="objectDefinitionSource">
         
<value>
            sample.contact.ContactManager.getAll=AFTER_ACL_COLLECTION_READ
            sample.contact.ContactManager.getById=AFTER_ACL_READ
            sample.contact.ContactManager.delete=ACL_CONTACT_DELETE
            sample.contact.ContactManager.deletePermission=ACL_CONTACT_ADMIN
            sample.contact.ContactManager.addPermission=ACL_CONTACT_ADMIN
         
</value>
      
</property>
   
</bean>
该拦截器实现了org.aopalliance.intercept.MethodInterceptor接口。在Ҏ(gu)被调用之前,拦截器会(x)先调?AuthenticationManager判断用户w䆾是否已验证,然后从objectDefinitionSource中获取方法所对应的权限,再调用AccessDecisionManager来匹配用h限和Ҏ(gu)对应的权限。如果用h有够权限调用当前方法,则抛?AccessDeniedException使方法不能被调用。方法调用后?x)调用AfterInvocationManager对返回的l果q行再次处理。下面依ơ说明?br />AccessDecisionManager的配|?/b>Q?br />
<bean id="businessAccessDecisionManager" class="org.acegisecurity.vote.AffirmativeBased">
      
<property name="allowIfAllAbstainDecisions"><value>false</value></property>
      
<property name="decisionVoters">
         
<list>
            
<ref local="roleVoter"/>
            
<ref local="aclContactReadVoter"/>
            
<ref local="aclContactDeleteVoter"/>
            
<ref local="aclContactAdminVoter"/>
         
</list>
      
</property>
   
</bean>
AccessDecisionManager接口有decide()和support()Ҏ(gu)。decide()Ҏ(gu)决策是否批准通过x法是否容许调用,如果没抛出AccessDeniedException则ؓ(f)允许讉K资源Q否则拒l访问。support()Ҏ(gu)是根据配|属性和受保护资源的cL判断是否需要对该资源作出决{判断?br />AccessDecisionManager?decisionVoters属性需要一个或多个Voter(投票?QVoter必须实现AccessDecisionVoter 接口。Voter的工作是d配用户已拥有的权限和受保护的资源要求的权限,在该资源有相应权限的情况下,如果匚w则投允许,否则投反对票?
allowIfAllAbstainDecisions属性表C是否允许所有都弃权时就通过。Voter的实现类RoleVoter在当受保护资源的名字由ROLE_开始时才参与投?br />AccessDecisionManager有三个实现类Q功能各不相?
AffirmativeBased: 当至有一个Voter投允许票时才通过
UnanimousBased: 没有Voter投反对票时才通过
ConsensusBased: 当所有Voter都投允许时才通过
下面列出一个Voter的配|?/b>Q?br />
<bean id="aclContactDeleteVoter" class="org.acegisecurity.vote.BasicAclEntryVoter">
      
<property name="processConfigAttribute"><value>ACL_CONTACT_DELETE</value></property>
      
<property name="processDomainObjectClass"><value>sample.contact.Contact</value></property>
      
<property name="aclManager"><ref local="aclManager"/></property>
      
<property name="requirePermission">
        
<list>
          
<ref local="org.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/>
          
<ref local="org.acegisecurity.acl.basic.SimpleAclEntry.DELETE"/>
        
</list>
      
</property>
   
</bean>
上面W一个配|里有这么一行:(x)sample.contact.ContactManager.delete=ACL_CONTACT_DELETE
所以在调用sample.contact.ContactManager.deleteq个Ҏ(gu)时aclContactDeleteVoter?x)参与投,它?x)获得sample.contact.Contactq个对象Q这个对象从deleteҎ(gu)的参C获得Q,然后通过aclManager去获得当前用户对该Contact实例的ACL权限Q最后拿q个权限与我们需要的权限比对Q我们配|需要的权限是org.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION和org.acegisecurity.acl.basic.SimpleAclEntry.DELETE。如果我们通过aclManager获得的权限包括这两个配置的权限之一QVoter投容许,Ҏ(gu)容许调用。如果不包括Q那对不P反对,AccessDecisionManager׃(x)抛出AccessDeniedException。方法拒l调用?br />AclManager的配|?/b>Q?br />
<bean id="aclManager" class="org.acegisecurity.acl.AclProviderManager">
      
<property name="providers">
         
<list>
            
<ref local="basicAclProvider"/>
         
</list>
      
</property>
   
</bean>

   
<bean id="basicAclProvider" class="org.acegisecurity.acl.basic.BasicAclProvider">
      
<property name="basicAclDao"><ref local="basicAclExtendedDao"/></property>
   
</bean>

   
<bean id="basicAclExtendedDao" class="org.acegisecurity.acl.basic.jdbc.JdbcExtendedDaoImpl">
      
<property name="dataSource"><ref bean="dataSource"/></property>
   
</bean>
AclManager是整个ACL中一个很核心的概念,它包含了两个Ҏ(gu)AclEntry[] getAcls(Object domainInstance)?br />AclEntry[] getAcls(Object domainInstance, Authentication authentication)。在了解q两个方法前Q我们先了解AclEntryq个对象。AclEntry只是一个接口,pȝ中一般都是造型为BasicAclEntry。它包括了这个Entry所保护的domainObject instanceQ这里是ContactQ,实际它实C是以AclObjectIdentity来替代这个domainObject的(domainClass+domainObjectIdQ;它包括了谁(RecipientQ拥有这个domainObject instance以及(qing)他所对这个domainObject instance的操作权限(maskQ?br />一个domainObject instance对应了多个AclEntryQ比如一条通讯录张三可以查看,而李四可以管理,一个Contact instance对应了两个AclEntryQ第一个AclEntry包含信息Q所保护的domainObjectQContactQ?谁(张三Q,权限Q查看);W二个AclEntry包含信息Q所保护的domainObjectQContactQ?谁(李四Q,权限Q管理)?br />q样AclManager的两个方法就很好理解了getAcls(Object domainInstance)q回所有这个domainInstance所对应的权限信息,
getAcls(Object domainInstance, Authentication authentication)在第一个方法返回结果的基础上做了过滤,qo(h)出和authenticationQ当前用P相关的权限信息。如果当前用h张三Q则q回与张三对应的记录?br />
q样Acegi׃(x)拦截业务Ҏ(gu)发挥相应的作用,但是在业务方法返回一个List或是单个domainObject instance的时候,同样也是需要把用户没有权限查看的domainObject instanceqo(h)掉的Q这时就要用afterInvocationManager了,看配|?/b>Q?br />
<bean id="afterInvocationManager" class="org.acegisecurity.afterinvocation.AfterInvocationProviderManager">
      
<property name="providers">
         
<list>
            
<ref local="afterAclRead"/>
            
<ref local="afterAclCollectionRead"/>
         
</list>
      
</property>
   
</bean>
   
   
<!-- Processes AFTER_ACL_COLLECTION_READ configuration settings -->
   
<bean id="afterAclCollectionRead" class="org.acegisecurity.afterinvocation.BasicAclEntryAfterInvocationCollectionFilteringProvider">
      
<property name="aclManager"><ref local="aclManager"/></property>
      
<property name="requirePermission">
        
<list>
          
<ref local="org.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/>
          
<ref local="org.acegisecurity.acl.basic.SimpleAclEntry.READ"/>
        
</list>
      
</property>
   
</bean>
   
   
<!-- Processes AFTER_ACL_READ configuration settings -->
   
<bean id="afterAclRead" class="org.acegisecurity.afterinvocation.BasicAclEntryAfterInvocationProvider">
      
<property name="aclManager"><ref local="aclManager"/></property>
      
<property name="requirePermission">
        
<list>
          
<ref local="org.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/>
          
<ref local="org.acegisecurity.acl.basic.SimpleAclEntry.READ"/>
        
</list>
      
</property>
   
</bean>
afterAclCollectionRead?x)对配置AFTER_ACL_COLLECTION_READ的方法进行拦截,q里是sample.contact.ContactManager.getAllҎ(gu)Q它?x)遍历方法返回的domainObjectQ然后挨个通过aclManager判断当前用户对domainObject的权限,如果和需要的权限不和Q则qo(h)掉。呵呵,传说中的虎牙子就在此时生了Q?br />afterAclRead则依ơ类推?br />参考了ss wiki里相关的文档Q特别是差沙和cac的文档,写的相当好。另外acegi的代码也是相当的易读?br />

ronghao 2007-03-20 19:07 发表评论
]]>
Ҏ(gu)限分cȝ补遗http://www.aygfsteel.com/RongHao/archive/2007/03/20/104902.htmlronghaoronghaoTue, 20 Mar 2007 03:04:00 GMThttp://www.aygfsteel.com/RongHao/archive/2007/03/20/104902.htmlhttp://www.aygfsteel.com/RongHao/comments/104902.htmlhttp://www.aygfsteel.com/RongHao/archive/2007/03/20/104902.html#Feedback1http://www.aygfsteel.com/RongHao/comments/commentRss/104902.htmlhttp://www.aygfsteel.com/RongHao/services/trackbacks/104902.html

六是数据范围操作权限Q?/span>其实q个是可以和数据范围权限合ؓ(f)一个的。具体的区别在与对已l划分范围的数据再增加操作的权限控制。还是以财务理ZQ部门经理只能查看金额小?/span>1W的数据;而ȝ理则没有限制Q可以查看所有数据。但是请注意Q他们只能对q些数据拥有查看的权限,不能修改或是删除Q而胦务则拥有修改的权限。在一些情况下可以?b style="">模块操作权限和数据范围权?/b>的叠加来满对该权限的需求,但是在权限复杂的情况下,q个权限独立出来是必ȝ?/span>

事实上现有系l就?span style="font-family: 宋体;">?b style="">模块操作权限和数据范围权?/b>的叠加来满q部分需求的?br />


ronghao 2007-03-20 11:04 发表评论
]]>
权限pȝ功能说明http://www.aygfsteel.com/RongHao/archive/2007/03/18/104606.htmlronghaoronghaoSun, 18 Mar 2007 14:46:00 GMThttp://www.aygfsteel.com/RongHao/archive/2007/03/18/104606.htmlhttp://www.aygfsteel.com/RongHao/comments/104606.htmlhttp://www.aygfsteel.com/RongHao/archive/2007/03/18/104606.html#Feedback5http://www.aygfsteel.com/RongHao/comments/commentRss/104606.htmlhttp://www.aygfsteel.com/RongHao/services/trackbacks/104606.html

权限pȝZacegi框架实现了从前端面到后台数据全面的控制。在权限控制中,它将权限分成五类Q?/span>  
 
一是系l权?/span>Q主要是Ҏ(gu)块ؓ(f)单位的权限划分,具体是用户对该模块可见不可见,能不能对该模块进行再授权的操作。表现在用户界面是用户dpȝ主页面后Q可以看到的剙菜单和左?/span>outlookbar菜单的内Ҏ(gu)制。作为粒度最大的权限控制Q系l实Cweb url的防盗链功能。D例来_(d)用户新开发的一个叫车辆理的模块,配置?/span>http://localhost/business/carmanage.action?/span>url下,当对q个模块的权限加以控制后Q直接在览器中键入http://localhost/business/carmanage.action同样是无法访问的Q而不仅仅是界面内容的屏蔽?/span>
 
二是模块操作权限Q在Ҏ(gu)个模块的权限做出控制后,q里l箋Ҏ(gu)块的览、增加,修改Q删除的操作权限做出控制Q也可以理解为对象权?/span> 。还是以车辆理ZQ不同的人员对这个模块的操作是不同的Q有些用户可以新增,删除车辆Q而有些用户则只是可以对R辆的情况查看不能修改。通过pȝ提供的一?/span>web 标签Q页面可以根据用户不同的操作权限屏蔽相应的功能按键。例如删除,新增按键。用L(fng)q页面直接操作相应业务方法同样也做到了严格的控制Q没有权限的讉K?x)被拒绝同时记入日志?/span> 
 
三是数据范围权限Q又可以叫做对象实例U权限。事实上不是每个用户都可以看到所有记录的。以财务理ZQ部门经理只能查看金额小?/span>1W的数据;而ȝ理则没有限制?/span>权限pȝ对这部分权限也做Z全面的控Ӟ可以Ҏ(gu)数据cdQ相应字D|D围做出控制?/span>
 
四是单条数据ACL权限Qؓ(f)了满x严格的数据权限要求,权限pȝҎ(gu)据实C单条数据?/span>ACL权限Q具体说是Ҏ(gu)条数据都实现了权限控Ӟ每条数据都有一到多条权限数据与其对应。以个h通讯录ؓ(f)例,每个用户都维护自q一个通讯录,q些数据都只是对本h可见Q其他h不可见。但用户可以对这些数据做出授权,某条联pL式以授权的方式共享给其他人,q赋予不同的权限Q包括拥有,修改Q删除,览四种权限?/span>

五是数据字段权限Q通过xml配置Q?/span>保证了用L(fng)最粒度的权限控制。每条业务数据权限可以精控制到每一个字Dc(din)包括单个字D늚可否览以及(qing)可否修改。保证了敏感信息的安全性?/span>


授权Q作为权限系l的重要部分Q?/span>提供了相当方便的操作体验。以?wi)状的方式展现权限主体(用户Q角Ԍ部门Q以?qing)资源,方便Q直接,一目了然。区别与传统?/span>RBAC模型Q权限不仅仅可以分配l角Ԍ也可以分配给部门和用戗实际的权限是这三者权限的叠加Q最大限度的方便用户操作。考虑到用L(fng)扩展Q系l提供两个权限承规则接口,用户可以自定义权限承的规则。例如,部门A下有部门A1Q部?/span>A的权限是否由部门A1l承?/span>

整个权限pȝ的数据都建立在系l统一的缓存管理之上,用户d后,其权限信息即被缓存,保证pȝ的效?/span>


ronghao 2007-03-18 22:46 发表评论
]]>
对Acegi ACL扩展的构?/title><link>http://www.aygfsteel.com/RongHao/archive/2006/12/14/87634.html</link><dc:creator>ronghao</dc:creator><author>ronghao</author><pubDate>Thu, 14 Dec 2006 02:20:00 GMT</pubDate><guid>http://www.aygfsteel.com/RongHao/archive/2006/12/14/87634.html</guid><wfw:comment>http://www.aygfsteel.com/RongHao/comments/87634.html</wfw:comment><comments>http://www.aygfsteel.com/RongHao/archive/2006/12/14/87634.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.aygfsteel.com/RongHao/comments/commentRss/87634.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/RongHao/services/trackbacks/87634.html</trackback:ping><description><![CDATA[ <p>数据权限分ؓ(f)两种Q一U是数据范围权限Q一U是具体到每一条数据的权限。前一U可以通过动态构建SQL解决Q后一U?br />g必须通过ACL不可。于是就惛_Acegi ACL做一个通用的扩展。以通讯录ؓ(f)?br />先看一个ȝ配置<br />  <bean id="contactManagerSecurityInterceptor" class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor"><br />      <property name="authenticationManager"><ref bean="authenticationManager"/></property><br />      <property name="accessDecisionManager"><ref local="aclDecisionManager"/></property><br />      <property name="afterInvocationManager"><ref local="afterInvocationManager"/></property><br />      <property name="objectDefinitionSource"><br />         <value><br />            com.ronghao.acltest.services.ContactService.saveContact=AFTER_ACL_CREAT<br />            com.ronghao.acltest.services.ContactService.getAllContacts=AFTER_ACL_COLLECTION_READ<br />            com.ronghao.acltest.services.ContactService.getContact=AFTER_ACL_READ<br />         </value><br />      </property><br />   </bean><br />扩展一、当你增加一条记录的同时向ACL表里插入权限信息 q个SS已经做到了这一?br />  ss有一个接口标C哪些doamin需要acl保护 AclDomainAware<br />  q里再扩展一个基c?Q目的很单当d数据旉加上权限信息<br />  public  class BasicAclDomain implements AclDomainAware {</p> <p>    private int mask; //权限</p> <p>    public int getMask() {<br />        return mask;<br />    }</p> <p>    public void setMask(int mask) {<br />        this.mask = mask;<br />    }<br />  }<br />  <br />  public class Contact extends BasicAclDomain <br />扩展二、读取列表时q行数据的过滤,原来的acegi在ACL的集合后处理?x)造成分页产生虎牙?br />     q里采用前拦截,在acl表里增加一个className字段,里面放上PO的类?q样可以~小<br />     数据查询范围.实际在读取集合时,是先到acl表里完成分页,然后获得对Contact的real id list <br />     然后拦截实际DAOҎ(gu),动态改变SQL成select * from real_data where id in ( {real id list} )的Ş?q样O(jin)K?<br />     分页实际是对acl表里相应记录?分页'.比如说取W?0条到20?实际是取acl表里相应记录的第10条到20条来动态改变SQL <br />     q个可以写一个专门被用来拦截的类 SecurityDAO Ҏ(gu)findByPageACL(query, page)QContactServiceImpl中getAllContacts<br />     Ҏ(gu)强制调用该方?br />扩展三、后拦截。这里AFTER_ACL_COLLECTION_READ和AFTER_ACL_READ的目的就很简单了Q因Z们不再进行数据过 滤, 他们只是把用户对每条记录的mask取最大权限就O(jin)KQ然后往PO里setMask。这样PO带了权限信息到页面上非常好处理了。比如button的显C等{?br />扩展四、封装AclService,对单条记录的ACL权限理。比如增加权限、修Ҏ(gu)限、删除权限。这个acegi的最?.0.3已经开始加入?br />具体在实C感觉acl的vote完全是鸡肋,全部不用。另外在扩展二中如果用户数据要实现数据库排序比较困难。所以就有了q未实现的构惻I(x)<br />一、PO创徏向ACL表里插入权限信息时可以配|不同的{略Q比如通讯录创Z条新信息只能创徏者可以看q管理,而你往请假表里插一条新信息后,不仅你了Q你的上怹可以同时看到。(q个q是比较easyQ?br />二、用h据要实现数据库排序。需要在ACL_OBJECT_IDENTITY里增加几个额外的字段Q把po相应的排序字D同步更新到ACL表中。什么?不好做?写配|文件啊Q再对PO的updateq行后拦截?br />xp栗实玎ͼQ?/p> <img src ="http://www.aygfsteel.com/RongHao/aggbug/87634.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/RongHao/" target="_blank">ronghao</a> 2006-12-14 10:20 <a href="http://www.aygfsteel.com/RongHao/archive/2006/12/14/87634.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>acegi整合CAShttp://www.aygfsteel.com/RongHao/archive/2006/08/29/66389.htmlronghaoronghaoTue, 29 Aug 2006 04:31:00 GMThttp://www.aygfsteel.com/RongHao/archive/2006/08/29/66389.htmlhttp://www.aygfsteel.com/RongHao/comments/66389.htmlhttp://www.aygfsteel.com/RongHao/archive/2006/08/29/66389.html#Feedback3http://www.aygfsteel.com/RongHao/comments/commentRss/66389.htmlhttp://www.aygfsteel.com/RongHao/services/trackbacks/66389.html例子Q原有系lA和系lBQ现在在它们之间做SSO?br />很显ӞpȝA和B都是CAS client。首先是讉KpȝAQ干掉A的登陆页面,在A的入口判断有没有Ticket(据Q,如果没有则重定向到CAS serverQ在CAS server提供CredentialQ大多数情况是用户名和密码Q。CAS server的作用非常简单:(x)是来验证用户密码。正,则发送Ticket。CAS?UTicketQ分别是TGC(通过cookie发送的ticketQ,STQService Ticket),PGT,PGTIOU,PT。其中PGT,PGTIOU,PT属于代理ticketQ这里不作讨论。具体可以参?br />http://www.aygfsteel.com/openssl/archive/2006/04/26/SSO_CASProxy.html
TGC和ST的关pd以打个比方:(x)
我去中央?sh)视塔去玩,l果发现Cq有个v底世界。SSO前我是这么玩的:(x)先去?sh)视塔买张门,玩完了;再去底世界买张门票Q玩完了。发现真累,两个景点q么q还要买两次门票Q就不能搞个通票吗?于是SSO。于是这P(x)我先ȝ(sh)视塔Q门卫告诉我你不能进去要买票Q于是把我送到通票售票处(CAS serverQ买(dQ,买吧Q于是给了我两张,注意Q是两张Q一张发到我手里Q上面写着仅限?sh)视塔用(STQ;靠,不是通票吗,咋仅限电(sh)视塔使用Q别急,q有一张票QTGCQ通过cookie发送你看不见。h家说了保证没问题Q我咋办Q这是h家的规矩Q那先ȝ吧。出了电(sh)视塔我直扑v底世界,
门卫说要底世界,不会(x)吧,我买的通票啊,门卫说不着急,又把我送回通票售票处(CAS serverQ,通票售票处(CAS serverQ一看,发现我有TGCQ嘿嘿,q家伙买q票了不用再乎ͼ不用再登录)Q于是换我一张票QSTQ上面写着仅限底世界使用Q于是我拿着q张又Lv底世界了。于是我明白了啥是SSO了,不就是把买票Ҏ(gu)换票了吗Q?br />比方完了Q最开始的例子也就不往下l了。需要注意的是系lA和B整合SSO需要把A、B的用户密码集中管理,你说A中我的用户名是张三,B中是李四QSSO能不能帮我自动识别,回答是不行的?br />l箋Acegi的整合?br />CAS server是做用户密码验证Q具体的权限授权的工作还是在各个单个pȝ里,也不应该交给它管。做用户密码验证需要AuthenticationHandler。这个具体就是根据Credentialq回一个boolean值来判断你输入的用户密码正不正确。acegi提供了一个实现?br />以一个典型的web讉K来说明整个过E?br />1、用戯问一个受acegi安全保护的页面或业务Ҏ(gu)Q?br />2、用h有登陆的话显然会(x)抛出AuthenticationException
3、配|exceptionTranslationFilter捕获q个异常重定向到CAS server登陆面
       <bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter">
            
<property name="authenticationEntryPoint"><ref local="casProcessingFilterEntryPoint"/></property>
        
</bean>
        
        
<bean id="casProcessingFilterEntryPoint" class="org.acegisecurity.ui.cas.CasProcessingFilterEntryPoint">
            
<property name="loginUrl"><value>https://my.company.com/cas/login</value></property>
            
<property name="serviceProperties"><ref local="serviceProperties"/></property>
        
</bean>
        
        
<bean id="serviceProperties" class="org.acegisecurity.ui.cas.ServiceProperties">
            
<property name="service"><value>https://server.company.com/myapp/j_acegi_cas_security_check</value></property>
            
<property name="sendRenew"><value>false</value></property>
        
</bean>
serviceProperties里的service属性即在CAS server登陆完毕后由CAS server重定向回来的面
  https://my.company.com/cas/login?service=https%3A%2F%2Fserver.company.com%2Fmyapp%2Fj_acegi_cas_security_check
4、CAS server(g)查是否有TGC Q没有则登陆Q登陆后q回。这里屁股后面跟着的即STQTGC通过cookie一q发送到客户端?br />   https://server.company.com/myapp/j_acegi_cas_security_check?ticket=ST-0-jhsdfguwgeds
5、配|casProcessingFilter来处理返回STQ和以前的authenticationProcessingFilter比较cMQ?br />
   <bean id="casProcessingFilter" class="org.acegisecurity.ui.cas.CasProcessingFilter">
        
<property name="authenticationManager"><ref local="authenticationManager"/></property>
        
<property name="authenticationFailureUrl"><value>/casfailed.jsp</value></property>
        
<property name="defaultTargetUrl"><value>/</value></property>
        
<property name="filterProcessesUrl"><value>/j_acegi_cas_security_check</value></property>
    
</bean>
6、配|a(chn)uthenticationManager
   <bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
      
<property name="providers">
         
<list>
            
<ref local="casAuthenticationProvider"/>
         
</list>
      
</property>
   
</bean>
   
  
<bean id="casAuthenticationProvider" class="org.acegisecurity.providers.cas.CasAuthenticationProvider">
        
<property name="casAuthoritiesPopulator"><ref local="casAuthoritiesPopulator"/></property>
        
<property name="casProxyDecider"><ref local="casProxyDecider"/></property>
        
<property name="ticketValidator"><ref local="casProxyTicketValidator"/></property>
        
<property name="statelessTicketCache"><ref local="statelessTicketCache"/></property>
        
<property name="key"><value>my_password_for_this_auth_provider_only</value></property>
    
</bean> 
具体作用的是casAuthenticationProviderQcasAuthenticationProvider通过 casProxyTicketValidator来校验ST
    <bean id="casProxyTicketValidator" class="org.acegisecurity.providers.cas.ticketvalidator.CasProxyTicketValidator">
        
<property name="casValidate"><value>https://my.company.com/cas/proxyValidate</value></property>
        
<property name="serviceProperties"><ref local="serviceProperties"/></property>
    
</bean> 
casProxyTicketValidator又具体实现调用了CAS Client library里的ProxyTicketValidator校验STQProxyTicketValidator 比较有意思了Q它做了个HTTPShCAS serverQ结果还是CAS server来校验STQ绕了一大圈Q?br /> https://my.company.com/cas/proxyValidate?service=https%3A%2F%2Fserver.company.com%2Fmyapp%2Fj_acegi_cas_security_check
 重新回到CAS serverQ它接受到这个HTTPShQ检查ST是否与对q个service发行的STdQ吻合的话CAS server׃(x)发回一个肯定的XML回复Q里面包含了用户名(username)。剩下的EASY了,casProxyTicketValidator解析XMLQcasProxyDecider处理代理QcasAuthoritiesPopulatorҎ(gu)解析后的XML获得userQ最后就是casAuthenticationProvider构造AuthenticationQ这里是CasAuthenticationTokenQ?br />7、重新回到casProcessingFilterQ它?yu)Authentication攑օHttpSession
q样完成了整个q程

ronghao 2006-08-29 12:31 发表评论
]]>
agegi整合经?/title><link>http://www.aygfsteel.com/RongHao/archive/2006/08/03/61475.html</link><dc:creator>ronghao</dc:creator><author>ronghao</author><pubDate>Thu, 03 Aug 2006 02:45:00 GMT</pubDate><guid>http://www.aygfsteel.com/RongHao/archive/2006/08/03/61475.html</guid><wfw:comment>http://www.aygfsteel.com/RongHao/comments/61475.html</wfw:comment><comments>http://www.aygfsteel.com/RongHao/archive/2006/08/03/61475.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.aygfsteel.com/RongHao/comments/commentRss/61475.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/RongHao/services/trackbacks/61475.html</trackback:ping><description><![CDATA[在web.xml中一般我们这样配|:(x)<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);">filter</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">mapping</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);">filter</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">name</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);">Acegi Filter Chain Proxy</span><span style="color: rgb(0, 0, 0);"></</span><span style="color: rgb(0, 0, 0);">filter</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">name</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);">url</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">pattern</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 128, 0);">/*</span><span style="color: rgb(0, 128, 0);"></url-pattern><br />    </filter-mapping></span></div>q样agegi对所有的urlq行了过滤检查,以一个显C树(wi)状菜单ؓ(f)例,它甚臛_面上的每一个图片连接都q行了检查,实际上这是完全没有必要,可以q样Q?br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);">filter</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">mapping</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);">filter</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">name</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);">Acegi Filter Chain Proxy</span><span style="color: rgb(0, 0, 0);"></</span><span style="color: rgb(0, 0, 0);">filter</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">name</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);">url</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">pattern</span><span style="color: rgb(0, 0, 0);">>*</span><span style="color: rgb(0, 0, 0);">.action</span><span style="color: rgb(0, 0, 0);"></</span><span style="color: rgb(0, 0, 0);">url</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">pattern</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 0);"></</span><span style="color: rgb(0, 0, 0);">filter</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">mapping</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"><br /><br />    </span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);">filter</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">mapping</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);">filter</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">name</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);">Acegi Filter Chain Proxy</span><span style="color: rgb(0, 0, 0);"></</span><span style="color: rgb(0, 0, 0);">filter</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">name</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);">url</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">pattern</span><span style="color: rgb(0, 0, 0);">>*</span><span style="color: rgb(0, 0, 0);">.ftl</span><span style="color: rgb(0, 0, 0);"></</span><span style="color: rgb(0, 0, 0);">url</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">pattern</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 0);"></</span><span style="color: rgb(0, 0, 0);">filter</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">mapping</span><span style="color: rgb(0, 0, 0);">></span></div>呵呵Q检查范围羃?yu)了Q可是登陆时pȝ?04错误Q找不到/j_acegi_security_checkQ因?j_acegi_security_checkq个路径是agegi自己的,所以再增加一行拦截过滤就O(jin)K<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);">filter</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">mapping</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);">filter</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">name</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);">Acegi Filter Chain Proxy</span><span style="color: rgb(0, 0, 0);"></</span><span style="color: rgb(0, 0, 0);">filter</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">name</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);">url</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">pattern</span><span style="color: rgb(0, 0, 0);">>/</span><span style="color: rgb(0, 0, 0);">j_acegi_security_check</span><span style="color: rgb(0, 0, 0);"></</span><span style="color: rgb(0, 0, 0);">url</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">pattern</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 0);"></</span><span style="color: rgb(0, 0, 0);">filter</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">mapping</span><span style="color: rgb(0, 0, 0);">></span></div><img src ="http://www.aygfsteel.com/RongHao/aggbug/61475.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/RongHao/" target="_blank">ronghao</a> 2006-08-03 10:45 <a href="http://www.aygfsteel.com/RongHao/archive/2006/08/03/61475.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>乱弹权限pȝl二http://www.aygfsteel.com/RongHao/archive/2006/07/06/56998.htmlronghaoronghaoThu, 06 Jul 2006 09:47:00 GMThttp://www.aygfsteel.com/RongHao/archive/2006/07/06/56998.htmlhttp://www.aygfsteel.com/RongHao/comments/56998.htmlhttp://www.aygfsteel.com/RongHao/archive/2006/07/06/56998.html#Feedback0http://www.aygfsteel.com/RongHao/comments/commentRss/56998.htmlhttp://www.aygfsteel.com/RongHao/services/trackbacks/56998.html 一?span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">             考虑实现

1?span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">  pȝ权限考虑l箋采用原先实现方式Q在构造功能树(wi)和树(wi)状菜单时作出权限判断Q?/span>

2?span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">  数据库操作权限考虑应用 Acegi 扩展Q在业务层对相应的浏?/span> / 增加 / 修改 / 删除的业务方法进行拦截;

3?span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">  行数据权限考虑采用 AOP 的方式在用户讉K相关资源时根据用h限动态构?/span> SQL 注入C务方法里Q再׃务方法传递到 DAO 里;

4?span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">  列数据权限考虑做入面Q这里不再讨论?/span>

5?span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">  大集中模式下的权限管理,本质也是行数据权限Q即在每ơ数据访问时都需要强制判断用h属部?/span> Group ?br />

一?/font> 权限理详细解决Ҏ(gu)

用户、用L(fng)、角色设计如下:(x)
Image00000.bmp

Principal 即ؓ(f)权限M

1?span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">  pȝ权限授权

web 面Q?/span>

面上显CZ|(wi)Q左侧显C用戗用L(fng)和角色树(wi)Q右侧显C功能模块树(wi)Q功能模块树(wi)的节点上跟两个复选框Q分别是可见 / 可再授权。点ȝ戗用L(fng)和角色树(wi)上的节点对相应权限主体进行授权?/span>

很显然可再授权权限包含可见权限?/span>

数据库实玎ͼ(x)

?/span> ACL 实现Q表设计如下Q?/span>

资源 ID Q权限主?/span> ID Q权限主?/span> TYPE Q资?/span> TYPE Q资源操作权限,条g查询语句 queryStr ?/span>

说明Q?/span>

权限M TYPE  三种Q?/span> user/group/role

资源 TYPE         两种Q?/span> function/method  此时对系l权限来说是 function

条g查询语句 queryStr    数据范围控制   此时对系l权限该字段无效

对象Q?br />Image00002.bmp

用户保存授权信息Ӟ先删除该权限M ID 的授权记录,再更新?/span>

2?span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">  数据库操作权限授?/span>

q里引入一个新的对象:(x)数据库操作资源对?/span>   DataResource

表设计如下:(x)

ID Q?/span> NAME Q?/span> parentId Q?/span> resStr Q?/span> resType Q?/span> desc

说明如下Q?/span>

ID

NAME 资源名称 例如Q新增用?/span>

parentId

resStr  业务Ҏ(gu)地址 例如Q?/span> com.way.sevice.UserService.addUser

resType 资源cdQ分两种Q?/span> abstract/detail  抽象 / 具体

desc  描述说明

例子Q?/span>

对用L(fng)理进行数据库操作权限授权

新徏“用L(fng)理”做父节点,选择资源cd为“抽象?/span>

在“用L(fng)理”下再依ơ新增“新增用户”、“浏览用户”、“修改用户”、“删除用户”四个子节点Q选择资源cd为“具体?/span>

如果pȝ自己来判断存储就是叶子节Ҏ(gu)“具体”,其他为“抽象?/span>

web 面Q?/span>

面上显CZ|(wi)Q左侧显C用戗用L(fng)和角色树(wi)Q右侧显C数据库操作资源对象?wi),数据库操作资源对象?wi)的叶子节点的一U父节点上跟一个数据范围限?/span> button Q点d弹出H口输入限定条gQ叶子节点上跟一个复选框。点ȝ戗用L(fng)和角色树(wi)上的节点对相应权限主体进行授?/span>

授权信息存入 ACL 表中

资源 TYPE ?/span> method

3?span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">  行数据权限授权

已在上面做了说明x据范围限?/span>

4?span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">  大集中模式下的权限授?/span>

其实所谓大集中模式控制的也不过是数据范_(d)考虑是所有相兌全部增加 groupId 字段Q新增时d该字D,d时进行判?/span>

web 面Q?/span>

“组l和用户理”模块中Q每个组l中都允许设定一个管理员Q一旦设定管理员Q该l织p入大集中模式Q即所有该l织的数据与其他同l织互相隔离Q仅上l织可见。同时说明一点的是:(x)该管理员与系lȝ理员权限一P不同的是数据范围仅限制与该组l内部?/span>

lDQ?/span>

实际的授权部分采用了 ACL Q所以授权比较简单和直观

pȝ资源和数据库操作资源分开两个表存储,q样可能?x)给用户带来不便Q也是授权时还需要切换,但这U不便似乎不好解冻I因ؓ(f)一个是_粒度的一个是l粒度的?/span>

Image00001.bmp



ronghao 2006-07-06 17:47 发表评论
]]>
乱弹权限pȝl一http://www.aygfsteel.com/RongHao/archive/2006/07/03/56258.htmlronghaoronghaoMon, 03 Jul 2006 02:50:00 GMThttp://www.aygfsteel.com/RongHao/archive/2006/07/03/56258.htmlhttp://www.aygfsteel.com/RongHao/comments/56258.htmlhttp://www.aygfsteel.com/RongHao/archive/2006/07/03/56258.html#Feedback4http://www.aygfsteel.com/RongHao/comments/commentRss/56258.htmlhttp://www.aygfsteel.com/RongHao/services/trackbacks/56258.html首先是系l中需要哪些权限?br />权限应该分类四类Q ?
  一是系l方面,主要是对模块的权限划?Q具体就是可见不可见Q用戯不能对该模块q行再授权?
  二是数据库操作权限,主要是浏览、增加,修改Q删除记录,也可以理解ؓ(f)对象权限  
  三是行数据权限Q又可以叫做对象实例U权限,主要是考虑C是每个用户都可以看到所有记录的Q比如在工资理中一个部门用户就只能看到本部门h员的工资Q甚臛_能看到本部门什么职位以下的人员的工资?br />  四是列数据权限Q即数据字段的权限,不是每个用户都可以看到或是修Ҏ(gu)有的字段的?br />具体四类可能的权限划分如下:(x)
  一pȝ权限Q可?可再授权  
  二数据库操作权限Q浏?增加/修改/删除  
  三行U数据权限,数据范围
  四列U数据权限,可见/修改
然后是可能存在的权限模式Q现在考虑的是大集中模式下的权限管?br />  理解Q什么是大集中模式下的权限管理。D个例子d怸面有分公司A和分公司BQd司系l管理员分别在分公司A和分公司B中设定分公司pȝ理员,则分公司A和分公司B数据是互不可见的Q分公司pȝ理员只对各自分公司负责Q他们可以同时徏立一个相同名字的角色Q但q两个角色是不同的。即下只可以看到自己,上可以看到所有。这个管理是可以嵌套的,卛_公司A下面可能q会(x)存在分公司,分公怸面还?x)有新的分部门。。。?img src ="http://www.aygfsteel.com/RongHao/aggbug/56258.html" width = "1" height = "1" />

ronghao 2006-07-03 10:50 发表评论
]]>
也来乱弹权限pȝhttp://www.aygfsteel.com/RongHao/archive/2006/06/29/55773.htmlronghaoronghaoThu, 29 Jun 2006 08:29:00 GMThttp://www.aygfsteel.com/RongHao/archive/2006/06/29/55773.htmlhttp://www.aygfsteel.com/RongHao/comments/55773.htmlhttp://www.aygfsteel.com/RongHao/archive/2006/06/29/55773.html#Feedback1http://www.aygfsteel.com/RongHao/comments/commentRss/55773.htmlhttp://www.aygfsteel.com/RongHao/services/trackbacks/55773.html1、授权。主要是授权模型的维护,如资源、角艌Ӏ用戗部门的对应关系{?br />2、认证。主要是用户w䆾的认证,以及(qing)取出用户的权限?br />3、校验权限。当用户Ҏ(gu)一资源q行操作Ӟ用L(fng)权限与操作该资源所应有的权限进行比Ҏ(gu)验?br />在对q三个方面进行说明前Q也惌说对数据权限的看法。什么是数据权限Q很单,
考虑一U场?Qjavaeye里的例子Q?br />看看销售数?
A销售员可以看到自己的销售情况和每一W具体销售业务,但是看不到B?
B销售员可以看到自己的销售情况和每一W具体销售业务,但是看不到A?
分公叔R售经理则可以看到本部门的A和B的销售情况,但是看不到其他分公司的销售业?
集团销售Boss可以看到集团内所有分公司的销售业务数?
共同点:(x)他们都可以看到“销售数据”这一模块
不同点:(x)他们d数据的范围是不一L(fng)
q个也可以叫做实例权限控制。有U权限一般是攑֜业务里做? 如果非要用一个固定的模型实现,可以参?ACL, 不过也是要在业务里写 ACL 相关代码的。确实,以前自己也都是放在业务里做的Q但一直认也应该是权限pȝ的一部分Q通过用户的权限来构造不同的sql语句。具体通过AOP实现Q好象已l有个开源的东西q没看(lllyq?a >http://bba96.dev.java.netQ。ACL对实例权限控制感觉效率?x)有问题Q个人看法?br />具体来说Q?br />1、授?br />   具体开发里便的授权方式已经成了用户必提的要求,很明显,仅仅Zrole和权限交互是q远不够的。现实中你必L角色、用戗部门三者全部与权限挂钩。而这三者毫无疑问地׃(x)存在权限l承的问题。考虑一下,在部门A增加一个用P很显然该用户?x)扉K门A的权限;同时如果在部门A下增加一个部门角Ԍ该角色应不应该也l承部门A的权限呢Q也?dng)R要一个规则接口,具体规则实现看客户需求?br />   再说说资源,q里仅讨论系l资源不考虑数据资源。考虑一个“业务管理”的模块Q该模块下面q有“项目管理”,“物品管理”,“采购管理”三个模块,当对用户赋予了“业务管理”模块的查看权限Q用h否同时对“项目管理”,“物品管理”,“采购管理”具有查看权限呢Q这里同样存在资源权限承的问题。客L(fng)需求是不同的,所以同样需要一个资源权限承的规则接口?br />   最后说说授权信息的保存。考虑ACL。表设计Q资源IDQ权限主体IDQ权限主体TYPEQ资源操作权限。一开始考虑权限MID是UserIDQ这样会(x)在认证的时候效率很高,但考虑到部门A下有100个用P当对部门A增加一个权限时Q实际上?x)往ACL表里插入100条记录,q就让h不能接受了?br />2、认?br />   其实׃个方面,一是检查是否存在这个用P二是取出用户的权限。呵呵,q里有些l对了,取出用户的权限完全可以放到校验权限里来做Q不必这里一ơ性全d来。用L(fng)权限攑֜一个List里,对象可以构造一个,两个属性:(x)资源ID和资源操作权限。取出用L(fng)权限时候要用到上面定义的规则接口来l装用户实际的所有权限?br />2、校验权?br />   q个比较简单了Q个人們֐于在Action里完成这个工作,需要进行权限检查的Action实现一个接口,接口里有一?public boolean hasPermission() Q写个拦截器拦截卛_。这里的关键q是通过资源权限l承的规则接口来校验用户操作该资源的权限?br />完全是个Zؕ弹,Ƣ迎拍砖Q)

ronghao 2006-06-29 16:29 发表评论
]]>
վ֩ģ壺 | | ӻ| | ̨| | | | ˳| | ǭ| | | | | | Դ| | | | ͨɽ| | | ְ| ֹ| Ϋ| | ľ| Ҫ| | Ͽ| | ɽ| ̨| | Ƕ| Ϻ| | ϳ| ɽ| |