Skip navigation.
Home

How to Integrate Central Authentication Service(CAS) with Spring

HI

how to integrate Central Authentication Service(CAS) with Spring Framework

plz give me the steps how to do

thanks in advance for the help

regards
surya

Matt Fleming's picture

Steps?

Did you read How Spring Security hooks to Central Authentication Service (CAS)? Is there something else that I missed?

-Matt

I have to login in each request

Firstly, thank you for your advices and your time.

The file application-context.xml seems not to keep the information about the authentication. I think the problem is the HttpSessionContextIntegrationFilter filter, that doesn't exist. I tried to do a new one for my application (CAS 3.3.2 with LDAP + Spring Security 2.0.4), but I have problems due to the position of the filters. My files are:

applicationContext-security.xml
<?xml version="1.0" encoding="UTF-8"?>

CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
**=REQUIRES_SECURE_CHANNEL

CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
*/secure/**=ROLE_CF_LECTOR
*/secure/extreme/**=ROLE_CF_EDITOR

web.xml
<?xml version="1.0"?>

Spring Security CAS Application

contextConfigLocation

/WEB-INF/applicationContext-security.xml

log4jConfigLocation
/WEB-INF/classes/log4j.properties

webAppRootKey
cas.root

filterChainProxy
org.springframework.web.filter.DelegatingFilterProxy

filterChainProxy
/*

org.jasig.cas.client.session.SingleSignOutHttpSessionListener

org.springframework.web.context.ContextLoaderListener

org.springframework.web.util.Log4jConfigListener

Any suggestion?

UserDetailService

Matt,
First off, like everyone else, thanks for posting this. I was wrestling with integrating Spring and CAS. I felt like I was close, but this post got it working.

I was able to get a test page to authenticate with the CAS server using the SimpleTestUsernamePasswordAuthenticationHandler. This worked like a charm, now I am on to actually implementing the UserDetailService. Here is where my question lies.

I have 3 applications (services, 1 Spring based, 2 Custom) that I want to authenticate with the CAS server. I am planning on using a JDBCDAoImp for the authentication. I have a HibernateUserDao that implements UserDetailsService and have successfully gotten the flow of information coming from CAS to the loadUserByUserName.

If each of the applications have their own roles (permissions) what is the best design to manage a users permissions? I wanted the CAS server to manage the users and their roles, along with other data that is relevant to what a user can see. This would make it easier to manage the users permissions between the various applications without having to be on each application server to manage the users permissions.

I am still learning so if this question is a dumb one I understand. I'll keep plugging along and try to find a better question.

Thanks again for the wonderful post.

B

Matt Fleming's picture

A centralized point

What you need is some centralized place for your users and roles. A lot of organizations that I work with use an LDAP server to manage users and roles. You could just as easily maintain a centralized database that is accessible (via JDBC) from each of the three applications as well. Essentially you want a single point that all of the applications can access.. the implementation doesn't really matter (e.g. LDAP, DB, roll-your-own, etc) but LDAP is pretty ubiquitous.

CAS is of course a centralized place, and that's why it feels like a good spot for this kind of information. However, that's not the scope of CAS, it's merely an authentication service, rather than an authorization service. If you do end up doing something like LDAP, you should also point your CAS instance at that as well (rather than copying data to a local database).

You could also do some kind of distributed implementation as well but this isn't usually necessary within the same organization.

-Matt

Thanks

Thanks for the comments. I need to be able to say John Doe created this software on the software server and then john doe created a forum thread on the forum server (example). Would the best solution here be a distributed model with the database? Is there a simpler solution? The applications will have their own separate databases to separate the workload of non revenue based operations with revenue based.

On a side bar...I am getting my butt stomped getting this CAS working with JDBC on different computers. I get authenticated by CAS using JDBC (pretty easy) and get the token back, but when it returns me back to my service (denoted in my serviceProperties) I get The requested resource (/AppServer/j_spring_cas_security_check) is not available.

I don't really have a question because I have hacked at it all day, so I can't even organize a question at this point. If you could, take a look at my securityconfig and see if there is anything blazing wrong. Basically I have two servers one cas and an application server. I have both running on two instances of tomcat on my laptop. One is on 8080 and the other 9443 (cas). Any help would be much appreciated. If you feel you'll just waste your time, I understand. I'll review my stuff and try to organize a more straightforward question.

BTW, sorry to double reply on you like this. My company blocked gmail and I didn't know you already responded to this post.

One more thing, if you are interested in some side work in helping me get this off the ground, I can offer you contractor work.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:security="http://www.springframework.org/schema/security"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
						http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.2.xsd
						http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">
 
 
	<bean id="filterChainProxy" class="org.springframework.security.util.FilterChainProxy">
		<security:filter-chain-map path-type="ant">
			<security:filter-chain filters="httpSessionContextIntegrationFilter,casSingleSignOutFilter,casProcessingFilter,securityContextHolderAwareRequestFilter,exceptionTranslationFilter,filterInvocationInterceptor" pattern="/secured/*"/>
		</security:filter-chain-map>
	</bean>
 
 
 
 
	<bean id="exceptionTranslationFilter" class="org.springframework.security.ui.ExceptionTranslationFilter">
		<property name="authenticationEntryPoint" ref="casProcessingFilterEntryPoint"/>
	</bean>	
 
 
	<bean id="casProcessingFilterEntryPoint" class="org.springframework.security.ui.cas.CasProcessingFilterEntryPoint">
	  <property name="loginUrl" value="https://localhost:9443/cas/login"/>
	  <property name="serviceProperties" ref="serviceProperties"/>
	</bean>
 
	 <!-- defines which roles are allowed to access http resources -->
    <bean id="filterInvocationInterceptor" class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="accessDecisionManager" ref="accessDecisionManager"/>
        <property name="objectDefinitionSource">
            <value>
                PATTERN_TYPE_APACHE_ANT
                /**=ROLE_ANONYMOUS
            </value>
        </property>
    </bean>
 
 
    <!-- hooks up CAS ticket validator and user details loader -->
    <bean id="authenticationManager" class="org.springframework.security.providers.ProviderManager">
        <property name="providers">
            <list>
                <ref bean="casAuthenticationProvider"/>
            </list>
        </property>
    </bean>
 
 
    <!-- supporting class for filterInvocationInterceptor -->
    <bean id="accessDecisionManager" class="org.springframework.security.vote.AffirmativeBased">
        <property name="allowIfAllAbstainDecisions" value="false"/>
        <property name="decisionVoters">
            <list>
                <ref local="roleVoter"/>
            </list>
        </property>
    </bean>
 
    <bean id="roleVoter" class="org.springframework.security.vote.RoleVoter">
        <property name="rolePrefix" value="ROLE"/>
    </bean>
 
	<!--  Which Application is using the CAS Service -->
	<bean id="serviceProperties" class="org.springframework.security.ui.cas.ServiceProperties">
 
		<property name="service" value="http://localhost:8080/AppServer/j_spring_cas_security_check"/>
	    <property name="sendRenew" value="false"/>
    </bean>
 
 
    <!-- handles a logout request from the CAS server -->
    <bean id="casSingleSignOutFilter" class="org.jasig.cas.client.session.SingleSignOutFilter"/>
 
 
    <bean id="casProcessingFilter" class="org.springframework.security.ui.cas.CasProcessingFilter">
	  <security:custom-filter after="CAS_PROCESSING_FILTER"/>
	  <property name="authenticationManager" ref="authenticationManager"/>
	  <property name="authenticationFailureUrl" value="/jsp/accessdenied.html"/>
	  <property name="alwaysUseDefaultTargetUrl" value="false"/>
	  <property name="defaultTargetUrl" value="/"/>
	</bean>
 
 
   	<bean id="casAuthenticationProvider" class="org.springframework.security.providers.cas.CasAuthenticationProvider">
    	<property name="userDetailsService" ref="userDao"/>
    	<property name="serviceProperties" ref="serviceProperties" />
    	<property name="ticketValidator">
	      	<bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
		        <constructor-arg index="0" value="https://localhost:9443/cas" />
	       	</bean>
    	</property>
    	<property name="key" value="casAuthProvider"/>
  	</bean>
 
	 <!-- Invoked when the user clicks logout -->
    <bean id="logoutFilter" class="org.springframework.security.ui.logout.LogoutFilter">
        <!-- URL redirected to after logout success -->
        <constructor-arg value="https://localhost:9443/cas/logout"/>
        <constructor-arg>
            <list>
                <bean class="org.springframework.security.ui.logout.SecurityContextLogoutHandler">
                    <property name="invalidateHttpSession" value="false"/>
                </bean>
            </list>
        </constructor-arg>
    </bean>
 
	 <!-- Log failed authentication attempts to commons-logging -->
    <bean id="loggerListener" class="org.springframework.security.event.authentication.LoggerListener"/>
 
    <bean id="httpSessionContextIntegrationFilter"
          class="org.springframework.security.context.HttpSessionContextIntegrationFilter"/>
 
    <bean id="securityContextHolderAwareRequestFilter"
          class="org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter"/>
 
 
</beans>