Module: Picnic::Authentication::Cas

Defined in:
lib/picnic/authentication.rb

Overview

Picnic::Authentication::Cas provides basic CAS (Central Authentication System) authentication for your Camping app.

To learn more about CAS, see rubycas-client.googlecode.com and www.ja-sig.org/products/cas.

The module defines a service method that intercepts every request to check for CAS authentication. If the user has already been authenticated, the request proceeds as normal and the authenticated user’s username is made available under <tt>@state. Otherwise the request is redirected to your CAS server for authentication.

Getting Started

To activate CAS authentication for your application:

  1. Picnic-fy your Camping app (e.g: Camping.goes :your_app; YourApp.picnic!)

  2. Call YourApp.authenticate_using :cas.

  3. In your app’s configuration YAML file add something like this:

    authentication:
       cas_base_url: https://login.example.com/cas
    

    Where the value for </tt>cas_base_url</tt> is the URL of your CAS server.

  4. That’s it. Now whenever a user tries to access any of your controller’s actions, the request will be checked for CAS authentication. If the user is authenticated, their username is availabe in @state. Note that there is currently no way to apply CAS authentication only to certain controllers or actions. When enabled, CAS authentication applies to your entire application, except for items placed in the /public subdirectory (CSS files, JavaScripts, images, etc.). The public directory does not require CAS authentication, so anyone can access its contents.

Defined Under Namespace

Modules: Session

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.append_features(mod) ⇒ Object

For some reason the Module#included callback is just not working for me, so I had to resort to overriding append_features(). If anyone has any ideas why, please let me know!



152
153
154
155
156
157
158
159
160
# File 'lib/picnic/authentication.rb', line 152

def self.append_features(mod)
  super
  
  require 'camping/db'
  require 'camping/session'
  
  $: << File.dirname(File.expand_path(__FILE__))+"/../../../rubycas-client2/lib" # for development
  require 'rubycas-client'
end

.included(mod) ⇒ Object



191
192
193
194
195
# File 'lib/picnic/authentication.rb', line 191

def self.included(mod)
  mod.module_eval do
    include Cas::Session
  end
end

Instance Method Details

#service(*a) ⇒ Object



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/picnic/authentication.rb', line 197

def service(*a)
  $LOG.debug "Running CAS filter for request #{a.inspect}..."
  
  if @env['PATH_INFO'] =~ /^\/public\/.*/
    $LOG.debug "Access to items in /public subdirectory does not require CAS authentication."
    return super(*a)
  end
  if @state[:cas_username]
    $LOG.debug "Local CAS session exists for user #{@state[:cas_username]}."
    return super(*a)
  end
          
  client = CASClient::Client.new($CONF[:authentication].merge(:logger => $LOG))
  
  ticket = @input[:ticket]
  
   = client.(read_service_url(@env))
  
  if ticket
    if ticket =~ /^PT-/
      st = CASClient::ProxyTicket.new(ticket, read_service_url(@env), @input[:renew])
    else
      st = CASClient::ServiceTicket.new(ticket, read_service_url(@env), @input[:renew])
    end
    
    $LOG.debug "Got CAS ticket: #{st.inspect}"
    
    client.validate_service_ticket(st)
    if st.is_valid?
      $LOG.info "CAS ticket #{st.ticket.inspect} is valid. Opening local CAS session for user #{st.response.user.inspect}."
      @state[:cas_username] = st.response.user
      return super(*a)
    else
      $LOG.warn "CAS ticket #{st.ticket.inspect} is INVALID. Redirecting back to CAS server at #{.inspect} for authentication."
      @state[:cas_username] = nil
      redirect 
      s = self
    end
  else
    $LOG.info "User is unauthenticated and no CAS ticket found. Redirecting to CAS server at #{.inspect} for authentication."
    @state[:cas_username] = nil
    redirect 
    s = self
  end
  s
end