Skip to content

Instantly share code, notes, and snippets.

@levibrown
Last active March 4, 2021 17:40
Show Gist options
  • Save levibrown/e9f186389b41849bf380a63b0fa5ed7a to your computer and use it in GitHub Desktop.
Save levibrown/e9f186389b41849bf380a63b0fa5ed7a to your computer and use it in GitHub Desktop.

For handling authentication with Auth0 we will continue to use our existing gems (g5_authenticatable and g5_authenticatable_api.) The g5_authentication_client gem will be removed as it is no longer applicable. In most cases we should only need to install g5_authenticatable. Moving forward with v2 these codebases will be in the g5search github org and once fully released we can depricate or remove the code in the G5 org.

Installing

  1. Update gem version
  source 'https://gem.fury.io/g5dev/' do
    gem 'g5_authenticatable', '~> 2.0.6.pre.alpha.gem'
  end
  1. Change g5_authenticatable engine namespace to mount G5Authenticatable::Engine => '/'
  • for new install this will be added with the generator rails g g5_authenticatable:install
  1. add env vars to secrets.yml file
development:
  secret_key_base: ...
  auth0_client_id: <%= ENV["AUTH0_CLIENT_ID"] %>
  auth0_client_secret: <%= ENV["AUTH0_CLIENT_SECRET"] %>
  auth0_domain: <%= ENV["AUTH0_DOMAIN"] %>
  1. changes for machine to machine token
  • Update instances of G5AuthenticationClient::Client.username_pw_access_token to G5Authenticatable::Api::Services::AuthClient::fetch_access_token(audience)
  • Update instances of G5AuthenticationClient::AuthToken::do_with_username_pw_access_token to G5Authenticatable::Api::AuthToken::do_with_access_token(audience)
  • Example:
class Something
  include G5Authenticatable::Api::AuthToken
    
  def send_payload
    # see here for available app names https://www.g5devops.com/apps/
    audience = 'app-name'
    
    @response = do_with_access_token(audience) do |token|
    HTTParty.post(endpoint,
                  body:    { example: @payload }.to_json,
                  headers: { 'authorization' => "Bearer #{token}" })
    end
  end
end
  • As conversions are made to fetch the token with the new access_token method, we will also need to adjust how we are sending the token. The gem currently still allows the token to be passed by either an Authorization header, access_token query parameter or from warden, but we could potentially run in to issues of hitting the max url length if we continue using the query parameter. For example, this could be a problem in the vendor lead feed, where there are also location urn query params. It is recommended that we convert to using the Authorization header.

Misc.

  1. access tokens that were previouly accessed from the TokenValidator class can now be accessed from the TokenInfo class.
  • example G5AuthenticatableApi::Services::TokenValidator.new(params, request.headers).access_token is now G5AuthenticatableApi::Services::TokenInfo.new(params, request.headers).access_token
@ryanmcadler
Copy link

For M2M support, maybe we'll want to incorporate:

  • Update instances of G5AuthenticationClient::Client.username_pw_access_token to G5AuthenticatableApi::Services::AuthClient::fetch_access_token(audience)
  • Update instances of G5AuthenticationClient::Helpers::AuthToken::do_with_username_pw_access_token to G5AuthenticatableApi::Helpers::AuthToken::do_with_access_token(audience)

@crissmancd
Copy link

For testing apps using authenticatable, I found this helpful

  • to test API methods that are secured by auth, you need to use the auth_request shared context, Read Here
  • to test controller methods secured by auth, you need to use the auth_controller shared context, Read Here

@dpetersen
Copy link

As we're going through these apps, I'd like to make sure we think about the session store. The default session store in Rails is the cookie store. This works great for a lot of apps, but not for customer-facing apps. Years ago when we added granular permissions, the session for a size grew for users with many location assignments. It got so big that it went over the limit for a browser cookie's max size (and generated CookieOverflow errors in Rails, which sound delicious but aren't).

So we switched some apps to the activerecord-session_store gem. This adds a migration which adds a new table where sessions are stored, and the cookie just holds a key that can get their row back out of the database. But sessions expire and database rows don't. The README for the gem says you need to trim old sessions (and they provide a rake task), but we haven't done that. Apps like the IMC and NAE now have millions of rows for expired sessions.

As we're going through these apps, I'd like to make sure we evaluate something like the following:

Are customers logging into the application?

  • If yes, you need the activerecord-session_store gem. Continue on to the next question.
  • If not, you don't need the gem. Ensure it's not in the Gemfile. If it is in the Gemfile and was in use, reverse the installation process in the README. Ensure you generate a new migration to drop the old table.

Still have the gem? Ensure there is a daily job that clears out stale sessions!

  • If the app already has sidekiq, use (or install) sidekiq-cron and have a nightly job to trim the sessions. You can find the code for this in the rake task in the gem.
  • If you don't have sidekiq, talk to DevOps about creating a Kubernetes CronJob object to perform this task.

@dpetersen
Copy link

dpetersen commented Mar 3, 2021

I will add some more info about this later, but I ended up writing some automation for the session store trimming on GCP. Let's just ignore the session trimming stuff on AWS for now. On GCP it is a one-line change, but I need to document how developers can bump the ruby-web-service Helm chart themselves. We will take care of the session trimming on AWS apps when they migrate to GCP.

@ryanmcadler
Copy link

Namespaces have changed a bit on the G5AuthenticatableApi side a bit. The auth client is now G5Authenticatable::Api::Services::AuthClient and the auth token helper is now G5Authenticatable::Api::AuthToken.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment