??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲妇女无套内射精,亚洲成人福利在线,亚洲视频一区二区http://m.tkk7.com/szhswl/category/28241.html宋针q的个hI间zh-cnFri, 21 Dec 2007 17:02:27 GMTFri, 21 Dec 2007 17:02:27 GMT60Z角色的权限控?RBAC)http://m.tkk7.com/szhswl/articles/169283.html宋针q?/dc:creator>宋针q?/author>Fri, 21 Dec 2007 04:54:00 GMThttp://m.tkk7.com/szhswl/articles/169283.htmlhttp://m.tkk7.com/szhswl/comments/169283.htmlhttp://m.tkk7.com/szhswl/articles/169283.html#Feedback0http://m.tkk7.com/szhswl/comments/commentRss/169283.htmlhttp://m.tkk7.com/szhswl/services/trackbacks/169283.html 

3.1 Z角色的权限控?RBAC)

    Acegi 自带?sample 表设计很? users表{username,password,enabled} authorities表{username,authority},q样单的设计无法适应复杂的权限需?故SpringSide选用RBAC模型Ҏ限控制数据库表进行扩展?nbsp;RBAC引入了ROLE的概?使User(用户)和Permission(权限)分离,一个用h有多个角?一个角色拥有有多个相应的权?从而减了权限理的复杂度,可更灉|地支持安全策略?

    同时,我们也引入了resource(资源)的概?一个资源对应多个权限,资源分ؓACL,URL,和FUNTION三种。注意,URL和FUNTION的权限命名需要以AUTH_开头才会有资格参加投票, 同样的ACL权限命名需要ACL_开头?/p>

3.2 理和用EhCache

3.2.1 讄~存

在SpringSide里的 Acegi 扩展使用 EhCache ׃ZU缓存解x?以缓存用户和资源的信息和相对应的权限信息?/span>

首先需要一个在classpath?span style="font-family: Arial"> ehcache.xml 文gQ用于配|?/span> EhCache?/span>

<ehcache>
       <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            overflowToDisk="true"
            timeToIdleSeconds="0"
            timeToLiveSeconds="0"
            diskPersistent="false"
           diskExpiryThreadIntervalSeconds= "120"/>
    <!-- acegi cache-->
    <cache name="userCache"
           maxElementsInMemory="10000"
           eternal="true"
          overflowToDisk= "true"/>
    <!-- acegi cache-->
    <cache name="resourceCache"
           maxElementsInMemory="10000"
           eternal="true"
           overflowToDisk="true"/>
</ehcache>

     maxElementsInMemory讑֮了允许在Cache中存攄数据数目Qeternal讑֮Cache是否会过期,overflowToDisk讑֮内存不的时候缓存到盘QtimeToIdleSeconds和timeToLiveSeconds讑֮~存游离旉和生存时_diskExpiryThreadIntervalSeconds讑֮~存在硬盘上的生存时_注意当eternal="true"ӞtimeToIdleSecondsQtimeToLiveSeconds和diskExpiryThreadIntervalSeconds都是无效的?/span>

<defaultCache>是除制定的Cache外其余所有Cache的设|,针对Acegi 的情? 专门讄了userCache和resourceCacheQ都设ؓ怸q期。在applicationContext-acegi-security.xml中相应的调用?/span>

<bean id="userCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
        <property name="cacheManager" ref="cacheManager"/>
        <property name="cacheName" value=" userCache"/>
    </bean>
    <bean id="userCache" class="org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache" autowire="byName">
        <property name="cache" ref="userCacheBackend"/>
    </bean>
    <bean id="resourceCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
        <property name="cacheManager" ref="cacheManager"/>
        <property name="cacheName" value=" resourceCache"/>
    </bean>
    <bean id="resourceCache" class="org.springside.modules.security.service.acegi.cache.ResourceCache" autowire="byName">
        <property name="cache" ref="resourceCacheBackend"/>
    </bean>
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>

"cacheName" 是讑֮?span lang="EN-US">ehcache.xml 中相应Cache的名U?/span>

userCache使用的是Acegi 的EhCacheBasedUserCache(实现了UserCache接口), resourceCache是SpringSide的扩展类

public interface UserCache   {
    public UserDetails getUserFromCache (String username);

    public void putUserInCache (UserDetails user);

    public void removeUserFromCache (String username);
}
public class ResourceCache   {
    public ResourceDetails getAuthorityFromCache (String resString) {...   }
    public void putAuthorityInCache (ResourceDetails resourceDetails) {...  }
 
   public void removeAuthorityFromCache (String resString) {... }
    public List getUrlResStrings() {... }
    public List getFunctions() {.. }
}

UserCache 是通过EhCache对UserDetails q行~存理, 而ResourceCache 是对ResourceDetails c进行缓存管?/span>

public interface UserDetails   extends Serializable {
    public boolean isAccountNonExpired();
    public boolean isAccountNonLocked();

    public GrantedAuthority[] getAuthorities();

    public boolean isCredentialsNonExpired();

    public boolean isEnabled();

    public String getPassword();

    public String getUsername();
}
public interface ResourceDetails   extends Serializable {
    public String getResString();

    public String getResType();

    public GrantedAuthority[] getAuthorities();
}

UserDetails 包含用户信息和相应的权限QResourceDetails 包含资源信息和相应的权限?/span>

public interface GrantedAuthority     {
    public String getAuthority ();
}

     GrantedAuthority 是权限信息Q在Acegi ?sample ?span lang="EN-US" style="font-family: Arial">GrantedAuthority 的信息如ROLE_USER, ROLE_SUPERVISOR, ACL_CONTACT_DELETE, ACL_CONTACT_ADMIN{等Q网上也有很多例子把角色作ؓGrantedAuthority Q但事实上看看ACL q道, Acegi本nҎ没有角色这个概念,GrantedAuthority 包含的信息应该是权限Q对于非ACL的权限用 AUTH_ 开头更为合? 如SpringSide里的 AUTH_ADMIN_LOGIN, AUTH_BOOK_MANAGE {等?/span>

3.2.2 理~存

     使用AcegiCacheManager?span lang="EN-US" style="font-family: Arial">userCache和resourceCacheq行l一~存理?font face="Tahoma">当在后台对用户信息进行修Ҏ赋权的时? 在更新数据库同时׃调用acegiCacheManager相应Ҏ, 从数据库中读取数据ƈ替换cache中相应部?使cache与数据库同步?/font>

public class AcegiCacheManager extends BaseService {
    private ResourceCache resourceCache ;
    private UserCache userCache ;
    /**
     * 修改User时更改userCache
     */

    public void modifyUserInCache (User user, String orgUsername) {...    }
    /**
     * 修改Resource时更改resourceCache
     */

    public void modifyResourceInCache (Resource resource, String orgResourcename) {...    }
    /**
     * 修改权限时同时修改userCache和resourceCache
     */

    public void modifyPermiInCache (Permission permi, String orgPerminame) {...  }
    /**
     * User授予角色时更改userCache
     */
    public void authRoleInCache (User user) {...    }
    /**
     * Role授予权限时更改userCache和resourceCache
     */

    public void authPermissionInCache (Role role) {...  }
    /**
     * Permissioni授予资源时更改resourceCache
     */

    public void authResourceInCache (Permission permi) {...  }
    /**
     * 初始化userCache
     */

    public void initUserCache () {...  }
    /**
     * 初始化resourceCache
     */

    public void initResourceCache () {... }
    /**
     * 获取所有的url资源
     */

    public List getUrlResStrings () {...  }
    /**
     * 获取所有的Funtion资源
     */

    public List getFunctions () {...  }
    /**
     * Ҏ资源串获取资?
     */

    public ResourceDetails getAuthorityFromCache (String resString) {...  }
  
 ......


}

 

3.3 资源权限定义扩展

     Acegil出的sample?资源权限对照关系是配|在xml中的,试想一下如果你的企业安全应用有500个用?100个角色权限的时?l护q个xml是个繁重无比的工作,如何动态更改用h限更是个头痛的问题?/p>

   <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.create=ROLE_USER
            sample.contact.ContactManager.getAllRecipients=ROLE_USER
            sample.contact.ContactManager.getAll=ROLE_USER,AFTER_ACL_COLLECTION_READ
            sample.contact.ContactManager.getById=ROLE_USER,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>
  <bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
      <property name="authenticationManager"><ref bean="authenticationManager"/></property>
      <property name="accessDecisionManager"><ref local="httpRequestAccessDecisionManager"/></property>
      <property name="objectDefinitionSource">
         <value>
       CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
       PATTERN_TYPE_APACHE_ANT
       /index.jsp=ROLE_ANONYMOUS,ROLE_USER
       /hello.htm=ROLE_ANONYMOUS,ROLE_USER
       /logoff.jsp=ROLE_ANONYMOUS,ROLE_USER
       /switchuser.jsp=ROLE_SUPERVISOR
       /j_acegi_switch_user=ROLE_SUPERVISOR
       /acegilogin.jsp*=ROLE_ANONYMOUS,ROLE_USER
     /**=ROLE_USER
         </value>
      </property>
   </bean>

 对如此不Pragmatic的做?SpringSideq行了扩? 让Acegi 能动态读取数据库中的权限资源关系?/p>

3.3.1 Aop Invocation Authorization

    <bean id="methodSecurityInterceptor" class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="accessDecisionManager" ref="httpRequestAccessDecisionManager"/>
        <property name="objectDefinitionSource" ref="methodDefinitionSource"/>
    </bean>
    <bean id="methodDefinitionSource" class="org.springside.security.service.acegi.DBMethodDefinitionSource">
        <property name="acegiCacheManager" ref="acegiCacheManager"/>
    </bean>

     研究下Aceig的源?ObjectDefinitionSource的实际作用是q回一?strong>ConfigAttributeDefinition对象Q而Acegi Sample 的方式是?strong>MethodDefinitionSourceEditor把xml中的文本Function资源权限对应关系信息加蝲?strong>MethodDefinitionMap ( MethodDefinitionSource 的实现类 )? 再组成ConfigAttributeDefinitionQ而我们的扩展目标是从~存中读取信息来l成ConfigAttributeDefinition?/p>

     MethodSecurityInterceptor是通过调用AbstractMethodDefinitionSource?strong>lookupAttributes(method)Ҏ获取ConfigAttributeDefinition。所以我们需要实现自qObjectDefinitionSourceQ?/font>l承AbstractMethodDefinitionSourceq实现其lookupAttributesҎ,从缓存中d资源权限对应关系l成q返回ConfigAttributeDefinition卛_。SpringSide中的DBMethodDefinitionSourcecȝ部分实现如下 :

public class DBMethodDefinitionSource extends AbstractMethodDefinitionSource {
......
    protected ConfigAttributeDefinition lookupAttributes(Method mi) {
        Assert.notNull(mi, "lookupAttrubutes in the DBMethodDefinitionSource is null");
        String methodString = mi.getDeclaringClass().getName() + "." + mi.getName();
        if (!acegiCacheManager.isCacheInitialized()) {
            //初始化Cache
            acegiCacheManager.initResourceCache();
        }
        //获取所有的function
        List methodStrings = acegiCacheManager.getFunctions();
        Set auths = new HashSet();
        //取权限的合集
        for (Iterator iter = methodStrings.iterator(); iter.hasNext();) {
            String mappedName = (String) iter.next();
            if (methodString.equals(mappedName)
                    || isMatch(methodString, mappedName)) {
                ResourceDetails resourceDetails = acegiCacheManager.getAuthorityFromCache(mappedName);
                if (resourceDetails == null) {
                    break;
                }
                GrantedAuthority[] authorities = resourceDetails.getAuthorities();
                if (authorities == null || authorities.length == 0) {
                    break;
                }
                auths.addAll(Arrays.asList(authorities));
            }
        }
        if (auths.size() == 0)
            return null;
        ConfigAttributeEditor configAttrEditor = new ConfigAttributeEditor();
        String authoritiesStr = " ";
        for (Iterator iter = auths.iterator(); iter.hasNext();) {
            GrantedAuthority authority = (GrantedAuthority) iter.next();
            authoritiesStr += authority.getAuthority() + ",";
        }
        String authStr = authoritiesStr.substring(0, authoritiesStr.length() - 1);
        configAttrEditor.setAsText(authStr);
       //l装q返回ConfigAttributeDefinition
        return (ConfigAttributeDefinition) configAttrEditor.getValue();
    }
    ......
}

要注意几点的?
1) 初始化Cache是比较浪费资源的Q所以SpringSide中除W一ơ访问外的Cache的更新是针对性更新?/p>

2) 因ؓmethod采用了匹配方?详见 isMatch() Ҏ) , 卛_?Book和save*q两个资源来_只要当前讉KҎ是Bookl尾或以save开头都匹配得上,所以应该取q些能匹配上的资源的相对应的权限的合集?/p>

3) 使用ConfigAttributeEditor 能更方便地组装ConfigAttributeDefinition?

3.3.2 Filter Invocation Authorization

    <bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="accessDecisionManager" ref="httpRequestAccessDecisionManager"/>
        <property name="objectDefinitionSource" ref="filterDefinitionSource"/>
    </bean>

    <bean id="filterDefinitionSource" class="org.springside.security.service.acegi.DBFilterInvocationDefinitionSource">
        <property name="convertUrlToLowercaseBeforeComparison" value="true"/>
        <property name="useAntPath" value="true"/>
        <property name="acegiCacheManager" ref="acegiCacheManager"/>
    </bean>

     PathBasedFilterInvocationDefinitionMap和RegExpBasedFilterInvocationDefinitionMap都是 FilterInvocationDefinitionSource的实现类,当PATTERN_TYPE_APACHE_ANT字符串匹配上时时,FilterInvocationDefinitionSourceEditor 选用PathBasedFilterInvocationDefinitionMap 把xml中的文本URL资源权限对应关系信息加蝲?/p>

     FilterSecurityInterceptor通过FilterInvocationDefinitionSource?strong>lookupAttributes(url)Ҏ获取ConfigAttributeDefinition?所以,我们可以通过l承FilterInvocationDefinitionSource的抽象类AbstractFilterInvocationDefinitionSourceQƈ实现其lookupAttributesҎ,从缓存中dURL资源权限对应关系卛_。SpringSide?strong>DBFilterInvocationDefinitionSourcec部分实现如?

public class DBFilterInvocationDefinitionSource extends AbstractFilterInvocationDefinitionSource {

......
    public ConfigAttributeDefinition lookupAttributes(String url) {
        if (!acegiCacheManager.isCacheInitialized()) {
            acegiCacheManager.initResourceCache();
        }

        if (isUseAntPath()) {
            // Strip anything after a question mark symbol, as per SEC-161.
            int firstQuestionMarkIndex = url.lastIndexOf("?");
            if (firstQuestionMarkIndex != -1) {
                url = url.substring(0, firstQuestionMarkIndex);
            }
        }
        List urls = acegiCacheManager.getUrlResStrings();
        //URL资源倒叙排序
        Collections.sort(urls);
        Collections.reverse(urls);
//是否先全部{为小写再比较
        if (convertUrlToLowercaseBeforeComparison) {
            url = url.toLowerCase();
        }
        GrantedAuthority[] authorities = new GrantedAuthority[0];
        for (Iterator iterator = urls.iterator(); iterator.hasNext();) {
            String resString = (String) iterator.next();
            boolean matched = false;
//可选择使用AntPath和Perl5两种不同匚w模式
            if (isUseAntPath()) {
                matched = pathMatcher.match(resString, url);
            } else {
                Pattern compiledPattern;
                Perl5Compiler compiler = new Perl5Compiler();
                try {
                    compiledPattern = compiler.compile(resString,
                            Perl5Compiler.READ_ONLY_MASK);
                } catch (MalformedPatternException mpe) {
                    throw new IllegalArgumentException(
                            "Malformed regular expression: " + resString);
                }
                matched = matcher.matches(url, compiledPattern);
            }
            if (matched) {
                ResourceDetails rd = acegiCacheManager.getAuthorityFromCache(resString);
                authorities = rd.getAuthorities();
                break;
            }
        }
        if (authorities.length > 0) {
            String authoritiesStr = " ";
            for (int i = 0; i < authorities.length; i++) {
                authoritiesStr += authorities[i].getAuthority() + ",";
            }
            String authStr = authoritiesStr.substring(0, authoritiesStr
                    .length() - 1);
            ConfigAttributeEditor configAttrEditor = new ConfigAttributeEditor();
            configAttrEditor.setAsText(authStr);
            return (ConfigAttributeDefinition) configAttrEditor.getValue();
        }
        return null;
    }

......
 }

l承AbstractFilterInvocationDefinitionSource注意几点Q?br /> 1)  需要先把获取回来的URL资源按倒序zֺQ以辑ֈ a/b/c/d.* ?a/.* 之前的效?详见 Acegi sample 的applicationContext-acegi-security.xml 中的filterInvocationInterceptor的注?Qؓ的是更具体的URL可以先匹配上Q而获取具体URL的权限,如a/b/c/d.*权限AUTH_a, AUTH_b 才可查看,  a/.* 需要权限AUTH_a 才可查看Q则如果当前用户只拥有权限AUTH_b,则他只可以查看a/b/c/d.jsp 而不能察看a/d.jsp?/p>

2) Z上面的原因,故第一ơ匹配上的就是当前所需权限Q而不是取权限的合集?/p>

3) 可以选用AntPath ?Perl5 的资源匹配方式,感觉AntPath匚w方式基本_?/p>

4) Filter 权限控制比较适合于较_颗_度的权限,如设定某个模块下的页面是否能讉K{,对于具体某个操作如增删修改,是否能执行,用Method  Invocation 会更佳些Q所以注意两个方面一h制效果更?/p>

 

3.4 授权操作

     RBAC模型中有不少多对多的关系Q这些关p都能以一个中间表的Ş式来存放Q而Hibernate中可以不中间表对应的hbm.xml , 以资源与权限的配|ؓ例,如下:

<hibernate-mapping package="org.springside.modules.security.domain">
    <class name="Permission" table="PERMISSIONS" dynamic-insert="true" dynamic-update="true">
        <cache usage="nonstrict-read-write"/>
        <id name="id" column="ID">
            <generator class="native"/>
        </id>
        <property name="name" column="NAME" not-null="true"/>
        <property name="descn" column="DESCN"/>
        <property name="operation" column="OPERATION"/>
        <property name="status" column="STATUS"/>
        <set name="roles" table="ROLE_PERMIS" lazy="true" inverse="true" cascade="save-update" batch-size="5">
            <key>
                <column name="PERMIS_ID" not-null="true"/>
            </key>
            <many-to-many class="Role" column="ROLE_ID" outer-join="auto"/>
        </set>
        <set name="resources" table="PERMIS_RESC" lazy="true" inverse="false" cascade="save-update" batch-size="5">
            <key>
                <column name="PERMIS_ID" not-null="true"/>
            </key>
            <many-to-many class="Resource" column="RESC_ID"/>
        </set>
    </class>
</hibernate-mapping>
<hibernate-mapping package="org.springside.modules.security.domain">
    <class name="Resource" table="RESOURCES" dynamic-insert="true" dynamic-update="true">
        <cache usage="nonstrict-read-write"/>
        <id name="id" column="ID">
            <generator class="native"/>
        </id>
        <property name="name" column="NAME" not-null="true"/>
        <property name="resType" column="RES_TYPE" not-null="true"/>
        <property name="resString" column="RES_STRING" not-null="true"/>
        <property name="descn" column="DESCN"/>
        <set name="permissions" table="PERMIS_RESC" lazy="true" inverse="true" cascade="save-update" batch-size="5">
            <key>
                <column name="RESC_ID" not-null="true"/>
            </key>
            <many-to-many class="Permission" column="PERMIS_ID" outer-join="auto"/>
        </set>
    </class>
</hibernate-mapping>

配置时注意几?

1) 因ؓ是分配某个权限的资源Q所以权限是L方,把inverse设ؓfalseQ资源是被控方inverse设ؓtrue

2) cascade?save-update"Q千万别配成delete

3) 只需?permission.getResources().add(resource)Q?permission.getResources()..remove(resource) 卛_很方便地完成授权和取消授权操?/p>

]]>
Acegi安全pȝ的配|?/title><link>http://m.tkk7.com/szhswl/articles/169244.html</link><dc:creator>宋针q?/dc:creator><author>宋针q?/author><pubDate>Fri, 21 Dec 2007 02:58:00 GMT</pubDate><guid>http://m.tkk7.com/szhswl/articles/169244.html</guid><wfw:comment>http://m.tkk7.com/szhswl/comments/169244.html</wfw:comment><comments>http://m.tkk7.com/szhswl/articles/169244.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/szhswl/comments/commentRss/169244.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/szhswl/services/trackbacks/169244.html</trackback:ping><description><![CDATA[Acegi 的配|看h非常复杂,但事实上在实际项目的安全应用中我们ƈ不需要那么多功能,清楚的了解Acegi配置中各的功能Q有助于我们灉|的运用Acegi于实践中? <h2>2.1 在Web.xml中的配置</h2> <p>1)  <strong>FilterToBeanProxy</strong><br />   Acegi通过实现了Filter接口的FilterToBeanProxy提供一U特D的使用Servlet Filter的方式,它委托Spring中的Bean -- FilterChainProxy来完成过滤功能,q好处是化了web.xml的配|,q且充分利用了Spring IOC的优ѝFilterChainProxy包含了处理认证过E的filter列表Q每个filter都有各自的功能?/p> <pre>    <filter><br />         <filter-name>Acegi Filter Chain Proxy</filter-name><br />         <filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class><br />         <init-param><br />             <param-name>targetClass</param-name><br />             <param-value>org.acegisecurity.util.FilterChainProxy</param-value><br />         </init-param><br />     </filter></pre> <p>2) <strong>filter-mapping</strong><br />   <filter-mapping>限定了FilterToBeanProxy的URL匚w模式,只有*.do?.jsp?j_acegi_security_check 的请求才会受到权限控Ӟ对javascript,css{不限制?/p> <pre>   <filter-mapping><br />       <filter-name>Acegi Filter Chain Proxy</filter-name><br />       <url-pattern>*.do</url-pattern><br />     </filter-mapping><br />     <br />     <filter-mapping><br />       <filter-name>Acegi Filter Chain Proxy</filter-name><br />       <url-pattern>*.jsp</url-pattern><br />     </filter-mapping><br />     <br />     <filter-mapping><br />       <filter-name>Acegi Filter Chain Proxy</filter-name><br />       <url-pattern>/j_acegi_security_check</url-pattern><br /> </filter-mapping></pre> <p>3) <strong>HttpSessionEventPublisher</strong><br />   <listener>的HttpSessionEventPublisher用于发布HttpSessionApplicationEvents和HttpSessionDestroyedEvent事glspring的applicationcontext?/p> <pre>    <listener><br />         <listener-class>org.acegisecurity.ui.session.HttpSessionEventPublisher</listener-class><br />     </listener><br /> </pre> <h2><br /> 2.2 在applicationContext-acegi-security.xml?/h2> <h3>2.2.1 FILTER CHAIN</h3> <p>  FilterChainProxy会按序来调用这些filter,使这些filter能n用Spring ioc的功? CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON定义了url比较前先转ؓ写Q?PATTERN_TYPE_APACHE_ANT定义了用Apache ant的匹配模?</p> <pre> <bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy"><br />         <property name="filterInvocationDefinitionSource"><br />             <value><br />                 CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON<br />                 PATTERN_TYPE_APACHE_ANT<br />                /**=httpSessionContextIntegrationFilter,authenticationProcessingFilter,<br /> basicProcessingFilter,rememberMeProcessingFilter,anonymousProcessingFilter,<br /> exceptionTranslationFilter,filterInvocationInterceptor<br />             </value><br />         </property><br />     </bean></pre> <h3>2.2.2 基础认证</h3> <p>1) <strong>authenticationManager</strong><br />   起到认证理的作用,它将验证的功能委托给多个ProviderQƈ通过遍历Providers, 以保证获取不同来源的w䆾认证Q若某个Provider能成功确认当前用Lw䆾Qauthenticate()Ҏ会返回一个完整的包含用户授权信息的Authentication对象Q否则会抛出一个AuthenticationException?br /> Acegi提供了不同的AuthenticationProvider的实?如:<br />         DaoAuthenticationProvider 从数据库中读取用户信息验证n?br />         AnonymousAuthenticationProvider 匿名用户w䆾认证<br />         RememberMeAuthenticationProvider 已存cookie中的用户信息w䆾认证<br />         AuthByAdapterProvider 使用容器的适配器验证n?br />         CasAuthenticationProvider ҎYale中心认证服务验证w䆾, 用于实现单点登陆<br />         JaasAuthenticationProvider 从JASS登陆配置中获取用户信息验证n?br />         RemoteAuthenticationProvider Ҏq程服务验证用户w䆾<br />         RunAsImplAuthenticationProvider 对n份已被管理器替换的用戯行验?br />         X509AuthenticationProvider 从X509认证中获取用户信息验证n?br />         TestingAuthenticationProvider 单元试时?/p> <p>        每个认证者会对自己指定的证明信息q行认证Q如DaoAuthenticationProvider仅对UsernamePasswordAuthenticationTokenq个证明信息q行认证?/p> <pre><bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager"><br />         <property name="providers"><br />             <list><br />                 <ref local="daoAuthenticationProvider"/><br />                 <ref local="anonymousAuthenticationProvider"/><br />                 <ref local="rememberMeAuthenticationProvider"/><br />             </list><br />         </property><br /> </bean></pre> <p><br /> 2) <strong>daoAuthenticationProvider</strong><br />   q行单的Z数据库的w䆾验证。DaoAuthenticationProvider获取数据库中的̎号密码ƈq行匚wQ若成功则在通过用户w䆾的同时返回一个包含授权信息的Authentication对象Q否则n份验证失败,抛出一个AuthenticatiionException?/p> <pre>    <bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider"><br />         <property name="userDetailsService" ref="jdbcDaoImpl"/><br />         <property name="userCache" ref="userCache"/><br />         <property name="passwordEncoder" ref="passwordEncoder"/><br />    </bean></pre> <p><br /> 3) <strong>passwordEncoder</strong> <br />   使用加密器对用户输入的明文进行加密。Acegi提供了三U加密器:<br /> PlaintextPasswordEncoder—默认,不加密,q回明文.<br /> ShaPasswordEncoder—哈希算?SHA)加密<br /> Md5PasswordEncoder—消息摘?MD5)加密</p> <pre><bean id="passwordEncoder" class="org.acegisecurity.providers.encoding.Md5PasswordEncoder"/></pre> <p><br /> 4) <strong>jdbcDaoImpl</strong> <br />   用于在数据中获取用户信息?acegi提供了用户及授权的表l构Q但是您也可以自己来实现。通过usersByUsernameQueryq个SQL得到你的(用户ID,密码,状态信?;通过authoritiesByUsernameQueryq个SQL得到你的(用户ID,授权信息)</p> <pre> <bean id="jdbcDaoImpl" class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl"><br />         <property name="dataSource" ref="dataSource"/><br />         <property name="usersByUsernameQuery"><br />             <value>select loginid,passwd,1 from users where loginid = ?</value><br />         </property><br />         <property name="authoritiesByUsernameQuery"><br />             <value>select u.loginid,p.name from users u,roles r,permissions p,user_role ur,role_permis rp where u.id=ur.user_id and r.id=ur.role_id and p.id=rp.permis_id and<br />                 r.id=rp.role_id and p.status='1' and u.loginid=?</value><br />         </property><br /> </bean></pre> <p>5) <strong>userCache &  resourceCache</strong> <br />   ~存用户和资源相对应的权限信息。每当请求一个受保护资源ӞdaoAuthenticationProvider׃被调用以获取用户授权信息。如果每ơ都从数据库获取的话Q那代h很高Q对于不常改变的用户和资源信息来_最好是把相x权信息缓存v来?详见 <a >2.6.3 资源权限定义扩展</a> )<br /> userCache提供了两U实? NullUserCache和EhCacheBasedUserCache, NullUserCache实际上就是不q行M~存QEhCacheBasedUserCache是用Ehcache来实现缓功能?/p> <pre>    <bean id="userCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean"><br />         <property name="cacheManager" ref="cacheManager"/><br />         <property name="cacheName" value="userCache"/><br />     </bean><br />     <bean id="userCache" class="org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache" autowire="byName"><br />         <property name="cache" ref="userCacheBackend"/><br />     </bean><br />     <bean id="resourceCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean"><br />         <property name="cacheManager" ref="cacheManager"/><br />         <property name="cacheName" value="resourceCache"/><br />     </bean><br />     <bean id="resourceCache" class="org.springside.modules.security.service.acegi.cache.ResourceCache" autowire="byName"><br />         <property name="cache" ref="resourceCacheBackend"/><br />     </bean></pre> <p><br /> 6) <strong>basicProcessingFilter</strong> <br />   用于处理HTTP头的认证信息Q如从Springq程协议(如Hessian和Burlap)或普通的览器如IE,Navigator的HTTP头中获取用户信息Q将他们转交l通过authenticationManager属性装配的认证理器。如果认证成功,会将一个Authentication对象攑ֈ会话中,否则Q如果认证失败,会将控制转交l认证入口点(通过authenticationEntryPoint属性装?</p> <pre>    <bean id="basicProcessingFilter" class="org.acegisecurity.ui.basicauth.BasicProcessingFilter"><br />         <property name="authenticationManager" ref="authenticationManager"/><br />         <property name="authenticationEntryPoint" ref="basicProcessingFilterEntryPoint"/><br />     </bean></pre> <p>7) <strong>basicProcessingFilterEntryPoint</strong> <br />   通过向浏览器发送一个HTTP401(未授?消息Q提C用L录?br /> 处理ZHTTP的授权过E, 在当验证q程出现异常后的"d"Q通常实现转向、在response里加入error信息{功能?/p> <pre> <bean id="basicProcessingFilterEntryPoint" class="org.acegisecurity.ui.basicauth.BasicProcessingFilterEntryPoint"><br />         <property name="realmName" value="SpringSide Realm"/><br /> </bean></pre> <p>8) <strong>authenticationProcessingFilterEntryPoint</strong> <br />   当抛出AccessDeniedExceptionӞ用户重定向到登录界面。属性loginFormUrl配置了一个登录表单的URL,当需要用L录时QauthenticationProcessingFilterEntryPoint会将用户重定向到该URL</p> <pre> <bean id="authenticationProcessingFilterEntryPoint" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint"><br />         <property name="loginFormUrl"><br />             <value>/security/login.jsp</value><br />         </property><br />         <property name="forceHttps" value="false"/><br /> </bean></pre> <h2>2.2.3 HTTP安全h</h2> <p>1) <strong>httpSessionContextIntegrationFilter</strong><br />   每次request?HttpSessionContextIntegrationFilter从Session中获取Authentication对象Q在request完后, 又把Authentication对象保存到Session中供下次request使用,此filter必须其他Acegi filter前用,使之能跨多个请求?/p> <pre><bean id="httpSessionContextIntegrationFilter" class="org.acegisecurity.context.HttpSessionContextIntegrationFilter"></bean><br />     <bean id="httpRequestAccessDecisionManager" class="org.acegisecurity.vote.AffirmativeBased"><br />         <property name="allowIfAllAbstainDecisions" value="false"/><br />         <property name="decisionVoters"><br />             <list><br />                 <ref bean="roleVoter"/><br />             </list><br />         </property><br /> </bean></pre> <p><br /> 2) <strong>httpRequestAccessDecisionManager</strong><br />   l过投票机制来决定是否可以访问某一资源(URL或方?。allowIfAllAbstainDecisions为false时如果有一个或以上的decisionVoters投票通过,则授权通过。可选的决策机制有ConsensusBased和UnanimousBased</p> <pre>    <bean id="httpRequestAccessDecisionManager" class="org.acegisecurity.vote.AffirmativeBased"><br />         <property name="allowIfAllAbstainDecisions" value="false"/><br />         <property name="decisionVoters"><br />             <list><br />                 <ref bean="roleVoter"/><br />             </list><br />         </property><br />     </bean></pre> <p><br /> 3) <strong>roleVoter</strong><br />    必须是以rolePrefix讑֮的value开头的权限才能q行投票,如AUTH_ , ROLE_</p> <pre>    <bean id="roleVoter" class="org.acegisecurity.vote.RoleVoter"><br />         <property name="rolePrefix" value="AUTH_"/><br />    </bean></pre> <p>4Q?strong>exceptionTranslationFilter</strong><br />   异常转换qo器,主要是处理AccessDeniedException和AuthenticationExceptionQ将l每个异常找到合适的"d" </p> <pre>   <bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter"><br />         <property name="authenticationEntryPoint" ref="authenticationProcessingFilterEntryPoint"/><br />     </bean></pre> <p>5) <strong>authenticationProcessingFilter</strong><br />   和servlet spec差不?处理登陆h.当n份验证成功时QAuthenticationProcessingFilter会在会话中放|一个Authentication对象Qƈ且重定向到登录成功页?br />          authenticationFailureUrl定义登陆p|时{向的面<br />          defaultTargetUrl定义登陆成功时{向的面<br />          filterProcessesUrl定义登陆h的页?br />          rememberMeServices用于在验证成功后dcookie信息</p> <pre>    <bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter"><br />         <property name="authenticationManager" ref="authenticationManager"/><br />         <property name="authenticationFailureUrl"><br />             <value>/security/login.jsp?login_error=1</value><br />         </property><br />         <property name="defaultTargetUrl"><br />             <value>/admin/index.jsp</value><br />         </property><br />         <property name="filterProcessesUrl"><br />             <value>/j_acegi_security_check</value><br />         </property><br />         <property name="rememberMeServices" ref="rememberMeServices"/><br />     </bean></pre> <p>6) <strong>filterInvocationInterceptor</strong><br />   在执行{向url前检查objectDefinitionSource中设定的用户权限信息。首先,objectDefinitionSource中定义了讉KURL需要的属性信?q里的属性信息仅仅是标志Q告诉accessDecisionManager要用哪些voter来投?。然后,authenticationManager掉用自己的provider来对用户的认证信息进行校验。最后,有投者根据用h有认证和讉Kurl需要的属性,调用自己的voter来投,军_是否允许讉K?/p> <pre>    <bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor"><br />         <property name="authenticationManager" ref="authenticationManager"/><br />         <property name="accessDecisionManager" ref="httpRequestAccessDecisionManager"/><br />         <property name="objectDefinitionSource" ref="filterDefinitionSource"/><br />     </bean></pre> <p><br /> 7) <strong>filterDefinitionSource </strong>(详见 <a >2.6.3 资源权限定义扩展</a>)<br />   自定义DBFilterInvocationDefinitionSource从数据库和cache中读取保护资源及光要的讉K权限信息 </p> <pre><bean id="filterDefinitionSource" class="org.springside.modules.security.service.acegi.DBFilterInvocationDefinitionSource"><br />         <property name="convertUrlToLowercaseBeforeComparison" value="true"/><br />         <property name="useAntPath" value="true"/><br />         <property name="acegiCacheManager" ref="acegiCacheManager"/><br /> </bean></pre> <h2>2.2.4 Ҏ调用安全控制</h2> <p>(详见 <a >2.6.3 资源权限定义扩展</a>)</p> <p>1) methodSecurityInterceptor<br />   在执行方法前q行拦截Q检查用h限信?br /> 2) methodDefinitionSource<br />   自定义MethodDefinitionSource从cache中读取权?/p> <pre>   <bean id="methodSecurityInterceptor" class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor"><br />         <property name="authenticationManager" ref="authenticationManager"/><br />         <property name="accessDecisionManager" ref="httpRequestAccessDecisionManager"/><br />         <property name="objectDefinitionSource" ref="methodDefinitionSource"/><br />     </bean><br />     <bean id="methodDefinitionSource" class="org.springside.modules.security.service.acegi.DBMethodDefinitionSource"><br />         <property name="acegiCacheManager" ref="acegiCacheManager"/><br />     </bean></pre> <img src ="http://m.tkk7.com/szhswl/aggbug/169244.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/szhswl/" target="_blank">宋针q?/a> 2007-12-21 10:58 <a href="http://m.tkk7.com/szhswl/articles/169244.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Acegi?/title><link>http://m.tkk7.com/szhswl/articles/169237.html</link><dc:creator>宋针q?/dc:creator><author>宋针q?/author><pubDate>Fri, 21 Dec 2007 02:25:00 GMT</pubDate><guid>http://m.tkk7.com/szhswl/articles/169237.html</guid><wfw:comment>http://m.tkk7.com/szhswl/comments/169237.html</wfw:comment><comments>http://m.tkk7.com/szhswl/articles/169237.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/szhswl/comments/commentRss/169237.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/szhswl/services/trackbacks/169237.html</trackback:ping><description><![CDATA[<table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td><a>    Acegi安全pȝQ是一个用于Spring Framework的安全框Ӟ能够和目前流行的Web容器无缝集成。它使用了Spring的方式提供了安全和认证安全服务,包括使用Bean ContextQ拦截器和面向接口的~程方式。因此,Acegi安全pȝ能够L地适用于复杂的安全需求?br />     Acegi安全pȝQ是一个用于Spring Framework的安全框Ӟ能够和目前流行的Web容器无缝集成。它使用了Spring的方式提供了安全和认证安全服务,包括使用Bean ContextQ拦截器和面向接口的~程方式。因此,Acegi安全pȝ能够L地适用于复杂的安全需求?br />     安全涉及C个不同的概念Q认证和授权。前者是关于认用户是否实是他们所宣称的n份。授权则是关于确认用h否有允许执行一个特定的操作?br />     在Acegi安全pȝ中,需要被认证的用Ppȝ或代理称?Principal"。Acegi安全pȝ和其他的安全pȝ不同Q它q没有角色和用户l的概念?br /> Acegipȝ设计<br /> 关键lg<br />     Acegi安全pȝ包含以下七个关键的功能组Ӟ<br />     1 Authentication对象Q包含了PrincipalQCredential和Principal的授权信息。同时还可以包含关于发v认证h的客L其他信息Q如IP地址?br />     2 ContextHolder对象Q用ThreadLocal储存Authentication对象的地斏V?br />     3 AuthenticationManagerQ用于认证ContextHolder中的Authentication对象?br />     4 AccessDecissionManagerQ用于授权一个特定的操作?br />     5 RunAsManagerQ当执行特定的操作时Q用于选择性地替换Authentication对象?br />     6 Secure Object拦截器,用于协调AuthenticationManagerQAccessDecissionManagerQRunAsManager和特定操作的执行?br />     7 ObjectDefinitionSourceQ包含了特定操作的授权定义?br />     q七个关键的功能lg的关pd下图所C(图中灰色部分是关键组ӞQ?br /> <br /> <strong>安全理对象</strong><br />     Acegi安全pȝ目前支持两类安全理对象?br />     W一cȝ安全理对象理AOP Alliance的MethodInvocationQ开发h员可以用它来保护Spring容器中的业务对象。ؓ了Spring理的Bean可以作ؓ MethodInvocation来用,Bean可以通过ProxyFactoryBean和BeanNameAutoProxyCreator来管理,像在Spring的事务管理一样用?br />     W二cLFilterInvocation。它用过滤器QFilterQ来创徏Qƈ单地包装了HTTP的ServletRequestQ?ServletResponse和FilterChain。FilterInvocation可以用来保护HTTP资源。通常Q开发h员ƈ不需要了解它的工作机Ӟ因ؓ他们只需要将Filter加入web.xmlQAcegi安全pȝ可以工作了?br /> <br /> <strong>安全配置参数</strong><br />     每个安全理对象都可以描q数量不限的各种安全认证h。例如,MethodInvocation对象可以描述带有L参数的Q意方法的调用Q而FilterInvocation可以描述L的HTTP URL?br />     Acegi安全pȝ需要记录应用于每个认证h的安全配|参数。例如,对于BankManager.getBalanceQint accountNumberQ方法和BankManager.approveLoanQint applicationNumberQ方法,它们需要的认证h的安全配|很不相同?br />     Z保存不同的认证请求的安全配置Q需要用配|参数。从实现的视角来看,配置参数使用ConfigAttribute接口来表C。Acegi安全pȝ提供了ConfigAttribute接口的一个实玎ͼSecurityConfigQ它把配|参C存ؓ一个字W串?br />     ConfigAttributeDefinitioncLConfigAttribute对象的一个简单的容器Q它保存了和特定h相关的ConfigAttribute的集合?br />     当安全拦截器收到一个安全认证请求时Q需要决定应用哪一个配|参数。换句话_它需要找出应用于q个h?ConfigAttributeDefinition对象。这个查扄q程是由ObjectDefinitionSource接口来处理的。这个接口的主要Ҏ是public ConfigAttributeDefinition getAttributes(Object object)Q其中Object参数是一个安全管理对象。因为安全管理对象包含有认证h的详l信息,所?ObjectDefinitionSource接口的实现类可以从中获得所需的详l信息,以查扄关的ConfigAttributeDefiniton 对象?br /> <br /> <br /> <strong>Acegi如何工作</strong><br />     Z说明Acegi安全pȝ如何工作Q我们设想一个用Acegi的例子。通常Q一个安全系l需要发挥作用,它必d成以下的工作Q?br />     1 首先Q系l从客户端请求中获得Principal和CredentialQ?br />     2 然后pȝ认证Principal和Credential信息Q?br />     3 如果认证通过Q系l取出Principal的授权信息;<br />     4 接下来,客户端发h作请求;<br />     5 pȝҎ预先配置的参数检查Principal对于该操作的授权Q?br />     6 如果授权查通过则执行操作,否则拒绝?br />     那么QAcegi安全pȝ是如何完成这些工作的呢?首先Q我们来看看Acegi安全pȝ的认证和授权的相关类Q?<br />     安全拦截器的抽象基类Q它包含有两个管理类QAuthenticationManager和AccessDecisionManager?AuthenticationManager用于认证ContextHolder中的Authentication对象Q包含了PrincipalQ?Credential和Principal的授权信息)QAccessDecissionManager则用于授权一个特定的操作?br /> <br />     下面来看一个MethodSecurityInterceptor的例子:<br /> </a> <pre class="overflow"> <bean id="bankManagerSecurity" class="net.sf.acegisecurity.intercept.method.MethodSecurityInterceptor"><br /> <property name="validateConfigAttributes"><br />             <value>true</value><br />         </property><br />         <property name="authenticationManager"><br />              <ref bean="authenticationManager"/><br />         </property><br />         <property name="accessDecisionManager"><br />              <ref bean="accessDecisionManager"/><br />         </property><br />         <property name="objectDefinitionSource"><br />              <value>net.sf.acegisecurity.context.BankManager.delete*=<br />                              ROLE_SUPERVISOR,RUN_AS_SERVER<br />                      net.sf.acegisecurity.context.BankManager.getBalance=<br />                              ROLE_TELLER,ROLE_SUPERVISOR,BANKSECURITY_CUSTOMER,RUN_<br />              </value><br />         </property><br />    </bean> </pre> <br />     上面的配|文件中QMethodSecurityInterceptor是AbstractSecurityInterceptor的一个实现类。它包含了两个管理器QauthenticationManager和accessDecisionManager。这两者的配置如下Q?br />        <pre class="overflow"><bean id="authenticationDao" class="net.sf.acegisecurity.providers.dao.jdbc.JdbcDaoImpl"><br />                <property name="dataSource"><ref bean="dataSource"/></property><br />       </bean><br />       <bean id="daoAuthenticationProvider" <br />                      class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider"><br />                <property name="authenticationDao"><ref bean="authenticationDao"/></property><br />       </bean><br />       <bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager"><br />                <property name="providers"><br />                       <list><ref bean="daoAuthenticationProvider"/></list><br />                </property><br />       </bean><br />       <bean id="roleVoter" class="net.sf.acegisecurity.vote.RoleVoter"/><br />       <bean id="accessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased"><br />                <property name="allowIfAllAbstainDecisions"><value>false</value></property><br />                <property name="decisionVoters"><br />                       <list><ref bean="roleVoter"/></list><br />                </property><br />       </bean></pre> <br /> <br />     准备工作做好了,现在我们来看看Acegi安全pȝ是如何实现认证和授权机制的。以使用HTTP BASIC认证的应用ؓ例子Q它包括下面的步骤:<br />        1. 用户dpȝQAcegi从acegisecurity.ui子系l的安全拦截器(如BasicProcessingFilterQ中得到用户的登录信息(包括Principal和CredentialQƈ攑օAuthentication对象Qƈ保存在ContextHolder对象中;<br />        2. 安全拦截器将Authentication对象交给AuthenticationManagerq行w䆾认证Q如果认证通过Q返回带有Principal 授权信息的Authentication对象。此时ContextHolder对象的Authentication对象已拥有Principal的详l信息;<br />        3. 用户d成功后,l箋q行业务操作Q?br />        4. 安全拦截器(bankManagerSecurityQ收到客L操作h后,操作请求的数据包装成安全管理对象(FilterInvocation或MethodInvocation对象Q;<br />        5. 然后Q从配置文gQObjectDefinitionSourceQ中d相关的安全配|参数ConfigAttributeDefinitionQ?br />        6. 接着Q安全拦截器取出ContextHolder中的Authentication对象Q把它传递给AuthenticationManagerq行w䆾认证Qƈ用返回值更新ContextHolder的Authentication对象Q?br />        7. Authentication对象QConfigAttributeDefinition对象和安全管理对象(secure ObjectQ交lAccessDecisionManagerQ检查Principal的操作授权;<br />        8. 如果授权查通过则执行客Lh的操作,否则拒绝Q?br /> <br /> <strong>AccessDecisionVoter</strong><br />        注意上节的accessDecisionManager是一个AffirmativeBasedc,它对于用h权的投票{略是,只要通过其中的一个授权投检查,卛_通过Q它的allowIfAllAbstainDecisions属性值是falseQ意思是如果所有的授权投票是都是弃权,则通不q授权检查?br />        Acegi安全pȝ包括了几个基于投策略的AccessDecisionManagerQ上节的RoleVoter是其中的一个投策略实玎ͼ它是 AccessDecisionVoter的一个子cRAccessDecisionVoter的具体实现类通过投票来进行授权决{, AccessDecisionManager则根据投结果来军_是通过授权查,q是抛出AccessDeniedException例外?br />        AccessDecisionVoter接口共有三个ҎQ?br /> public int vote(Authentication authentication, Object object, ConfigAttributeDefinition config);<br /> public boolean supports(ConfigAttribute attribute);<br /> public boolean supports(Class clazz);<br />        其中的voteҎq回intq回|它们是AccessDecisionVoter的三个静态成员属性:ACCESS_ABSTAIN,QACCESS_DENIED和ACCESS_GRANTEDQ它们分别是弃权Q否军_赞成?br />        Acegi安全pȝ中,使用投票{略的AccessDecisionManager共有三个具体实现c:AffirmativeBased?ConsensusBased和UnanimousBased。它们的投票{略是,AffirmativeBasedcd需有一个投赞成即可通过Q?ConsensusBasedc需要大多数投票赞成卛_通过Q而UnanimousBasedc需要所有的投票赞成才能通过?br />        RoleVotercL一个Acegi安全pȝAccessDecisionVoter接口的实现。如果ConfigAttribute以ROLE_开_RoleVoter则进行投。如果GrantedAuthority的getAutorityҎ的Stringq回值匹配一个或多个以ROLE_ 开头的ConfigAttributeQ则投票通过Q否则不通过。如果没有以ROLE_开头的ConfigAttributeQRoleVoter则弃权?/td> </tr> </tbody> </table> <img src ="http://m.tkk7.com/szhswl/aggbug/169237.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/szhswl/" target="_blank">宋针q?/a> 2007-12-21 10:25 <a href="http://m.tkk7.com/szhswl/articles/169237.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Acegi 参考的部分译http://m.tkk7.com/szhswl/articles/169215.html宋针q?/dc:creator>宋针q?/author>Fri, 21 Dec 2007 01:20:00 GMThttp://m.tkk7.com/szhswl/articles/169215.htmlhttp://m.tkk7.com/szhswl/comments/169215.htmlhttp://m.tkk7.com/szhswl/articles/169215.html#Feedback0http://m.tkk7.com/szhswl/comments/commentRss/169215.htmlhttp://m.tkk7.com/szhswl/services/trackbacks/169215.html阅读全文

]]>
acegi-security-sample-contacts-filter例子学习(?http://m.tkk7.com/szhswl/articles/168839.html宋针q?/dc:creator>宋针q?/author>Wed, 19 Dec 2007 11:56:00 GMThttp://m.tkk7.com/szhswl/articles/168839.htmlhttp://m.tkk7.com/szhswl/comments/168839.htmlhttp://m.tkk7.com/szhswl/articles/168839.html#Feedback0http://m.tkk7.com/szhswl/comments/commentRss/168839.htmlhttp://m.tkk7.com/szhswl/services/trackbacks/168839.html功能实现分析

q个例子使用了HSQL做数据库Qspring的AOP作ؓ基础Q用Acegi做安全控制组件?br /> 联系人管理的web应用在启动时候,会做一pd初始化动作:
1. dweb.xml文gQ?/p>

2. q解析文仉的内宏V?br /> a) context-param元素?br /> i. contextConfigLocation属性。这个属性定义了spring所需要的3个属性文件。它们分别是QapplicationContext -acegi-security.xml、applicationContext-common-business.xml?applicationContext-common-authorization.xml
ii. log4jConfigLocation属性。这个属性定义了log4j配置文g?/p>

b) filter元素?br /> q里定义了acegi的一个过滤器。Acegi的大部分qo器都是这样配|的。用FilterToBeanProxylgQ给它传递一个targetClass属性。这个targetClass必须实现javax.servlet.Filter接口?br /> q里配置的是FilterChainProxy。这个FilterChainProxy比较好用Q可以ؓ它定义一串filter属性。这些filter会按照定义的顺序被调用。例如,
<bean id="filterChainProxy" class="net.sf.acegisecurity.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=httpSessionContextIntegrationFilter,authenticationProcessingFilter,basicProcessingFilter,rememberMeProcessingFilter,anonymousProcessingFilter,securityEnforcementFilter
</value>
</property>
</bean>
q个qo器的mapping?#8220;/*”?br /> c) listener元素?br /> i. ContextLoaderListener。这个是Spring使用来加载根applicationcontext。ƈ分别解析 applicationContext-acegi-security.xml、applicationContext-common- business.xml、applicationContext-common-authorization.xml{配|文Ӟ把相关的对象初始?br /> iii. Log4jConfigListener。这个是spring用来初始化log4jlg的listener?br /> iv. HttpSessionEventPublisher。这个组件将发布HttpSessionCreatedEvent和HttpSessionDestroyedEvent事glspring的applicationcontext?br /> d) servlet元素?br /> i. contacts。这里采用了spring的MVC框架Q?所以这个servlet是spring MVC的一个核心控制器Qorg.springframework.web.servlet.DispatcherServletQ。这个servlet 启动时候,会从contacts-servlet.xml里面d信息Qƈ做相关的初始化?br /> v. remoting。也是spring MVC的一个核心控制器。与contacts不同Q这个servlet主要是提供web services服务。这个servlet启动时候, 会从remoting-servlet.xml里面d信息Qƈ做相关的初始化?br /> e) taglib元素。这里定义了spring的标f) {ֺ?br /> 3. 解析applicationContext-acegi-security.xml?br /> a) qo器链。定义了一个FilterChainProxyQb) q指c) 定了一pd的过滤器链。httpSessionContextIntegrationFilter, authenticationProcessingFilter,basicProcessingFilter,rememberMeProcessingFilter,anonymousProcessingFilter,securityEnforcementFilter
d) 认证理器。这个管理器由acegi提供。这个管理器需要一个providers参数。这个providers参数包含了提供系l认证的对象?br /> i. daoAuthenticationProvider。一般用戯证?br /> ii. anonymousAuthenticationProvider。匿名用戯证?br /> iv. rememberMeAuthenticationProvider。记住我认证?/p>

e) 密码加密。这里定义了一个acegi的Md5法加密对象Md5PasswordEncoder?br /> f) 定义了一个jdbcDao实现cR这个类由acegi提供的net.sf.acegisecurity.providers.dao.jdbc.JdbcDaoImpl。这个对象需要一个dataSource的参数?br /> g) 定义daoAuthenticationProvider。这个对象由acegi提供。它?个属性:
authenticationDao。这里指向前面定义的jdbcDao?br /> userCache。这里指向后面定义的user~存对象?br /> passwordEncoder。这里指向前面定义的密码加密对象?br /> h) 用户~存理?br /> Z~存userQ这里用spring的ehcache来缓存user。缓存机Ӟ
i. 定义~存理器――CacheManager。这个对象是spring的EhCacheManagerFactoryBean对象
ii. 定义user~存实际执行对象――UserCacheBackend。这个对象是spring的EhCacheFactoryBean。它有两个属性:
1. cacheManager。这里指向前面定义的~存理器?br /> 2. cacheName?br /> iii. 定义user~存――UserCache。它是acegi提供的EhCacheBasedUserCache对象。它有一个属性:
1. cache。这里指向的是前面定义的userCacheBackend?/p>

i) 定义接收来自DaoAuthenticationProvider的认证事件的listener――LoggerListener?br /> j)
4. 解析applicationContext-common-business.xml?br /> a) dataSource.
q里使用了spring的DriverManagerDataSource对象。这个对象是一个JDBC数据源的定义?br /> b) TransactionManager。这里用spring的DataSourceTransactionManager对象?br /> c) 事务拦截器。这里用spring的事务拦截器TransactionInterceptor。它?个属性:
transactionManager。这个属性指向前面定义的TransactionManager?br /> transactionAttributeSource。这个属性里Q?指定了ContactManager的各个方法的事务斚w的要求?br /> d) DataSourcePopulator?br /> 使用sample.contact.DataSourcePopulator对象Q往HSQL里创建相关的表结构和数据?br /> 实现原理QDataSourcePopulator 实现了接?InitializingBean。其中afterPropertiesSetҎ在spring初始化DataSourcePopulator后被调用?br /> e) ContactDao。这里指向一个ContactDaoSpring对象。它l承spring?JdbcDaoSupportQg) q实现ContactDao接口。它是真正实现JDBC操作的对象?br /> h) ContactManager。这里用的是spring的ProxyFactoryBean。它?个属性:
i. ProxyInterfaces。代理接口:sample.contact.ContactManager

ii. InterceptorNames。拦截器名称。可以有多个Qiv. q里包括QtransactionInterceptor、contactManagerSecurity、contactManagerTarget。其中,v. transactionInterceptor是前面定义的事务拦截器。ContactManagerSecurity则是?applicationContext-common-authorization.xml里定义的Ҏ调用授权?br /> i) ContactManagerTarget。这里指向的是sample.contact.ContactManagerBackend对象?ContactManagerBackend实现了ContactManager接口和InitializingBean接口。它?个自定义属性: contactDao和basicAclExtendedDao。这里会调用ACL的APId些创建权限和删除权限的工作?/p>

]]>
acegi-security-sample-contacts-filter例子学习(一)http://m.tkk7.com/szhswl/articles/168837.html宋针q?/dc:creator>宋针q?/author>Wed, 19 Dec 2007 11:43:00 GMThttp://m.tkk7.com/szhswl/articles/168837.htmlhttp://m.tkk7.com/szhswl/comments/168837.htmlhttp://m.tkk7.com/szhswl/articles/168837.html#Feedback0http://m.tkk7.com/szhswl/comments/commentRss/168837.htmlhttp://m.tkk7.com/szhswl/services/trackbacks/168837.htmlq是一?/span>Acegi官方的例子。它以联pMh的管理ؓ例子Q说明如何?/span>Acegi作权限控制。这个例子包含在acegi的包里面。下载地址Q?/span>http://prdownloads.sourceforge.net/acegisecurity/acegi-security-0.8.3.zip?download?/span>

联系人管理说明了下列中心?span lang="EN-US">Acegi安全控制能力:

  • Role-based securityQ基于角色的安全Q?/span>――每个责Mh都是某个角色的一员。而角色被用来限制Ҏ些安全对象的讉K?/span>
  • Domain object instance securityQ域对象实例安全Q?/span>――合同,q个pȝ里的主要域对象,拥有一个访问控制列表(ACLQ,用来指明谁允许读、管理和删除对象?/span>
  • Method invocation securityQ方法调用安全)―?/span>q个 ContactManager服务层对?/span> 包含一些受保护的和公开的方法?/span>
  • Web request securityQ?/span>Webh安全Q?/span>――这?#8220;/secureURI路径被?/span>Acegi安全保护Q得没?/span>ROLE_USER 角色的用h法访问?/span>.
  • Security unaware application objectsQ保护未知的应用对象Q?/span>――受保护的对象与Acegi之间没有明显的耦合或契U,所以它们没有察觉到安全是由Acegi 提供的?/span>*
  • Security taglib usageQ安全标{ֺ使用Q?/span>――所有的JSP使用Acegi 安全标签库来装安全信息?/span>*
  • Fully declarative security(完全声明式的安全)――每一个安全方面特性都是在application context里面使用标准?/span>Acegi安全对象来配|的?/span> *
  • Database-sourced security dataQ支持数据库来源的安全数据)――所有的用户、角色和ACL信息都可以从一个兼?/span>JDBC的内存数据库获得?/span>
  • Integrated form-based and BASIC authenticationQ集成基于表单和BASIC验证Q―?/span> MBASIC验证头部被检以及作为验证用。默认用基于表单的普通交互式验证?/span>
  • Remember-me servicesQ记住我的服务)―?/span> Acegi安全的插件式?#8220;remember-me {略被演C。在d表单里有一个相关的选择框与之对应?/span>

 

    联系人管理的业务功能描述Q?/span>

              1. 每个用户d后,可以看到一个联pMh列表。例如,

marissa's Contacts

id

Name

Email

1

John Smith

john@somewhere.com

Del

Admin Permission

2

Michael Citizen

michael@xyz.com

 


 


3

Joe Bloggs

joe@demo.com

Del

 


4

Karen Sutherland

karen@sutherland.com

Del

Admin Permission

Add

说明Q用h有权限访问的联系Z息,不会显C?/span>

             2. 用户可以增加新的联系Z息?/span>

             3. 如果有删除权限,用户可以看到在联pMh后面有一?#8220;Del”链接。用户可以点击这个链接来删除某个联系Z息?/span>

             4. 如果有管理权限,用户可以看到在联pMh后面有一?#8220;Admin Permission”链接。用户可以点击这个链接来理讉Kq个联系人的权限。例如,

Administer Permissions

sample.contact.Contact@26807f: Id: 1; Name: John Smith; Email: john@somewhere.com

-R--- [2] dianne

Del

-RW-D [22] peter

Del

A---- [1] marissa

Del

Add Permission Manage

说明Q每一行记录包含有3列?/span>

W一列表C权限,例如Q?#8220;-RW-D”表示可读、可写、可删除?/span>

W二列也表示权限Q但它是以类?/span>unix权限的数字表达。例如,“[22], 表示可读、可写、可删除?/span>

W三列是用户名称?/span>

每一行记录后面都有一?#8220;Del”链接。点击这个链接,可以删除掉指定用户对q个联系Z息的权限?/span>

             5. 用户可以为某个联pMh信息d权限。例如,

Add Permission

Contact:

sample.contact.Contact@1787005: Id: 1; Name: John Smith; Email: john@somewhere.com

 


Recipient:

 


Permission:

 


说明Q权限是动态添加的。例如,上图中给用户scott增加了读联系?/span>John的权限。那?/span>scott马上可以看到联pMhJohn的信息了?/span>

]]>
վ֩ģ壺 ޹ۺ| ޾Ƶ| þþþùɫAVѹۿ| þñѵӰˬˬˬ| 99ƵȫѾƷȫĻ| ޹Ʒ˾þ| Ʒ1024Ƶ| Ʒ޳A߹ۿ| ˳ɫ777777߹ۿ| aëƬѹۿ| ޵һҳĻ| Ѵվ߹| Ļȫ| ۺһƷþ| Ʒ_ۿ| ŷպƵ| ɫ߾Ʒѹۿ| ȫƴȫɫȫѴƬ| ۺŷɫ°Ҳȥ| ѹۿŮվ| ɫtvվѿ| ߹ۿ޾Ʒר| һѹۿ| ޹˾þۺһ77| 8888ɫ߹ۿѿ| ؼaƬëƬѿ| Ʒ߹ۿ| ޳aƬ77777kkkk| avר| ҪWWWѿƵ| ձĻ| ձѾƷһ | Ƶѹۿ| sŷm봵| Ƶ| 㽶þþƷ| JIZZJIZZйٸ| ѻ߹ۿ| Ļ˾Ʒһվ| þþþþAVվ| Ļ|