Skip to content

Instantly share code, notes, and snippets.

@lowang
Created January 21, 2021 09:32
Show Gist options
  • Save lowang/f4927ec035aead44b329bb6343a64e99 to your computer and use it in GitHub Desktop.
Save lowang/f4927ec035aead44b329bb6343a64e99 to your computer and use it in GitHub Desktop.
module CASApp
# CAS JWT Authentication
class JWTAuthenticatable < Devise::Strategies::Base
HEADER_KEY = 'HTTP_X_TOPTAL_AUTH'.freeze
HEADER_PREFIX = 'Bearer '.freeze
def valid?
header.present?
end
def authenticate!
@current_token = TokenData.new(JwtEncoder.for_cas.decode(token))
user = GlobalID::Locator.locate(@current_token.user_gid, only: User)
role = GlobalID::Locator.locate(@current_token.current_role_gid, only: Role)
if user && role
# Warden is only signing in user, signing in roles is our custom Authentication extension
# this workaround is setting proper role from token for further use
env['rack.session'][::Authentication::CURRENT_ROLE_KEY] = role.id
success! user
else
fail!
end
rescue JWT::DecodeError
fail! 'Invalid token'
end
private
def token
header.to_s.sub(HEADER_PREFIX, '')
end
def header
env[HEADER_KEY]
end
end
class TokenData
include ActiveData::Model
attribute :gid, String
attribute :full_name, String
attribute :email, String
attribute :user_gid, String
attribute :time_zone_name, String
attribute :tos_accepted, Boolean
attribute :current_role_gid, String
attribute :fake_session, Boolean
end
end
Warden::Strategies.add(:cas_jwt_token, CASApp::JWTAuthenticatable)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment