# File lib/casclient/frameworks/rails/filter.rb, line 13
          def filter(controller)
            raise "Cannot use the CASClient filter because it has not yet been configured." if config.nil?
            
            last_st = controller.session[:cas_last_valid_ticket]
            
            if single_sign_out(controller)
              controller.send(:render, :text => "CAS Single-Sign-Out request intercepted.")
              return false 
            end

            st = read_ticket(controller)
            
            is_new_session = true
            
            if st && last_st && 
                last_st.ticket == st.ticket && 
                last_st.service == st.service
              # warn() rather than info() because we really shouldn't be re-validating the same ticket. 
              # The only situation where this is acceptable is if the user manually does a refresh and 
              # the same ticket happens to be in the URL.
              log.warn("Re-using previously validated ticket since the ticket id and service are the same.")
              st = last_st
              is_new_session = false
            elsif last_st &&
                !config[:authenticate_on_every_request] && 
                controller.session[client.username_session_key]
              # Re-use the previous ticket if the user already has a local CAS session (i.e. if they were already
              # previously authenticated for this service). This is to prevent redirection to the CAS server on every
              # request.
              # This behaviour can be disabled (so that every request is routed through the CAS server) by setting
              # the :authenticate_on_every_request config option to false.
              log.debug "Existing local CAS session detected for #{controller.session[client.username_session_key].inspect}. "+
                "Previous ticket #{last_st.ticket.inspect} will be re-used."
              st = last_st
              is_new_session = false
            end
            
            if st
              client.validate_service_ticket(st) unless st.has_been_validated?
              vr = st.response
              
              if st.is_valid?
                if is_new_session
                  log.info("Ticket #{st.ticket.inspect} for service #{st.service.inspect} belonging to user #{vr.user.inspect} is VALID.")
                  controller.session[client.username_session_key] = vr.user.dup
                  controller.session[client.extra_attributes_session_key] = HashWithIndifferentAccess.new(vr.extra_attributes.dup)
                  
                  if vr.extra_attributes
                    log.debug("Extra user attributes provided along with ticket #{st.ticket.inspect}: #{vr.extra_attributes.inspect}.")
                  end
                  
                  # RubyCAS-Client 1.x used :casfilteruser as it's username session key,
                  # so we need to set this here to ensure compatibility with configurations
                  # built around the old client.
                  controller.session[:casfilteruser] = vr.user
                  
                  if config[:enable_single_sign_out]
                    f = store_service_session_lookup(st, controller.session.session_id)
                    log.debug("Wrote service session lookup file to #{f.inspect} with session id #{controller.session.session_id.inspect}.")
                  end
                end
              
                # Store the ticket in the session to avoid re-validating the same service
                # ticket with the CAS server.
                controller.session[:cas_last_valid_ticket] = st
                
                if vr.pgt_iou
                  unless controller.session[:cas_pgt] && controller.session[:cas_pgt].ticket && controller.session[:cas_pgt].iou == vr.pgt_iou
                    log.info("Receipt has a proxy-granting ticket IOU. Attempting to retrieve the proxy-granting ticket...")
                    pgt = client.retrieve_proxy_granting_ticket(vr.pgt_iou)

                    if pgt
                      log.debug("Got PGT #{pgt.ticket.inspect} for PGT IOU #{pgt.iou.inspect}. This will be stored in the session.")
                      controller.session[:cas_pgt] = pgt
                      # For backwards compatibility with RubyCAS-Client 1.x configurations...
                      controller.session[:casfilterpgt] = pgt
                    else
                      log.error("Failed to retrieve a PGT for PGT IOU #{vr.pgt_iou}!")
                    end
                  else
                    log.info("PGT is present in session and PGT IOU #{vr.pgt_iou} matches the saved PGT IOU.  Not retrieving new PGT.")
                  end

                end
                
                return true
              else
                log.warn("Ticket #{st.ticket.inspect} failed validation -- #{vr.failure_code}: #{vr.failure_message}")
                redirect_to_cas_for_authentication(controller)
                return false
              end
            else
              if returning_from_gateway?(controller)
                log.info "Returning from CAS gateway without authentication."
                
                if use_gatewaying?
                  log.info "This CAS client is configured to use gatewaying, so we will permit the user to continue without authentication."
                  return true
                else
                  log.warn "The CAS client is NOT configured to allow gatewaying, yet this request was gatewayed. Something is not right!"
                end
              end
              
              redirect_to_cas_for_authentication(controller)
              return false
            end
          end