Class Rack::Auth::OpenID
In: lib/rack/auth/openid.rb
Parent: AbstractHandler

Rack::Auth::OpenID provides a simple method for permitting openid based logins. It requires the ruby-openid lib from janrain to operate, as well as some method of session management of a Hash type.

After a transaction, the response status object is stored in the environment at rack.auth.openid.status, which can be used in the followup block or in a wrapping application to accomplish additional data maniipulation.

NOTE: Due to the amount of data that ruby-openid stores in the session, Rack::Session::Cookie may fault.

A hash of data is stored in the session hash at the key of :openid. The fully canonicalized identity url is stored within at ‘identity’. Extension data from ‘openid.sreg.nickname’ would be stored as { ‘nickname’ => value }.

NOTE: To my knowledge there is no collision at this point from storage of this manner, if there is please let me know so I may adjust this app to cope.

Methods

auth_fail   bad_login   call   check   finish   new   no_session  

Constants

OIDStore = ::OpenID::MemoryStore.new   Required for ruby-openid

Public Class methods

A Hash of options is taken as it‘s single initializing argument. String keys are taken to be openid protocol extension namespaces.

  For example: 'sreg' => { 'required' => # 'nickname' }

Other keys are taken as options for Rack::Auth::OpenID, normally Symbols. Only :return is required. :trust is highly recommended to be set.

  • :return defines the url to return to after the client authenticates with the openid service provider. Should point to where this app is mounted. (ex: ‘mysite.com/openid’)
  • :trust defines the url identifying the site they are actually logging into. (ex: ‘mysite.com/’)
  • :session_key defines the key to the session hash in the env. (by default it uses ‘rack.session’)

[Source]

    # File lib/rack/auth/openid.rb, line 48
48:       def initialize(options={})
49:         raise ArgumentError, 'No return url provided.'  unless options[:return]
50:         warn  'No trust url provided.'  unless options[:trust]
51:         options[:trust] ||= options[:return]
52: 
53:         @options  = {
54:           :session_key => 'rack.session'
55:         }.merge(options)
56:       end

Public Instance methods

[Source]

     # File lib/rack/auth/openid.rb, line 101
101:       def auth_fail
102:         @options.
103:           fetch :auth_fail, [500, {'Content-Type'=>'text/plain'},'Foreign server failure.']
104:       end

[Source]

     # File lib/rack/auth/openid.rb, line 105
105:       def bad_login
106:         @options.
107:           fetch :bad_login, [401, {'Content-Type'=>'text/plain'},'Identification has failed.']
108:       end

[Source]

    # File lib/rack/auth/openid.rb, line 58
58:       def call(env)
59:         request = Rack::Request.new env
60:         return no_session unless session = request.env[@options[:session_key]]
61:         resp = if request.GET['openid.mode']
62:                  finish session, request.GET, env
63:                elsif request.GET['openid_url']
64:                  check session, request.GET['openid_url'], env
65:                else
66:                  bad_request
67:                end
68:       end

[Source]

    # File lib/rack/auth/openid.rb, line 70
70:       def check(session, oid_url, env)
71:         consumer = ::OpenID::Consumer.new session, OIDStore
72:         oid = consumer.begin oid_url
73:         return auth_fail unless oid.status == ::OpenID::SUCCESS
74:         @options.each do |ns,s|
75:           next unless ns.is_a? String
76:           s.each {|k,v| oid.add_extension_arg(ns, k, v) }
77:         end
78:         r_url = @options.fetch :return do |k| request.url end
79:         t_url = @options.fetch :trust
80:         env['rack.auth.openid.status'] = oid
81:         return 303, {'Location'=>oid.redirect_url( t_url, r_url )}, []
82:       end

[Source]

    # File lib/rack/auth/openid.rb, line 84
84:       def finish(session, params, env)
85:         consumer = ::OpenID::Consumer.new session, OIDStore
86:         oid = consumer.complete params
87:         return bad_login unless oid.status == ::OpenID::SUCCESS
88:         session[:openid] = {'identity' => oid.identity_url}
89:         @options.each do |ns,s|
90:           next unless ns.is_a? String
91:           oid.extension_response(ns).each{|k,v| session[k]=v }
92:         end
93:         env['rack.auth.openid.status'] = oid
94:         return 303, {'Location'=>@options[:trust]}, []
95:       end

[Source]

     # File lib/rack/auth/openid.rb, line 97
 97:       def no_session
 98:         @options.
 99:           fetch :no_session, [500,{'Content-Type'=>'text/plain'},'No session available.']
100:       end

[Validate]