IntegrateBackends
Ruby on Rails integration
Authenticate via Olympus in a Rails backend
Use omniauth-oauth2 or directly the oauth2 gem.
Setup
Gemfile:
gem 'omniauth'
gem 'omniauth-oauth2'
gem 'jwt'Middleware config
config/initializers/omniauth.rb:
Rails.application.config.middleware.use OmniAuth::Builder do
provider :oauth2, ENV['OLYMPUS_CLIENT_ID'], ENV['OLYMPUS_CLIENT_SECRET'],
client_options: {
site: ENV['OLYMPUS_ISSUER'],
authorize_url: '/oauth2/auth',
token_url: '/oauth2/token'
},
scope: 'openid profile email',
pkce: true,
name: 'olympus'
endCallback controller
app/controllers/sessions_controller.rb:
class SessionsController < ApplicationController
def create
auth = request.env['omniauth.auth']
# auth.credentials.token => access token
# auth.info.email, etc.
user = User.find_or_create_by(olympus_sub: auth.uid) do |u|
u.email = auth.info.email
end
session[:user_id] = user.id
redirect_to root_path
end
def destroy
session.clear
redirect_to ENV['OLYMPUS_LOGOUT_URL']
end
endconfig/routes.rb:
get '/auth/:provider/callback', to: 'sessions#create'
post '/logout', to: 'sessions#destroy'Token introspection for APIs
If your Rails app also serves an API consumed by mobile / SPA clients:
class Api::BaseController < ActionController::API
before_action :authenticate_token
private
def authenticate_token
token = request.headers['Authorization']&.split(' ')&.last
return render json: { error: 'unauthorized' }, status: 401 unless token
introspect = HTTParty.post(
"#{ENV['OLYMPUS_ISSUER']}/admin/oauth2/introspect",
basic_auth: { username: ENV['HYDRA_ADMIN_USER'], password: ENV['HYDRA_ADMIN_PASS'] },
body: { token: token }
)
if introspect['active']
@current_user = User.find_by(olympus_sub: introspect['sub'])
else
render json: { error: 'inactive' }, status: 401
end
end
end