标签:
在cas中默认获取的用户信息为登录时填写的登录用户名,但是如果我不想返回登录的用户名,返回其他的信息呢?
首先在cas server中找到deployerConfigContext.xml配置文件中关于认证信息配置的地方即name="credentialsToPrincipalResolvers",这里是
关于返回用户信息所对应的类。默认执行的是下面这个类。
<bean
class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver" />
在这个类中定义返回的用户信息为userName了。
源码如下:
public final class UsernamePasswordCredentialsToPrincipalResolver extends
AbstractPersonDirectoryCredentialsToPrincipalResolver {
protected String extractPrincipalId(final Credentials credentials) {
final UsernamePasswordCredentials usernamePasswordCredentials = (UsernamePasswordCredentials) credentials;
return usernamePasswordCredentials.getUsername();
}
/**
* Return true if Credentials are UsernamePasswordCredentials, false
* otherwise.
*/
public boolean supports(final Credentials credentials) {
return credentials != null
&& UsernamePasswordCredentials.class.isAssignableFrom(credentials
.getClass());
}
}
所以,如果我们想要改变这个返回信息,就要重写这个类。重写代码如下:
public class MyCredentialsToPrincipalResolver implements
CredentialsToPrincipalResolver {
private DataSource dataSource;//查询数据库用
public Principal resolvePrincipal(Credentials credentials) {
UsernamePasswordCredentials up = //强制类型转换
(UsernamePasswordCredentials) credentials;
String name = up.getUsername();
String pwd = up.getPassword();
String sql = "select id from ta_allusers where userCode=? and password=?"; //查询id - 一般只根据用户查询即可
String id = null;
try{
id=new JdbcTemplate(getDataSource()).queryForObject(sql, String.class, name,pwd);
if(id!=null){
Principal p = new SimplePrincipal(id);//封装成包含id的Principal对象
return p;
}
}catch(Exception e){
e.printStackTrace();
}
return null;
}
public boolean supports(Credentials credentials) {
boolean boo = //判断是否是用户和密码凭据
UsernamePasswordCredentials.class.isAssignableFrom(credentials.getClass());
return boo;
}
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
}
这样返回的结果如下:
二、利用Map返回用户的更多信息
如果一次返回用户的更多信息,我们可以利用Map来获取想要的数据。同样需要重写上面的方法。
public class MoreInfoMap implements CredentialsToPrincipalResolver {
private DataSource dataSource;//查询数据库用
public Principal resolvePrincipal(Credentials credentials) {
UsernamePasswordCredentials up = //强制类型转换
(UsernamePasswordCredentials) credentials;
String name = up.getUsername();
String pwd = up.getPassword();
//如果有其他属性需要查询,也可以查询其他信息,增加多个列就可以,可以返回一个list,或者对象数组,然后再往map里面赋值。
String sql = "select id from ta_allusers where userCode=? and password=?"; //查询id - 一般只根据用户查询即可
String id = null;
try{
id=new JdbcTemplate(getDataSource()).queryForObject(sql, String.class, name,pwd);
if(id!=null){
Map<String, Object> map=new HashMap<String, Object>();
map.put("username", name);
map.put("password", pwd);
Principal p = new SimplePrincipal(id,map);//封装成包含id的Principal对象
return p;
}
}catch(Exception e){
e.printStackTrace();
}
return null;
}
public boolean supports(Credentials credentials) {
boolean boo = //判断是否是用户和密码凭据
UsernamePasswordCredentials.class.isAssignableFrom(credentials.getClass());
return boo;
}
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
}
当然在deployerConfigContext.xml这个配置文件中需要配置相应的实现类。如下:
<bean class="com.wyy.moreInfo.MoreInfoMap">
<property name="dataSource" ref="dataSource"></property>
</bean>
在cas client访问的页面中需要读取Map的相关信息如下:
<%
Assertion ass=AssertionHolder.getAssertion();
ass=(Assertion)session.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION);
Map m=ass.getPrincipal().getAttributes();
out.print(m);
%>
经过上述的配置后,并不能看到我们想要的信息。因为服务器验证成功以后,是通过xml形式将结果传递给客户端的,
xml的生成由casServiceValidationSuccess.jsp文件负责。它的具体构造应该是以下形式:
<cas:serviceResponse
xmlns:cas=‘http://www.yale.edu/tp/cas‘>
<cas:authenticationSuccess>
<cas:user>U001</cas:user>
<cas:attributes>
<cas:pwd>1234</cas:pwd>
<cas:username>Jack</cas:username>
</cas:attributes>
</cas:authenticationSuccess>
</cas:serviceResponse>
在上面的代码中,cas:attributes元素是我自己添加的,客户端的的Filter在接收到上述的XML以后,会将css:attributes中的属性解析出来,
放到AttirubtePrincipal的attributes属性中去(或是放到Asseration的attributes中去,两个只会放一个)。
默认情况下,将所有属性信息放到AttributePrincipal中去,所以在客户端的页面上可以通过
Map m=ass.getPrincipal().getAttributes();来进行取值。
所以,组成上面的<cas :attributes>元素中的内容,就成了如何传递更多属性的关键,在修改了MoreInfoMap
的代码以后,然后还必须要在cas server中casServiceValidationSuccess.jsp中添加如下代码:
<cas:attributes>
<c:forEach
items="${assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes}"
var="attr">
<cas:${attr.key}>${attr.value}</cas:${attr.key}>
</c:forEach>
</cas:attributes>
再者,因为cas服务端默认是不支持以Map形式来显示用户的更多信息的,所以,我们需要将deployerConfigContext.xml
这个配置文件中关于id="serviceRegistryDao"的所有<property>全部注释掉。就可以显示了。
显示效果如下:
标签:
原文地址:http://blog.csdn.net/wangyy130/article/details/51941086