vendredi 3 avril 2015

CAS Attribute Release for Collections

When my client app calls CAS's /p3/serviceValidate endpoint I am having trouble getting multi-valued attributes to be considered as a Collection rather than just a single-valued string attribute. The client app receives the following message back from CAS and the issue is the 'authorities' attribute is a comma separated value rather than multiple xml elements:


Spring Client - Receiving This From CAS Server



<cas:serviceResponse xmlns:cas='http://ift.tt/1jNd6ZE'>
<cas:authenticationSuccess>
<cas:user>srowatt</cas:user>
<cas:attributes>
<cas:firstname>Shane</cas:firstname>
<cas:authorities>ROLE_INNOADVERT,ROLE_INNOADVERT_ADMIN</cas:authorities>
<cas:lastname>Rowatt</cas:lastname>
<cas:username>srowatt</cas:username>
</cas:attributes>
</cas:authenticationSuccess>
</cas:serviceResponse>


Spring Client - Expecting This From CAS Server



<cas:serviceResponse xmlns:cas='http://ift.tt/1jNd6ZE'>
<cas:authenticationSuccess>
<cas:user>srowatt</cas:user>
<cas:attributes>
<cas:firstname>Shane</cas:firstname>
<cas:authorities>ROLE_ROLE_INNOADVERT</cas:authorities>
<cas:authorities>ROLE_INNOADVERT_ADMIN</cas:authorities>
<cas:lastname>Rowatt</cas:lastname>
<cas:username>srowatt</cas:username>
</cas:attributes>
</cas:authenticationSuccess>
</cas:serviceResponse>


CAS Server - User and Attributes Table


Below is the CAS Database Table with some sample values as comments:



CREATE TABLE users (
username character varying(50) NOT NULL, -- srowatt
password character varying(50) NOT NULL, --
active bit(1) NOT NULL, -- 1
firstname character varying, -- shane
lastname character varying, -- rowatt
authorities character varying -- ROLE_ROLE_INNOADVERT,ROLE_INNOADVERT_ADMIN
)


CAS Server - deployerConfigContext.xml


This is the important bean defs on the CAS Server side that tells CAS which attributes to put in the serviceValdidate response:



<bean id="primaryPrincipalResolver"
class="org.jasig.cas.authentication.principal.PersonDirectoryPrincipalResolver" >
<property name="attributeRepository" ref="attributeRepository" />
</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 users WHERE {0}" />
<property name="queryAttributeMapping">
<map>
<entry key="username" value="username" />
</map>
</property>
<property name="resultAttributeMapping">
<map>
<entry key="username" value="username" />
<entry key="firstname" value="firstname" />
<entry key="lastname" value="lastname" />
<entry key="authorities" value="authorities"/>
</map>
</property>
</bean>


On my spring client app side I'm using the GrantedAuthorityFromAssertionAttributesUserDetailsService class to pick the 'authorities' attribute and inject the values as Spring Authorities and hence why I want this attribute to be a collection (not a csv).



@Bean
public AuthenticationUserDetailsService<CasAssertionAuthenticationToken> authenticationUserDetailsService() {
String[] attributes = new String[] {
"authorities"
};
GrantedAuthorityFromAssertionAttributesUserDetailsService userDetailsService =
new GrantedAuthorityFromAssertionAttributesUserDetailsService(attributes);
return userDetailsService;
}


I'm not sure what magic I'm missing to tell CAS should treat 'authorities' as a collection and not just a string.


Aucun commentaire:

Enregistrer un commentaire