Skip to content
This repository has been archived by the owner on Mar 22, 2021. It is now read-only.

How to reference public key in knock.rb (config.token_public_key) ? #148

Closed
jessecravens opened this issue Feb 26, 2017 · 14 comments
Closed

Comments

@jessecravens
Copy link

jessecravens commented Feb 26, 2017

I am trying to properly configure an app that uses auth0js v8.2.0 to use RS256. Since Auth0 is returning a token signed with RS256. I've debugged it down to here: jwt/ruby-jwt#115

One theory that I have is that my reference in config.token_public_key is improper.

Knock.setup do |config|
  config.token_audience = -> { Rails.application.secrets.auth0_client_id }
  config.token_secret_signature_key = -> { Rails.application.secrets.auth0_client_secret }
  config.token_public_key = ????
end

I've tried every which way I can think of, but this methodpublic_key.verify(OpenSSL::Digest.new(algorithm.sub('RS', 'sha')), signature, signing_input) continues to raise a no method error:

no method 'verify' for type String.

Does anyone have a working example?
Or is there something more fundamental that I am missing here?

@jessecravens
Copy link
Author

jessecravens commented Feb 26, 2017

I figured this out .. for anyone else stumped by this, here is my solution:

In secrets.yml:

development:
  secret_key_base: <secret>
  auth0_client_id: <secret>
  auth0_client_secret: <secret>
  auth0_rsa_domain: <link from AuthO : Clients > Advanced Settings > Endpoints > JSON Web Key Set

In knock.rb:

  jwks_raw = Net::HTTP.get URI(Rails.application.secrets.auth0_rsa_domain)
  jwks_keys = Array(JSON.parse(jwks_raw)['keys'])
  config.token_public_key = OpenSSL::X509::Certificate.new(Base64.decode64(jwks_keys[0]['x5c'].first)).public_key

@utilityboy
Copy link

@jessecravens thanks so much for tracking this down... hours lost here. I'm going to work up a PR to update the initializer with some comments

@maxigs
Copy link

maxigs commented Mar 15, 2017

Thanks @jessecravens, just saved me from setting the keyboard on fire here ;)

@Sashkan
Copy link

Sashkan commented Mar 24, 2017

@jessecravens, did you need to configure anything else in knock.rb ? I configured it just as you did, stil lgetting the

Filter chain halted as :authenticate_user rendered or redirected
Completed 401 Unauthorized in 0ms (ActiveRecord: 0.0ms)

I used jwt.io debugger to make sure everything was fine, and it is, signature is validated, therefore I guess the problem comes from my app configuration

@clemoberti
Copy link

Thank you so much @jessecravens. Spent hours trying to figure out what the problem was...

@Sashkan make sure you change this line in the knock.rb by
config.token_secret_signature_key = -> { Rails.application.secrets.auth0_client_secret }
as @sidevesh suggested.

Auth0 algorithm toggle is not working ATM so make sure that you use RS256 by default
config.token_signature_algorithm = 'RS256'

Should work fine after that 👍

@fightingtheboss
Copy link

Worth noting that #124 does this same thing, but via JSON::JWT. Introduces a new dependency to knock, but it works transparently, rather than having to generate a new cert just to interpret and decode the public key.

@mikeeus
Copy link

mikeeus commented Jul 3, 2017

Thanks @jessecravens! This was super frustrating, you're a life saver!

@Think4866
Copy link

Thanks @jessecravens! Your solution saved me a ton of headache!

@chandlervdw
Copy link

@Sashkan did you make progress? I'm stuck with the same piece, though this does give me back the PEM I need...

@romanos
Copy link

romanos commented Aug 16, 2017

How is this not part of the core README? It's a breaking change from prior behavior with Auth0...

@TomGroombridge
Copy link

@jessecravens YOU ARE A HERO!!!!

@henvo
Copy link

henvo commented Aug 23, 2018

I also encountered the same problem as described above:
no method 'verify' for type String
but I was not using Auth0 so I had no idea what @jessecravens is talking about.

I think the point that is missing in the description of config/initializers/knock.rb is that token_public_key needs to be of type OpenSSL::PKey::RSA. I passed the public key as a String.
But I got it working with:

config.token_public_key = OpenSSL::PKey::RSA.new(
  File.read('some_key.pub')
)

I think it would be better if knock was accepting a String and creates an OpenSSL::PKey from it internally.

@rankin
Copy link

rankin commented Feb 18, 2019

My man, thank you! This one was brutal.

@Flexicon
Copy link

@jessecravens I know this is old, but thank you so much! I was missing the OpenSSL::PKey::RSA bit and it was driving me insane!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests