码迷,mamicode.com
首页 > 其他好文 > 详细

【cas】利用Map返回更多信息

时间:2016-07-19 10:08:08      阅读:151      评论:0      收藏:0      [点我收藏+]

标签:

在cas中默认获取的用户信息为登录时填写的登录用户名,但是如果我不想返回登录的用户名,返回其他的信息呢?

一、将登录用户的id作为默认值 显示

首先在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>全部注释掉。就可以显示了。
显示效果如下:

技术分享

【cas】利用Map返回更多信息

标签:

原文地址:http://blog.csdn.net/wangyy130/article/details/51941086

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!