Module: Sinatra::BrowserID
- Defined in:
- lib/sinatra/browserid.rb,
lib/sinatra/browserid/helpers.rb,
lib/sinatra/browserid/template.rb
Defined Under Namespace
Class Method Summary collapse
-
.registered(app) ⇒ Object
10 minutes We need to set a global :expires here because of github.com/grosser/cachy/issues/7.
Class Method Details
.registered(app) ⇒ Object
10 minutes We need to set a global :expires here because of github.com/grosser/cachy/issues/7
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/sinatra/browserid.rb', line 28 def self.registered(app) app.helpers BrowserID::Helpers app.set :browserid_url, "https://broker.portier.io" app.set :browserid_login_button, :red app.set :browserid_login_url, "/_browserid_login" app.set :browserid_button_class, "" app.set :browserid_button_text, "Log in" app.get '/_browserid_login' do end app.post '/_browserid_assert' do begin # Server checks signature # For that, fetch the public key from the LA instance (TODO: Do that beforehand for trusted instances, and generally cache the key) public_key_jwks_uri = Addressable::URI.parse(settings.browserid_url + '/keys.json') public_key_jwks = ::JSON.parse(URI.parse(public_key_jwks_uri).read) public_key = OpenSSL::PKey::RSA.new if public_key.respond_to? :set_key # We initially set n and d via the then new set_key function, as direct access to n and e is blocked for some ruby and openssl versions. # But with OpenSSL 3 this function throws an error, as keys are immutable now. Instead we have to generate the key directly with # the right params, as in https://github.com/railslove/epics/issues/138 sequence = [] # modulus: sequence << OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(UrlSafeBase64.decode64(public_key_jwks["keys"][0]["n"]), 2)) # exponent: sequence << OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(UrlSafeBase64.decode64(public_key_jwks["keys"][0]["e"]), 2)) public_key = OpenSSL::PKey::RSA.new(OpenSSL::ASN1::Sequence(sequence).to_der) else public_key.e = OpenSSL::BN.new UrlSafeBase64.decode64(public_key_jwks["keys"][0]["e"]), 2 public_key.n = OpenSSL::BN.new UrlSafeBase64.decode64(public_key_jwks["keys"][0]["n"]), 2 end id_token = JWT.decode params[:id_token], public_key, true, { :algorithm => 'RS256' } id_token = id_token[0] # Needs to make sure token is still valid if (id_token["iss"] == settings.browserid_url && id_token["aud"] == request.base_url.chomp('/') && id_token["exp"] > Time.now.to_i && id_token["email_verified"] && # nonce is really known to us Cachy.get(id_token["nonce"])) session[:browserid_email] = id_token['email'] Cachy.delete_key(id_token["nonce"]) session.delete(:nonce) # it's possible the session persisted if session['redirect_url'] redirect session['redirect_url'] else redirect "/" end else # Even when the token check failed the nonce has to be invalidated Cachy.delete_key(id_token["nonce"]) session.delete(:nonce) end rescue OpenURI::HTTPError => e puts "could not validate token: " + e.to_s end halt 403 end end |