Class: Aker::Cas::RackProxyCallback

Inherits:
Object
  • Object
show all
Defined in:
lib/aker/cas/rack_proxy_callback.rb

Overview

Rack code for handling the PGT callback part of the CAS proxy authentication protocol. The class itself is middleware; it can also generate an endpoint.

Behavior

As middleware, this class intercepts and handles two paths and passes all other requests down the chain. The paths are:

  • /receive_pgt: implements the PGT callback process per section 2.5.4 of the CAS protocol.
  • /retrieve_pgt: allows an application to retrieve the PGT for a PGTIOU. The PGTIOU is returned to the application as part of the CAS ticket validation process. It should be passed to /receive_pgt as the pgtIou query parameter. Note that a given PGT may only be retrieved once.

As a full rack app, it handles the same two paths and returns 404 Not Found for all other requests.

Middleware vs. Application

It is only appropriate to use the class as middleware in a multithreaded or multiprocessing deployment. If your application only has one executor at a time, using this class as middleware will cause a deadlock during CAS authentication.

Based on

This class was heavily influenced by CasProxyCallbackController in rubycas-client. That class has approximately the same behavior, but is Rails-specific.

Constant Summary

RETRIEVE_PATH =
"/retrieve_pgt"
RECEIVE_PATH =
"/receive_pgt"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, options = {}) ⇒ RackProxyCallback

Create a new instance of the middleware.

Parameters:

  • app (#call)

    the next rack application in the chain.

  • options (Hash) (defaults to: {})

Options Hash (options):

  • :store (String)

    the file where the middleware will store the received PGTs until they are retrieved.



53
54
55
56
57
# File 'lib/aker/cas/rack_proxy_callback.rb', line 53

def initialize(app, options={})
  @app = app
  @store_filename = options.delete(:store) or
    raise "Please specify a filename for the PGT store"
end

Class Method Details

.application(options = {}) ⇒ #call

Creates a rack application which responds as described in the class overview.

Parameters:

  • options (Hash) (defaults to: {})

    the same options that you can pass to #initialize.

Returns:

  • (#call)

    a full rack application



80
81
82
83
84
85
# File 'lib/aker/cas/rack_proxy_callback.rb', line 80

def self.application(options={})
  app = lambda { |env|
    [404, { "Content-Type" => "text/plain" }, ["Unknown resource #{env['PATH_INFO']}"]]
  }
  RackProxyCallback.new(app, options)
end

Instance Method Details

#call(env) ⇒ Array

Handles a single request in the manner specified in the class overview.

Parameters:

  • env (Hash)

    the rack environment for the request.

Returns:

  • (Array)

    an appropriate rack response.



66
67
68
69
70
# File 'lib/aker/cas/rack_proxy_callback.rb', line 66

def call(env)
  return receive(env) if env["PATH_INFO"] == RECEIVE_PATH
  return retrieve(env) if env["PATH_INFO"] == RETRIEVE_PATH
  @app.call(env)
end