在cas中默认获取的用户信息为登录时填写的登录用户名,但是如果我不想返回登录的用户名,返回其他的信息呢?
First, the login user's ID as the default value display
首先在cas server中找到deployerConfigContext.xml配置文件中关于认证信息配置的地方即name="credentialsToPrincipalResolvers",这里是关于返回用户信息所对应的类。默认执行的是下面这个类。
<bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver" />
在这个类中定义返回的用户信息为userName了。源码如下:
Public Final class usernamepasswordcredentialstoprincipalresolver extends Abstractpersondirectorycredentialstoprincipalresolver { protectedStringExtractprincipalid(FinalCredentials Credentials) {FinalUsernamepasswordcredentials usernamepasswordcredentials = (usernamepasswordcredentials) credentials;returnUsernamepasswordcredentials.getusername (); }/** * Return true if Credentials is usernamepasswordcredentials, false * otherwise. */ Public Boolean supports(FinalCredentials Credentials) {returnCredentials! =NULL&& UsernamePasswordCredentials.class.isAssignableFrom (Credentials getclass ()); }}
所以,如果我们想要改变这个返回信息,就要重写这个类。重写代码如下:
Public class mycredentialstoprincipalresolver implements Credentialstoprincipalresolver { PrivateDataSource DataSource;//Query database with PublicPrincipalResolveprincipal(Credentials Credentials) {Usernamepasswordcredentials up =//coercion type conversion(usernamepasswordcredentials) credentials; String name = Up.getusername (); String pwd = Up.getpassword (); String sql ="SELECT ID from ta_allusers where usercode=?" and password=? ";//Query ID-generally only based on user queriesString ID =NULL;Try{id=NewJdbcTemplate (Getdatasource ()). queryForObject (SQL, String.class, name,pwd);if(id!=NULL) {Principal p =NewSimpleprincipal (ID);//Encapsulated as an principal object containing ID returnP } }Catch(Exception e) {E.printstacktrace (); }return NULL; } Public Boolean supports(Credentials Credentials) {BooleanBoo =//Determine if the user and password credentialsUsernamePasswordCredentials.class.isAssignableFrom (Credentials.getclass ());returnBoo } PublicDataSourceGetdatasource() {returnDataSource; } Public void Setdatasource(DataSource DataSource) { This. DataSource = DataSource; }}
这样返回的结果如下:
Second, use map to return the user more information
如果一次返回用户的更多信息,我们可以利用Map来获取想要的数据。同样需要重写上面的方法。
Public class moreinfomap implements credentialstoprincipalresolver { PrivateDataSource DataSource;//Query database with PublicPrincipalResolveprincipal(Credentials Credentials) {Usernamepasswordcredentials up =//coercion type conversion(usernamepasswordcredentials) credentials; String name = Up.getusername (); String pwd = Up.getpassword ();//If there are other attributes that need to be queried, you can also query other information, add multiple columns, and you can return a list, or an array of objects, and then assign values to the map. String sql ="SELECT ID from ta_allusers where usercode=?" and password=? ";//Query ID-generally only based on user queriesString ID =NULL;Try{id=NewJdbcTemplate (Getdatasource ()). queryForObject (SQL, String.class, name,pwd);if(id!=NULL) {map<string, object> map=NewHashmap<string, object> (); Map.put ("username", name); Map.put ("Password", PWD); Principal p =NewSimpleprincipal (ID,MAP);//Encapsulated as an principal object containing ID returnP } }Catch(Exception e) {E.printstacktrace (); }return NULL; } Public Boolean supports(Credentials Credentials) {BooleanBoo =//Determine if the user and password credentialsUsernamePasswordCredentials.class.isAssignableFrom (Credentials.getclass ());returnBoo } PublicDataSourceGetdatasource() {returnDataSource; } Public void Setdatasource(DataSource DataSource) { This. DataSource = DataSource; }}
当然在deployerConfigContext.xml这个配置文件中需要配置相应的实现类。如下:
class="com.wyy.moreInfo.MoreInfoMap"> <propertyname="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:serviceresponsexmlns: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" uses map to return more information