diff --git a/README.md b/README.md index fecde5a..96aa979 100644 --- a/README.md +++ b/README.md @@ -41,14 +41,19 @@ $ rails db:migrate ### Private Key -You will need to generate a unique private key per application. +This gem signs the generated [JWT (JSON Web Tokens)](https://jwt.io/) using a +private key that should exist at the path `lib/oidc_provider_key.pem` in your +Rails application. + +You can pass its passphrase using the `OIDC_PROVIDER_KEY_PASSPHRASE` environment +variable. + +This gem provide a convenient way of generating one if you need it by running : ```bash -$ ssh-keygen +$ rails oidc_provider:generate_key ``` -Due to Docker Composes' lack of support for multiline `.env` variables, put a passphrase on it. Then add the key to your application at `lib/oidc_provider_key.pem` and add the passphrase as an environment variables in your application: `ENV["OIDC_PROVIDER_KEY_PASSPHRASE"]`. - # Testing Visit: https://demo.c2id.com/oidc-client/ diff --git a/app/models/oidc_provider/id_token.rb b/app/models/oidc_provider/id_token.rb index 72f1696..a690354 100644 --- a/app/models/oidc_provider/id_token.rb +++ b/app/models/oidc_provider/id_token.rb @@ -1,5 +1,9 @@ +# frozen_string_literal: true + module OIDCProvider class IdToken < ApplicationRecord + PASSPHRASE_ENV_VAR = 'OIDC_PROVIDER_KEY_PASSPHRASE' + belongs_to :authorization attribute :expires_at, :datetime, default: -> { 1.hour.from_now } @@ -24,8 +28,19 @@ def to_jwt private class << self + def config + { + issuer: OIDCProvider.issuer, + jwk_set: JSON::JWK::Set.new(public_jwk) + } + end + + def oidc_provider_key_path + Rails.root.join("lib/oidc_provider_key.pem") + end + def key_pair - @key_pair ||= OpenSSL::PKey::RSA.new(File.read(Rails.root.join("lib/oidc_provider_key.pem")), ENV["OIDC_PROVIDER_KEY_PASSPHRASE"]) + @key_pair ||= OpenSSL::PKey::RSA.new(File.read(oidc_provider_key_path), ENV[PASSPHRASE_ENV_VAR]) end def private_jwk @@ -35,13 +50,6 @@ def private_jwk def public_jwk JSON::JWK.new key_pair.public_key end - - def config - { - issuer: OIDCProvider.issuer, - jwk_set: JSON::JWK::Set.new(public_jwk) - } - end end end end diff --git a/lib/oidc_provider.rb b/lib/oidc_provider.rb index 8823413..66cddf6 100644 --- a/lib/oidc_provider.rb +++ b/lib/oidc_provider.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "openid_connect" require "oidc_provider/engine" diff --git a/lib/oidc_provider/engine.rb b/lib/oidc_provider/engine.rb index 0374145..1660028 100644 --- a/lib/oidc_provider/engine.rb +++ b/lib/oidc_provider/engine.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rack/oauth2' module OIDCProvider diff --git a/lib/tasks/oidc_provider.rake b/lib/tasks/oidc_provider.rake new file mode 100644 index 0000000..96adfdb --- /dev/null +++ b/lib/tasks/oidc_provider.rake @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +namespace :oidc_provider do + desc 'Generate the lib/oidc_provider_key.pem key file' + task generate_key: :environment do + key_filepath = OIDCProvider::IdToken.oidc_provider_key_path + + File.exist?(key_filepath) && raise("ERROR: A key file already exists at #{key_filepath}.") + + passphrase_env_var = OIDCProvider::IdToken::PASSPHRASE_ENV_VAR + + pass_phrase = ENV.fetch(passphrase_env_var, '') + + if pass_phrase == '' + puts "\033[33mWARNING: You haven't defined a passphrase to be used to " \ + 'generate the new key which is concidered as insecured. You can ' \ + "do it by setting the #{passphrase_env_var} environment variable " \ + "and re-run this task.\033[0m" + + raise + end + + key_file_content = OpenSSL::PKey::RSA.new(2048).export( + OpenSSL::Cipher.new('AES-128-CBC'), + pass_phrase + ) + + File.write(key_filepath, key_file_content) + FileUtils.chmod(0_600, key_filepath) + + puts "SUCCESS: A new key file has been created at #{key_filepath}." + end +end diff --git a/lib/tasks/openid/connect/provider_tasks.rake b/lib/tasks/openid/connect/provider_tasks.rake deleted file mode 100644 index 53e2983..0000000 --- a/lib/tasks/openid/connect/provider_tasks.rake +++ /dev/null @@ -1,4 +0,0 @@ -# desc "Explaining what the task does" -# task :openid_connect_provider do -# # Task goes here -# end