Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example how to use it with RS256 #4

Closed
paxti opened this issue Feb 3, 2017 · 4 comments
Closed

Example how to use it with RS256 #4

paxti opened this issue Feb 3, 2017 · 4 comments

Comments

@paxti
Copy link

paxti commented Feb 3, 2017

Hello,

New auth0.js v8 sends jwt signed with RS256 and I can't make it work with Knock. I've added

config.token_signature_algorithm = 'RS256'

and

config.token_public_key = key.public_key

into initializer but still no luck. Key seems to be correct, at least it works in jwt.io

I would be grateful for any help.

Best, Iurii

@chenkie
Copy link
Contributor

chenkie commented Feb 3, 2017

Hi @fungi-fungi, we're working on a revamp to this sample and the docs that go along with it. In the meantime, check out this open PR for some guidance on using RS256 #2

@mrrobby
Copy link

mrrobby commented Feb 3, 2017

@chenkie @fungi-fungi, I did a lot of work with this and have some working code allow you to toggle between RS256 and HS256, per controller, without the use of Knock. It's based on the work done in PR #2. It needs slight DRY refactoring, but I've been swamped and just de-prioritized it. It's not in in a public repo, but if you're in a hurry, I can try to get a PR going.

The primary motivation is I couldn't get Knock to work without a full User table, which to me, seems antithetical to having an external user store, especially in an API-only or microservice-type app. Instead, we create an ActiveModel object for user to achieve a @current_user object on an API call. You can populate that in an ActiveSupport::Concern on a successful decoding and you can use it in your controllers.

Then just build your decoder to be something like below (which includes a test case too):

require_relative 'base64_decoder'

class Rs256Decoder
  def self.decode(token)
    if Rails.env.test?
        @rsa_private = OpenSSL::PKey::RSA.new ENV.fetch("RSA_PRIVATE")
        @rsa_public = @rsa_private.public_key
        return JWT.decode(token, @rsa_public, true, # Verify the signature of this token
        {
          :algorithm => 'RS256',
          :iss => Rails.application.secrets.auth0_domain,
          :verify_iss => true,
          :aud => Rails.application.secrets.auth0_api_audience,
          :verify_aud => true
        })
    else
      return JWT.decode(token, nil, true, # Verify the signature of this token
      {
        :algorithm => 'RS256',
        :iss => Rails.application.secrets.auth0_domain,
        :verify_iss => true,
        :aud => Rails.application.secrets.auth0_api_audience,
        :verify_aud => true
      }) do |header|
        jwks_hash[header['kid']]
      end
    end
  end

  def self.jwks_hash
    jwks_raw = Net::HTTP.get URI(Rails.application.secrets.auth0_rsa_domain)
    jwks_keys = Array(JSON.parse(jwks_raw)['keys'])
    Hash[
      jwks_keys
      .map do |k|
        [
          k['kid'],
          OpenSSL::X509::Certificate.new(
            Base64.decode64(k['x5c'].first)
          ).public_key
        ]
      end
    ]
  end  
end

@paxti
Copy link
Author

paxti commented Feb 6, 2017

Thank you so much @chenkie @mrrobby this solved all my problems, I got myself way too focused on using Knock instead of looking for a more direct solution.

@mrrobby
Copy link

mrrobby commented Feb 6, 2017

Anytime! Sounds like we can close this one.

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

No branches or pull requests

3 participants