NUBIC / aker

A flexible security framework for Rack (and Rails) apps. Good for integration with legacy systems, CAS SSO (including proxying), machine and interactive authentication, and much more.
MIT License
1 stars 2 forks source link

Aker-using applications ought to be able to host their own proxy callbacks #27

Open hannahwhy opened 11 years ago

hannahwhy commented 11 years ago

The CAS 2 protocol only mandates a single URL for sending PGTs to services using CAS proxy tickets. (See section 2.5.4.)

Aker's CAS support adds a second URL for retrieving PGTs. This was modelled off of rubycas-server and rubycas-client behavior, but it is not required by the CAS protocol. It was added in the Old Days when making Rails applications handle multiple requests in development and test modes was tricky.

Things are different now: Rails multithreading is no longer a joke and rubycas-client has done away with the PGT retrieval URL. Aker's CAS support ought to be able to join this brave new era of protocol compliance.

However, we want to usher in that era without unrest, which means that the current ways of Aker must be preserved. To this end, I want to make changes that achieve the following three goals:

  1. Applications using the existing CAS URL trifecta will continue to work as-is.
  2. Applications that only specify a CAS base URL (and use the CAS mode/authority) will use CAS for authentication, but will not support CAS proxy authentication. (This is also the current behavior.)
  3. Applications may choose to host their own CAS proxy callback.

For goal 3, I think it is best to add new Rack middleware that

  1. installs a proxy callback into a Rack app's middleware stack
  2. for requests that result in a redirect to the CAS login URL, appends a URL that leads to the receive_pgt endpoint installed by the callback

This will work with the CAS PGT protocol as follows:

  1. A user makes a request to a CAS-protected endpoint.
  2. A redirect to the CAS login URL is generated. This includes a redirect URL.
  3. The middleware described above appends a URL for the CAS proxy callback hosted by the application.
  4. The user logs into CAS.
  5. The CAS server deposits a PGT and PGTIOU into the callback.
  6. The user is redirected to the URL sent in (2) with a service ticket.
  7. The CAS client checks the service ticket via /serviceValidate.
  8. The CAS server returns 200, along with the PGTIOU generated in (5).
  9. The Aker CAS mode sends a message to the middleware (presumably accessible in the Rack environment) to get the PGT for the PGTIOU.

In code:

# Aker configuration
Aker.configure do
  ui_mode :cas
  api_mode :cas_proxy
  # this is all you need
  cas_parameters base_url: 'https://cas.example.edu'
end

# Webapp (Sinatra-ish here, but so long as there's Rack it doesn't matter)
Aker::Rack.use_in(self)
use Aker::Cas::SelfHostedRackProxyCallback  # name's terrible, we can come up with a better one

get '/' do
   # etc.
end
hannahwhy commented 11 years ago

A couple of notes on this hypothetical Aker::Cas::SelfHostedRackProxyCallback:

  1. It should be able to act as an application, as it may be convenient to mount it in e.g. Rails apps.
  2. As a middleware, it should accept a configurable path.
  3. The PGT store should also be configurable. The PStore-based one in use by Aker::Cas::RackProxyCallback is probably fine to start with, but any key-value store would be usable. (For example, a global Ruby hash with synchronized writing would probably work out fine for single-process applications.)