CAS多条件登录后返回用户信息
(2013-08-06 14:11:05)分类: Cas |
参考文档:http://aayy520.blog.163.com/blog/static/2318226020128531134381/
很多人在使用CAS作为自己的单点登录服务器时,都想从CAS Server端获取更多的用户信息,网上的介绍一般都是仅限于单条件SQL来进行查询,而实际上,有些使用情况比较复杂,
比如我想让CAS支持多种方式的登录,那就必须使用多条件的SQL来获取用户信息,下面将介绍如何达成这一目的,而对于单条件SQL将不再赘述,网上一大把:
1、查看org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttri
通过SingleRowJdbcPersonAttri
然后找到AbstractJdbcPersonAttrib
private Map<String, Set<String>> queryAttributeMapping;
private Map<String, Set<String>> resultAttributeMapping;
private Set<String> possibleUserAttributes;
private boolean requireAllQueryAttribute
private boolean useAllQueryAttributes = true;
private String unmappedUsernameAttribut
看懂了这些,我们就可以在deployerConfigContext.xml中添加
<bean id="attributeRepository" class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttri
<constructor-arg index="0" ref="dataSource" />
<constructor-arg index="1" value="select * from user where {0} {1} {2}"/>
</constructor-arg>
<!-- 组装sql用的查询条件属性 -->
<property name="queryAttributeMapping">
<map>
<entry key="nickname" value="nickname"/>
<entry key="cellphone" value="cellphone"/>
<entry key="email" value="email"/>
</map>
</property>
<!-- 如果要组装多个查询条件,需要加上下面这个,默认为AND -->
<property name="queryType">
<value>OR</value>
</property>
<!-- 要获取的属性在这里配置 -->
<property name="resultAttributeMapping">
<map>
<!--key为对应的数据库字段名称,value为提供给客户端获取的属性名字,系统会自动填充值-->
<entry key="nickname" value="nickname" />
<entry key="cellphone" value="cellphone" />
<entry key="id" value="id" />
<entry key="email" value="email" />
</map>
</property>
</bean>
上面的配置中,关键点在:
<property name="queryAttributeMapping">
<map>
<entry key="nickname" value="nickname" />
<entry key="cellphone" value="cellphone" />
<entry key="id" value="id" />
<entry key="email" value="email" />
</map>
</property>
<property name="queryType">
<value>OR</value>
</property>
最终组装而成的SQL是:nickname='xxxx' OR cellphone='xxxx' OR email='xxxxx'
好了,我们开始调试,实际测试的结果不是我想要的,实际组装成的SQL,永远都只是取queryAttributeMapping的最后一个来组装SQL条件:email='xxxx',经过分析,
发现CAS虽然在这里可以配置成多条件SQL,但并未给出组装成多条件SQL的方法,不知道是何缘故。
2、 在AbstractDefaultAttribute
经过分析发现,在AbstractDefaultAttribute
这里singletonMap永远只会返回单条map,所以如果要返回多条KEY的MAP,必须自己添加一个方法,我加了一个方法:
protected Map<String, List<Object>> toSeedMutiMap(String uid) {
final List<Object> values = Collections.singletonList((Object)uid);
final String nicknameAttribute = this.usernameAttributeProvide
final String cellphoneAttribute = this.usernameAttributeProvide
final String emailAttribute = this.usernameAttributeProvide
Map<String, List<Object>> seed =new HashMap<String, List<Object>>();
seed.put(nicknameAttribute , values);
seed.put(cellphoneAttribute , values);
seed.put(emailAttribute , values);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Created seed map='" + seed + "' for uid='" + uid + "'");
}
return seed;
}
在IUsernameAttributeProvid
public String getNicknameAttribute();
public String getCellphoneAttribute();
public String getEmailAttribute();
在SimpleUsernameAttributeP
private String cellphoneAttribute = "cellphone";//和配置文件中的key值一样
private String nicknameAttribute = "nickname";";//和配置文件中的key值一样
private String emailAttribute = "email";";//和配置文件中的key值一样
public void setCellphoneAttribute(String cellphoneAttribute) {
Validate.notNull(cellphoneAttribute);
this.cellphoneAttribute = cellphoneAttribute;
}
public void setNicknameAttribute(String nicknameAttribute) {
Validate.notNull(nicknameAttribute);
this.nicknameAttribute = nicknameAttribute;
}
public void setEmailAttribute(String emailAttribute) {
Validate.notNull(emailAttribute);
this.emailAttribute = emailAttribute;
}
@Override
public String getCellphoneAttribute() {
// TODO Auto-generated method stub
return this.cellphoneAttribute;
}
@Override
public String getEmailAttribute() {
// TODO Auto-generated method stub
return this.emailAttribute;
}
@Override
public String getNicknameAttribute() {
// TODO Auto-generated method stub
return this.nicknameAttribute;
}
最后在public IPersonAttributes getPerson(String uid)中将final Map<String, List<Object>> seed = this.toSeedMap(uid);修改为:
final Map<String, List<Object>> seed = this.toSeedMutiMap(uid);
这样就大功告成。