技术分享 CAS单点登录 服务端配置 查看内容

cas入门之二十七:person directory(中)

老高 | 发布于 2017-05-05 14:36| 浏览()| 评论() | 收藏() | 点赞() | 打印

摘要: 在很多情况下,需要从多个数据源中获取用户信息,然后合并相关的信息返回给客户端。

在很多情况下,需要从多个数据源中获取用户信息,然后合并相关的信息返回给客户端。在person directory中有两种方式来解决这个问题,一是MergingPersonAttributeDaoImpl, 即将多个IPersonAttributesAttributeDao获取到的用户信息,进行合并成一个结果集,默认是将几个结果集相同属性的合成在一起,然后返回给客户端;另一个是CascadingPersonAttributeDao,默认它将后一个结果集,替换上一个结果集中相同的属性值,然后返回给客户端。

MergingPersonAttributeDaoImpl配置:

<bean id="mergingPersonAttributeDao"
    class="org.jasig.services.persondir.support.MergingPersonAttributeDaoImpl">
    <property name="personAttributeDaos">
        <list>
            <ref bean="jdbcPersonAttributeDao1" />
            <ref bean="jdbcPersonAttributeDao2" />
            <ref bean="jdbcPersonAttributeDao3" />
        </list>
    </property>
</bean>

它的返回结果是jdbcPersonAttributeDao1,jdbcPersonAttributeDao2,jdbcPersonAttributeDao3三个结果集的合并集, 默认合并方式MultivaluedAttributeMerger;

CascadingPersonAttributeDao配置:

<bean id="cascadingPersonAttributeDao"
    class="org.jasig.services.persondir.support.CascadingPersonAttributeDao">
    <property name="personAttributeDaos">
        <list>
            <ref bean="jdbcPersonAttributeDao1" />
            <ref bean="jdbcPersonAttributeDao2" />
            <ref bean="jdbcPersonAttributeDao3" />
        </list>
    </property>
</bean>

它的返回结果是jdbcPersonAttributeDao1,jdbcPersonAttributeDao2,jdbcPersonAttributeDao3依次替换最后剩下的属性集合结果,默认合并方式ReplacingAttributeAdder。

假设jdbcPersonAttributeDao1的返回结果集{email=test@example.com,phone=12345678};jdbcPersonAttributeDao2的返回结果集{phone=12356790,office=33438}

那么如何进行结果集的合并呢?这就涉及到合并策略。

1.MultivaluedAttributeMerger

它的合并结果将所有的属性合并在一起,result={email=test@example.com,phone=[12345678,12356790],office=33438}

2.ReplacingAttributeAdder

它的合并结果是 result={email=test@example.com,phone=12356790,office=33438};

另外person directory还提供了另外一种合并策略

3.NoncollidingAttributeAdder

它的合并结果是 result={email=test@example.com,phone=12345678,office=33438}

MergingPersonAttributeDaoImpl或者CascadingPersonAttributeDao的合并策略,通过merger属性,如下:

<bean id="mergingPersonAttributeDao"
    class="org.jasig.services.persondir.support.MergingPersonAttributeDaoImpl">
    <property name="personAttributeDaos">
        <list>
            <ref bean="jdbcPersonAttributeDao1" />
            <ref bean="jdbcPersonAttributeDao2" />
            <ref bean="jdbcPersonAttributeDao3" />
        </list>
    </property>
    <property name="merger" ref="noncollidingAttributeAdder"  />
</bean>

<bean id="noncollidingAttributeAdder"  class="org.jasig.services.persondir.support.merger.NoncollidingAttributeAdder" />

对于这种用户认证成功之后,cas服务器,通过person directory,每次都需要重新获取用户信息,然后合并处理,最后返回给客户端。通常用户信息,都是不频繁更改的,person directory提供了用户信息的缓存功能:CachingPersonAttributeDaoImpl,它的配置如下:

<bean id="cachingPersonAttributeDao"
    class="org.jasig.services.persondir.support.CachingPersonAttributeDaoImpl">
    <property name="cachedPersonAttributesDao" ref="mergingPersonAttributeDao" />
    <property name="userInfoCache" ref="userInfoCacheMap" />
    <property name="cacheNullResults" value="false" />
    <property name="cacheKeyGenerator" ref="attributeBasedCacheKeyGenerator" />
</bean>

<bean id="attributeBasedCacheKeyGenerator"
    class="org.jasig.services.persondir.support.AttributeBasedCacheKeyGenerator">  <!-- 需要增加spring-modules-cache-.jar -->
</bean>

默认情况下attributeBasedCacheKeyGenerator,是以用户名username生成缓存键值,然后进行数据缓存;

userInfoCache是一个private Map<Serializable, Set<IPersonAttributes>> userInfoCache;

在person directory 中没有默认实现类,这个需要用户自己去实现。在这里我们就有了很大的发挥空间了,可以实现单机版,可以实现集群版等。

对于集群版,可以用ehcache,memcached 等去存储,这个不具体说明了。对于单机版进行测试,可以进行如下配置:

<bean id="userInfoCacheMap" class="java.util.concurrent.ConcurrentHashMap" /> 

它的缺点,就是对于缓存的内容无过期处理策略.

发表评论(对文章涉及的知识点还有疑问,可以在这里留言,老高看到后会及时回复的。)

表情