Skip to main content
Skip table of contents

Ruby OpenID Connect example

This example illistrates how the openid_connect gem (https://github.com/nov/openid_connect) can be used to implement the OpenID connect Authorization Code Flow. Due to the wide variety of Ruby frameworks it has not been possible to provide detail at every step.

Goal in this example

Create a wrapper ruby module  using the openid_connect gem which will...

  1. Generate an authentication request
  2. Process the recieved (authentication) token code to obtain the users OpenID claims

You will then be able to use this module within you choosen ruby web framework, e.g Rails or Sinatra (http://rubyonrails.org/, http://www.sinatrarb.com/)

Instructions

  1. Install the required gem (how you do this will depend on your ruby framework) e.g

    RUBY
    gem install openid_connect
  2. Create the module file e.g oa_oidc_example.rb 

    RUBY
    module OpenAthensOIDCExample
    	class Worker
    		# 
    		# * +provider_uri+ - For OpenAthens this will be <code>https://connect.openathens.net</code>
    		# * +client_id+ - Obtain from the OpenAthens publisher dashboard
    		# * +secret+ - Obtain from the OpenAthens publisher dashboard
    		# * +redirect_uri+ - This is where the user will be returned to after successful authentication. 
    		#   You will need to implement this on your server (e.g <code>https://oidc-rp.example/redirect</code>)
    		#
    		def initialize(provider_uri, client_id, secret, redirect_uri)
    			@provider_uri = provider_uri
    			@client_id = client_id
    			@secret = secret
    			@redirect_uri = redirect_uri
    		end
    		# 
    		# * +nonce+ - Unique value associated with the request. Same value needs to be passed to the #redirect method (store in users session)
    		# Returns the authentication URL. Redirect users to authenticate.
    		#
    		def auth_uri(nonce)
    			authz_url = init_client.authorization_uri(
    				scope: [:profile, :email],
    				state: nonce,
    				nonce: nonce
    			)
    		end
    		#
    		# * +code+ - The code returned from the OP after successful user authentication.  
    
            # This will be available via the <code>querystring</code> when the user is return to <code>redirect_uri</code>.
    		# * +nonce+ - The same value use to call #auth_uri (e.g read from the user session - <code>session.delete(:nonce)</code>)
    		#
    		# Returns the userinfo <code>OpenIDConnect::ResponseObject::UserInfo</code>.  
            # Use <code>userinfo.raw_attributes</code> to access all the OpenId claims returned from the OpenAthens connect service.
    		#
    		def redirect (code, nonce)
    			client = init_client
    			#What we are expecting.		
    			expected = {:client_id => @client_id, :issuer => discover.issuer, :nonce => nonce}
    			#Get code from query string.
    			client.authorization_code = code
    			access_token = client.access_token! 
    			#Validate the access token.
    			id_token = OpenIDConnect::ResponseObject::IdToken.decode access_token.id_token, discover.jwks
    			id_token.verify! expected
    			#Read userinfo
    			user_info = access_token.userinfo!
    	  	end
    
    
    		private 
    		def init_client			
    			@client ||= OpenIDConnect::Client.new(
    				identifier:@client_id,
    				secret: @secret,
    				redirect_uri: @redirect_uri,
    				authorization_endpoint: discover.authorization_endpoint,
    				token_endpoint: discover.token_endpoint,
    				userinfo_endpoint: discover.userinfo_endpoint
    			)
    		end
    
    		def discover
    			@disco ||= OpenIDConnect::Discovery::Provider::Config.discover! @provider_uri
    		end 
    
    	end
    end
  3. Test your set up by implementing two handlers (pages) on your ruby server. E.g:

    1. login - This will invoke the auth_uri method and then redirect the user.

    2. redirect - This will invoke the redirect method.  On success you will be able to access the OpenID claims via the raw_attributes method on the returned object.



JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.