I am using CAS with JDBC Authentication handler and was wondering is it possible to get the other attributes of principal object (for e.g. firstname, lastname) not just the username from CAS after successful authentication?
-
1You might wanna have a look at this blog post: http://beansgocrazy.blogspot.com.au/2012/05/cas-attribute-release-backed-by.html – n0rm1e May 30 '12 at 13:24
5 Answers
In the casServiceValidationSuccess.jsp, I add like below:
<cas:attributes>
<c:forEach var="attr" items="${assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes}">
**<cas:${fn:escapeXml(attr.key)}>${fn:escapeXml(attr.value)}</cas:${fn:escapeXml(attr.key)}>**
</c:forEach>
</cas:attributes>
In the deployerConfigContent.xml, I add like below:
<bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver" >
**<property name="attributeRepository">
<ref bean="attributeRepository" />
</property>**
</bean>
<bean id="attributeRepository" class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao">
<constructor-arg index="0" ref="dataSource"/>
<constructor-arg index="1" value="select * from bbs_members where {0}" />
<property name="queryAttributeMapping">
<map>
<entry key="username" value="username" />
</map>
</property>
<property name="resultAttributeMapping">
<map>
<entry key="uid" value="uid"/>
<entry key="email" value="email"/>
<entry key="password" value="password"/>
</map>
</property>
</bean>
It works.
I came across this problem during the debug, please close the browser if you change this JSP or XML files, otherwise the changes won't work. Be careful.

- 3,836
- 6
- 50
- 75

- 313
- 3
- 7
-
see also: [/WEB-INF/view/jsp/protocol/3.0/casServiceValidationSuccess.jsp](https://github.com/Jasig/cas/blob/4.0.x/cas-server-webapp/src/main/webapp/WEB-INF/view/jsp/protocol/3.0/casServiceValidationSuccess.jsp), you can use it to overlay [/WEB-INF/view/jsp/protocol/2.0/casServiceValidationSuccess.jsp](https://github.com/Jasig/cas/blob/4.0.x/cas-server-webapp/src/main/webapp/WEB-INF/view/jsp/protocol/2.0/casServiceValidationSuccess.jsp) – btpka3 Feb 03 '15 at 05:09
To get any user attributes from DB I did the following: use PersonDirectoryPrincipalResolver
in deployerConfigContext.xml:
<bean id="primaryPrincipalResolver"
class="org.jasig.cas.authentication.principal.PersonDirectoryPrincipalResolver" >
<property name="attributeRepository" ref="singleRowJdbcPersonMultiplyAttributeDao" />
</bean>
instead of using standard SingleRowJdbcPersonAttributeDao class create your own implementation which returns not only one row from a query result but aggregated data from all returned rows:
copy all code from SingleRowJdbcPersonAttributeDao
and change only one method parseAttributeMapFromResults
.
you will have something like that:
public class SingleRowJdbcPersonMultiplyAttributeDao extends AbstractJdbcPersonAttributeDao<Map<String, Object>> {
...
@Override
protected List<IPersonAttributes> parseAttributeMapFromResults(final List<Map<String, Object>> queryResults, final String queryUserName) {
final List<IPersonAttributes> peopleAttributes = new ArrayList<IPersonAttributes>(queryResults.size());
Map<String, List<Object>> attributes = new HashMap<String, List<Object>>();
for (final Map<String, Object> queryResult : queryResults) {
for (final Map.Entry<String, Object> seedEntry : queryResult.entrySet()) {
final String seedName = seedEntry.getKey();
final Object seedValue = seedEntry.getValue();
if (attributes.get(seedName) != null && !attributes.get(seedName).get(0).equals(seedValue)) {
attributes.get(seedName).add(seedValue);
} else {
List<Object> list = new ArrayList<Object>();
list.add(seedValue);
attributes.put(seedName, list);
}
}
}
final IPersonAttributes person;
final String userNameAttribute = this.getConfiguredUserNameAttribute();
if (this.isUserNameAttributeConfigured() && attributes.containsKey(userNameAttribute)) {
// Option #1: An attribute is named explicitly in the config,
// and that attribute is present in the results from LDAP; use it
person = new CaseInsensitiveAttributeNamedPersonImpl(userNameAttribute, attributes);
} else if (queryUserName != null) {
// Option #2: Use the userName attribute provided in the query
// parameters. (NB: I'm not entirely sure this choice is
// preferable to Option #3. Keeping it because it most closely
// matches the legacy behavior there the new option -- Option #1
// -- doesn't apply. ~drewwills)
person = new CaseInsensitiveNamedPersonImpl(queryUserName, attributes);
} else {
// Option #3: Create the IPersonAttributes doing a best-guess
// at a userName attribute
person = new CaseInsensitiveAttributeNamedPersonImpl(userNameAttribute, attributes);
}
peopleAttributes.add(person);
return peopleAttributes;
}
...
}
and in deployerConfigContext.xml:
<bean id="singleRowJdbcPersonMultiplyAttributeDao"
class="com.scentbird.SingleRowJdbcPersonMultiplyAttributeDao">
<constructor-arg index="0" ref="dataSource" />
<constructor-arg index="1" value="SELECT attributes_table1.*, attributes_table2.attr1, attributes_table2.roles AS roles FROM user_table ut LEFT JOIN roles_table rt ON <condition> LEFT JOIN another_table at ON <condition> WHERE {0}" />
<property name="queryAttributeMapping">
<map>
<entry key="username" value="username" />
</map>
</property>
</bean>
Also in my case I used SAML protocol.
As a result you will get on the client all attributes which your select returns. For example, if user have many roles you could have on the client:
User: username, firstname, lastname, email, ... , [ROLE_1, ROLE_2, ROLE_3]
My case works with Spring Security and Grails.
I'm not sure this is 100% Feng Shui solution :) as it's fast cooked but it works in our case.
Hope it helps.

- 306
- 3
- 15
The definitive and complete solution is the following (for this undocumented feature):
Server side:
a. Add an
attributeRepository
to yourCredentialsToPrincipalResolver
.b. Implement the
your.package.YourPersonAttributeDao
like anIPersonAttributeDao
.c. Declare the attributes that will be transmitted into assertion to client.
d. Modify the
casServiceValidationSuccess.jsp
to display the attributes (thx to xiongjiabin).Client side. You get all attributes by doing this:
Due to formatting problem I can't post the code of the definitive solution.... Let me know if you are interested, I will send you an email with all the code.

- 9,137
- 11
- 75
- 83

- 2,896
- 6
- 27
- 49
-
I have authorize CAS to have OAuth Client Support, it is working fine now what I need is to have all the attributes of user logging through Facebook and add the same user to my web application, please send me code and any tips to my mail id aasifzia786@gmail.com – Laxman Rana Jun 13 '13 at 05:20
I just spent the last three days attempting to get CAS properly configured. One of the issues I encountered was that I had to explicitly instruct CAS to publish the properties. I did this by:
- opening https://localhost/cas/services
- going to the 'Manage Services' tab
- click 'edit' for each service
- highlight the properties you wish to publish
- click the save button
FWIW, the other issue is that casServiceValidationSuccess.jsp does contain any code to pass the properties back in the response. I was looking for a solution to this when I found your question. I notice that you have rewritten your implementation.

- 1,354
- 10
- 23
-
Hi Faron, I had used the maven war 2 overlay for installing the CAS and it didn't showed anyway by which I could publish the attributes through the services interface and that's why I had to rewrite. I think you might benefit from using a SAML2.0 to get the response from CAS about the extra attributes you have published. – Pranav Garg Jun 08 '11 at 17:06
-
Thanks for the tip with selecting the attributes in the service tab - that was a step I had not realized was necessary – Jesse Vogt Jul 27 '11 at 14:24
-
Thanks for the tip about `casServiceValidationSuccess.jsp`. Apparently that's necessary for passing attributes to phpCAS. – Nic Apr 13 '13 at 03:19
-
Instead of making [possibly temporary] changes in the web interface, you could could define the list of allowedAttributes for your serviceRegistryDao in deployerConfigContext.xml. – Nic Apr 13 '13 at 03:24
In addition to the answer provided by @xiongjiabin if you are using CAS v4+ you probably want to use assertion.primaryAuthentication
instead of assertion.chainedAuthentications
in casServiceValidationSuccess.jsp
:
<cas:attributes>
<c:forEach var="attr" items="${assertion.primaryAuthentication.principal.attributes}">
<cas:${fn:escapeXml(attr.key)}>${fn:escapeXml(attr.value)}</cas:${fn:escapeXml(attr.key)}>**
</c:forEach>
</cas:attributes>
If you do use assertion.chainedAuthentications
with CAS v4+ then the serviceRegistryDao
list of allowedAttributes
will be ignored and all attributes will be returned.

- 1,076
- 9
- 12
-
If you're using CAS v4+ you can use the /p3/serviceValidate endpoint and it has the attributes already included in the casServiceValidationSuccess.jsp – REW Sep 27 '16 at 15:23
-
This answer is great to know if you are upgrading from CAS 3.x to 4.x and a majority of your clients are still using the CAS 2.0 protocol. If you have any new clients and running CAS 4.x, then you can recommend they use the CAS 3.0 protocol endpoint. – acvcu Dec 09 '16 at 13:50