Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redirect loop with Grails Spring Security CAS plugin

I am working with a project involving CAS server works with other Spring-based projects using Single-Sign On (SSO), but I am receiving a redirect loop involving the Grails spring-security-cas plugin (version: ":spring-security-cas:2.0-RC1"). I've looked at the plugin's documentation. I know CAS redirect questions appear common, but I have yet to find a posting related to this type of situation. I am new-ish to the Grails and CAS worlds, so thank you in advance for any push in the right direction.

Accessing a secured page on the grails app initially redirects to the CAS server login page correctly, with the appropriate service parameter: https:// example.com:8443/cas/login?service=http:// example.com:8080/grailsapp/j_spring_cas_security_check

The problem occurs after the user logs in successfully and CAS redirects back to the service. The j_spring_cas_security_check in the grails app is redirecting back to the https://example.com:8443/cas login page, which sees the TGC and redirects back to the service j_spring_cas_security_check page, which redirects ad infinitum [until the browser gives the redirect loop error]. It also looks like new service tickets are getting created each iteration.

My Config.groovy has:

grails.plugin.springsecurity.cas.loginUri = /login
grails.plugin.springsecurity.cas.serviceUrl = http://example.com:8080/grailsapp/j_spring_cas_security_check
grails.plugin.springsecurity.cas.serverUrlPrefix = https://example.com:8443/cas
# we aren't using cas with proxy
# logout details not shown here

Unsuccessful attempts already tried based on other questions/answers:

  • I don't think the issue is with the cas server: when I go directly to another of the projects already using CAS they detect the ticket cookie and login just fine without the user having to authenticate again.
  • The SSL certificate is self-signed and already added to Java's cacert store. No SSLHandshake or Certificate-related exceptions, etc. occur.
  • It's not a bad credentials or proxy situation like question 19710841, but I've tried adding the /j_spring_cas_security_check to the Annotation staticRules anyways but get the same loop.

The cas server's logs include:

=============================================================
WHO: [username: sampleuser]
WHAT: supplied credentials: [username: sampleuser]
ACTION: AUTHENTICATION_SUCCESS
APPLICATION: CAS
WHEN: Fri Jan 03 23:52:41 GMT 2014
CLIENT IP ADDRESS: XXX.XXX.XXX.XXX
SERVER IP ADDRESS: example.com
=============================================================
=============================================================
WHO: [username: sampleuser]
WHAT: TGT-24-Rttmt5i5raWcV1Z5wZavVopigQc4xeIckEUfMKdG3EwEzI3LUI-cas.service
ACTION: TICKET_GRANTING_TICKET_CREATED
APPLICATION: CAS
WHEN: Fri Jan 03 23:52:41 GMT 2014
CLIENT IP ADDRESS: XXX.XXX.XXX.XXX
SERVER IP ADDRESS: example.com
=============================================================

INFO [org.jasig.cas.CentralAuthenticationServiceImpl] - <Granted service ticket [ST-77-cneJOIwmnoOdKqkscaiy-cas.service] for service [http://example.com:8080/grailsapp/j_spring_cas_security_check] for user [sampleuser]>

####### FIRST ITERATION OF LOOP BELOW #############

=============================================================
WHO: sampleuser
WHAT: ST-77-cneJOIwmnoOdKqkscaiy-cas.service for http://example.com:8080/grailsapp/j_spring_cas_security_check
ACTION: SERVICE_TICKET_CREATED
APPLICATION: CAS
WHEN: Fri Jan 03 23:52:41 GMT 2014
CLIENT IP ADDRESS: XXX.XXX.XXX.XXX
SERVER IP ADDRESS: example.com
=============================================================
=============================================================
WHO: audit:unknown
WHAT: ST-77-cneJOIwmnoOdKqkscaiy-cas.service
ACTION: SERVICE_TICKET_VALIDATED
APPLICATION: CAS
WHEN: Fri Jan 03 23:52:41 GMT 2014
CLIENT IP ADDRESS: 127.0.0.1
SERVER IP ADDRESS: example.com
=============================================================

DEBUG [org.jasig.cas.web.flow.InitialFlowSetupAction] - <Placing service in FlowScope: http://example.com:8080/grailsapp/j_spring_cas_security_check>
INFO [org.jasig.cas.CentralAuthenticationServiceImpl] - <Granted service ticket [ST-78-6qsbaVNNOess4VhGOQE4-cas.service] for service [http://example.com:8080/grailsapp/j_spring_cas_security_check] for user [sampleuser]>

####### SERVICE_TICKET_CREATED and SERVICE_TICKET_VALIDATED LOOP CONTINUES A FEW MORE TIMES BEFORE BROWSER GIVES UP #############
like image 532
Josito Avatar asked Oct 01 '22 23:10

Josito


2 Answers

In addition to overwriting UserDetailsService I had to configure filterProcessesUrl in Config.groovy

grails.plugin.springsecurity.cas.filterProcessesUrl = "/user/login" // same as uri part of serviceUrl
grails.plugin.springsecurity.cas.serviceUrl = "http://yoursite.com/user/login"

for CasAuthenticationFilter to kick in after authentication on CAS. Following are source code reference links:

You can also look at the source for CasAuthenticationFilter.java see the serviceTicketRequest and super.requiresAuthentication methods.

like image 94
Mayank Avatar answered Oct 13 '22 10:10

Mayank


The issue was that in the Grails client I did not create a userDetailsService. I implemented a custom class within Grails' services folder (See http://grails-plugins.github.io/grails-spring-security-core/guide/userDetailsService.html):

public class MyUserDetailsService implements UserDetailsService {
    // Required methods here
}

then referenced this in resources.groovy:

beans = {
    userDetailsService(MyUserDetailsService)
}
like image 38
Josito Avatar answered Oct 13 '22 09:10

Josito