At the Forge - Integrating OpenID

 in
Integrate OpenID into any Rails application, using off-the-shelf libraries and a bit of custom code.
Storing User Information

When we display this form in our browser, the user has one option—namely, to sign in with OpenID by entering a URL. The action (create) that is invoked has to find the user's OpenID server and redirect to that server. In order to do this, we need an instance of OpenID::Consumer, an object defined by the ruby-openid gem. Because we will continue to need this, we can create it as an instance variable:

def openid_consumer
 if @openid_consumer.blank?
   @openid_consumer =
     OpenID::Consumer.new(session,
           OpenID::Store::Filesystem.new("#{RAILS_ROOT}/tmp/openid"))
 end

 return @openid_consumer
end

Notice that we're storing the OpenID information on the filesystem, in the tmp directory under the root of our Rails project directory. This is a bad idea when you have multiple Web servers, but is certainly good enough for a small or beginning site.

Now that we have a method named openid_consumer and an instance variable named @openid_consumer, we can implement the create action, to which our HTML form is going to be submitted:

def create
 # Get the OpenID parameter
 openid_url = params[:openid_url]

 # Make sure we got something
 if openid_url.blank?
   flash[:error] = "No OpenID was entered; try again"
   redirect_to :back
   return
 end

 # Get an OpenID response
 openid_response = openid_consumer.begin openid_url

 home_url = url_for :controller => "openid", :action => "index"
 complete_url = url_for :controller => "openid", :action => "complete"
 openid_redirect_url = openid_response.redirect_url(home_url, complete_url)
 redirect_to openid_redirect_url

 return
end

In other words, we get the user's OpenID URL, and we check that it wasn't blank. Then, we use our instance of OpenID::Consumer to begin the OpenID login process, using open_consumer.begin, passing it the user's OpenID URL. If all goes well, this returns an instance of SuccessRequest, which also hands us the URL to which we should redirect the user. (If the request fails, the response will be a subclass of OpenIDStatus.)

Completing the Login Process

When we send the user to the user's OpenID server, we have to provide two different URLs as arguments: one that we're calling home_url, and the other that we're calling complete_url. The former is the root URL of our site; typically, it'll be a top-level URL. The latter, complete_url, tells the OpenID server to which URL the user should be redirected after logging in. In both cases, I use the built-in Rails url_for method, which constructs a URL out of a controller and action name.

When the user returns from the OpenID server, it will be to the URL indicated in complete_url. This means we have to define our complete method as well:

def complete
 home_url = url_for :controller => "openid", :action => "index"
 complete_url = url_for :controller => "openid", :action => "complete"

 openid_response = openid_consumer.complete(params, complete_url)

 session[:openid] = openid_response.identity_url
 flash[:error] = "You have been logged in as '#{session[:openid]}'"
 redirect_to :action => "new"
 return
end

After defining home_url and complete_url once again, we invoke the complete method on our instance of OpenID::Consumer. If the response is good (and here we assume that it is, ignoring the possibility that we might have gotten an instance of OpenIDStatus back). Obviously, your real-life applications should include such a check.

Sure enough, when we put all this in place, it works! We can enter our user ID into the HTML form. We get verified by the user's OpenID server, even if that means another redirect. And, we get the user verified with basic information.

______________________

Webinar
One Click, Universal Protection: Implementing Centralized Security Policies on Linux Systems

As Linux continues to play an ever increasing role in corporate data centers and institutions, ensuring the integrity and protection of these systems must be a priority. With 60% of the world's websites and an increasing share of organization's mission-critical workloads running on Linux, failing to stop malware and other advanced threats on Linux can increasingly impact an organization's reputation and bottom line.

Learn More

Sponsored by Bit9

Webinar
Linux Backup and Recovery Webinar

Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.

In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.

Learn More

Sponsored by Storix