# Referenzimplementierung für die nachträgliche Integration der OpenID-Unterstützung in eine # Relying Party anwendung # # Dieses Beispiel beruht auf dem Einsatz von Ruby on Rails ab Version 1.2 und folgenden Ruby Gems: # * ruby-openid (Version 2.0.4, http://www.openidenabled.com/ruby-openid/) # * ruby-yadis (Version 0.3.4) # # Neben der folgenden Implementierung eines Controllers, welcher die Möglichkeit bietet, ein bestehendes # Benutzerkonto mit einer OpenID zu verknüpfen und diese Verknüpfung auch wieder aufzuheben, müssen noch # weitere Teile dem Projekt hinzugefügt werden. # # Folgende Routes müssen in der Datei config/routes.rb ergänzt werden: # # map.with_options :controller => 'users' do |users| # users.add_openid 'users/add_openid', :action => 'add_openid' # users.associate_openid 'users/associate_openid', :action => 'associate_openid' # users.remove_openid 'users/remove_openid', :action => 'remove_openid' # end # # Folgende Migration muss ergänzt werden, um dem Benutzerpofil die Identity URL hinzuzufügen: # # class AddIdentityUrlToUsers < ActiveRecord::Migration # def self.up # add_column :users, :identity_url, :string # end # # def self.down # remove_column :users, :identity_url # end # end # # Mittels des folgenden Formulars kann der Benutzer beim Bearbeiten des Profils den Identifier angeben: # #

Ihre OpenID

# <% if @user.identity_url.blank? %> #

Ihr Benutzerkonto ist bisher mit keiner OpenID verbunden. Wenn Sie sich für die Anwendung zukünftig # mit ihrer OpenID anmelden wollen, dann klicken Sie den Button und bestätigen Sie die Anfrage.

# <% form_for :user, :url => { :action => 'add_openid' } do |f| %> # <%= image_submit_tag 'https://openid.tzi.de/images/login_button.png' %> # <% end %> # <% else %> #

Ihr Benutzerkonto ist mit aktuell mit folgender OpenID verbunden:
<%=h @user.identity_url %>

#

Wenn Sie diese Verbindung entfernen, ist es nicht mehr möglich,
sich per OpenID einzuloggen.

# <% form_for :user, :url => { :action => 'remove_openid' }, :html => { :method => :put } do |f| %> # <%= submit_tag 'Verbindung mit dieser OpenID entfernen' %> # <% end %> # # Das Formular enthält lediglich den Login-Buttons des OpenID-Servers vom Fachbereich 3 und startet # beim Abschicken den Verknüpfungsvorgang in der add_openid-Action des folgenden UsersControllers. # # ------------------------------------------------------------------------------------------------------------ require 'openid' # Einbinden der benötigten Bibliotheken aus den Gems require 'openid/store/filesystem' # Store fürs Speichern der OpenID-Transaktionsdaten require 'openid/consumer/discovery' # Yadis Discovery Funktionalitäten class UsersController < ApplicationController # Startet den Vorgang zum Hinzufügen einer OpenID def add_openid begin oidreq = openid_consumer.begin(identity_provider) rescue OpenID::OpenIDError => e flash[:error] = "Der OpenID-Server #{identity_provider} konnte nicht kontaktiert werden.
#{e}" redirect_to :action => 'edit' return end redirect_to oidreq.redirect_url(home_url, url_for(:action => 'associate_openid')) end # Verknüpft ein Benutzerkonto mit einer OpenID def associate_openid parameters = params.reject{ |k,v| request.path_parameters[k] } oidresp = openid_consumer.complete(parameters, url_for({})) if oidresp && oidresp.endpoint && oidresp.endpoint.server_url.match(identity_provider) if oidresp.status == OpenID::Consumer::SUCCESS current_user.update_attribute(:identity_url, oidresp.display_identifier) flash[:notice] = "Ihr Benutzerkontos wurde mit der OpenID #{oidresp.display_identifier} verbunden." else flash[:error] = "Die Verknüpfung mit der OpenID ist fehlgeschlagen." end else flash[:error] = "Es werden nur OpenIDs von #{identity_provider} akzeptiert." end redirect_to :action => 'edit' end # Entfernt die Verknüpfung des Benutzerkontos mit einer OpenID def remove_openid current_user.update_attribute(:identity_url, nil) flash[:notice] = "Die Verknüpfung Ihres Benutzerkontos mit der OpenID wurde aufgehoben." redirect_to :action => 'edit' end private # Die Daten der OpenID-Transaktionen werden in diesem Fall im Dateisystem abgelegt. # Sollte dies nicht erwünscht sein, kann auch ein anderer Store-Mechanismus angegeben # werden - näheres dazu findet sich in der Dokumentation des ruby-openid Gems unter: # http://www.openidenabled.com/ruby-openid/ def openid_consumer store = OpenID::Store::Filesystem.new("#{RAILS_ROOT}/tmp/openid") @openid_consumer ||= OpenID::Consumer.new(session, store) end # Die URL des Identity Providers - in diesem Fall die URL # des OpenID-Servers des Fachbereich 3 der Uni Bremen def identity_provider 'https://openid.tzi.de/' end end