Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Federating Oauth In Ruby

Federating Oauth In Ruby

Presentation given at Railsconf 2015 about a sane approach to federating Oauth in Rails by Lance Gleason of Polyglot Programming

Lance Gleason

April 21, 2015
Tweet

More Decks by Lance Gleason

Other Decks in Technology

Transcript

  1. XML

  2. resource_owner_authenticator do #could be a call to a central authentication

    service. @user = env[:clearance].current_user unless @user session[:return_to] = request.fullpath redirect_to(routes.sign_in_url) end @user end
  3. module OmniAuth module Strategies autoload :VulcanService, Rails.root.join('lib', 'strategies', 'vulcan_service') autoload

    :KlingonManager, Rails.root.join('lib', 'strategies', 'klingon_manager') autoload :Bieber, Rails.root.join('lib', 'strategies', 'beiber') end end Rails.application.config.middleware.use OmniAuth::Builder do provider :Vulcan, "#{APP_CONFIG['vulcan_url']}/login" provider :KlingonService, "#{APP_CONFIG['klingon_service_url']}/login" provider :BeiberManager, "#{APP_CONFIG['beiber_manager_url']}/login" provider :developer end
  4. require 'strategies/common' module OmniAuth module Strategies class VulcanService include Common

    include OmniAuth::Strategy args [:authentication_url] def request_phase # some request code to authenticate # live long and prosper end #todo: add checks to make sure the values returned here are valid def callback_phase request = Rack::Request.new env cookies = request.cookies response = Rack::Response.new cookie_monster = VulcanCookieMonster.new cookies common_vulcan_callback cookie_monster: cookie_monster, response: response, cookies: cookies end private def strategy_id 'comcast_tve' end end end end
  5. class ApplicationController < ActionController::API def check_authorization authorization = request.headers[‘Authorization'] if

    authorization party_response = HTTParty.get("#{APP_CONFIG['doorkeeper_service_url']}:#{ENV[DOORKEEPER_SERVICE_PORT']}/ check_key.json", query: {'signature' => Hancock.sign, 'oauth_token' => authorization}) parsed_response = party_response.parsed_response if parsed_response['user_key'] expires = Marshal.load(parsed_response['expires_at'].force_encoding('UTF-8')).to_json @user = { 'user_id' => parsed_response['user_id'], 'user_key' => parsed_response['user_key'], 'email' => parsed_response['email'], 'expires_at' => expires } else response.status = 401 render json: {authorized: false} and return end end else response.status = 401 render json: {authorized: false} and return end end end
  6. require 'redis' class ApplicationController < ActionController::API def check_authorization authorization =

    request.headers['Authorization'] if authorization redis = Redis.new(:host => ENV['REDIS_HOST'], :port => ENV['REDIS_PORT']) redis_user = redis.get(authorization) if redis_user != nil @user = JSON.parse(redis_user) expires_at = DateTime.parse(@user['expires_at']) end if !@user or expires_at < DateTime.now party_response = HTTParty.get("#{APP_CONFIG['doorkeeper_service_url']}:#{ENV['DOORKEEPER_SERVICE_PORT']}/check_key.json", query: {'signature' => Hancock.sign, 'oauth_token' => authorization}) parsed_response = party_response.parsed_response if parsed_response['user_key'] expires = Marshal.load(parsed_response['expires_at'].force_encoding('UTF-8')).to_json @user = { 'user_id' => parsed_response['user_id'], 'user_key' => parsed_response['user_key'], 'email' => parsed_response['email'], 'expires_at' => expires } redis.set authorization, @user.to_json else response.status = 401 render json: {authorized: false} and return end end else response.status = 401 render json: {authorized: false} and return end end end
  7. 97