oidc_provider 0.3.10 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +9 -4
- data/app/controllers/oidc_provider/authorizations_controller.rb +30 -13
- data/app/models/oidc_provider/id_token.rb +16 -8
- data/lib/oidc_provider/client.rb +4 -2
- data/lib/oidc_provider/engine.rb +2 -0
- data/lib/oidc_provider/token_endpoint.rb +25 -12
- data/lib/oidc_provider/version.rb +1 -1
- data/lib/oidc_provider.rb +2 -0
- data/lib/tasks/oidc_provider.rake +33 -0
- metadata +3 -3
- data/lib/tasks/openid/connect/provider_tasks.rake +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 29ccfbd4c57f22b63424ddbd7998bde94566c24e06721b43bfa5b07df0852ef6
|
4
|
+
data.tar.gz: fdeaa21ebbc146987ed9547988d4f7d59449a8dae6609477e72f1f78b47e7f91
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 82cd93fa057ecf8522d3ae4754360e202da2e102a9ee4b8ac8d52cbfa2df6da8a86532de765cf52ddea63080b182f9605c37c87db8097066ac019b6091e70812
|
7
|
+
data.tar.gz: 5a8cd740d69fb544665b7262ccb8124d4ce51791ca052495b12369b01a5d8b40d4eabf6d0efc2a0b469086a8123d52ad898821083838d6d80e862be475262409
|
data/README.md
CHANGED
@@ -41,14 +41,19 @@ $ rails db:migrate
|
|
41
41
|
|
42
42
|
### Private Key
|
43
43
|
|
44
|
-
|
44
|
+
This gem signs the generated [JWT (JSON Web Tokens)](https://jwt.io/) using a
|
45
|
+
private key that should exist at the path `lib/oidc_provider_key.pem` in your
|
46
|
+
Rails application.
|
47
|
+
|
48
|
+
You can pass its passphrase using the `OIDC_PROVIDER_KEY_PASSPHRASE` environment
|
49
|
+
variable.
|
50
|
+
|
51
|
+
This gem provide a convenient way of generating one if you need it by running :
|
45
52
|
|
46
53
|
```bash
|
47
|
-
$
|
54
|
+
$ rails oidc_provider:generate_key
|
48
55
|
```
|
49
56
|
|
50
|
-
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"]`.
|
51
|
-
|
52
57
|
# Testing
|
53
58
|
|
54
59
|
Visit: https://demo.c2id.com/oidc-client/
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module OIDCProvider
|
2
4
|
class AuthorizationsController < ApplicationController
|
3
5
|
include Concerns::ConnectEndpoint
|
@@ -5,16 +7,13 @@ module OIDCProvider
|
|
5
7
|
before_action :require_oauth_request
|
6
8
|
before_action :require_response_type_code
|
7
9
|
before_action :require_client
|
10
|
+
before_action :reset_login_if_necessary
|
8
11
|
before_action :require_authentication
|
9
12
|
|
10
13
|
def create
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
nonce: oauth_request.nonce,
|
15
|
-
scopes: requested_scopes,
|
16
|
-
account: oidc_current_account
|
17
|
-
)
|
14
|
+
Rails.logger.info "scopes: #{requested_scopes}"
|
15
|
+
|
16
|
+
authorization = build_authorization_with(requested_scopes)
|
18
17
|
|
19
18
|
oauth_response.code = authorization.code
|
20
19
|
oauth_response.redirect_uri = @redirect_uri
|
@@ -27,21 +26,39 @@ module OIDCProvider
|
|
27
26
|
|
28
27
|
private
|
29
28
|
|
29
|
+
def build_authorization_with(scopes)
|
30
|
+
Authorization.create(
|
31
|
+
client_id: @client.identifier,
|
32
|
+
nonce: oauth_request.nonce,
|
33
|
+
scopes: scopes,
|
34
|
+
account: oidc_current_account
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
30
38
|
def require_client
|
31
39
|
@client = ClientStore.new.find_by(identifier: oauth_request.client_id) or oauth_request.invalid_request! 'not a valid client'
|
32
|
-
@redirect_uri = oauth_request.verify_redirect_uri!
|
40
|
+
@redirect_uri = oauth_request.verify_redirect_uri! @client.redirect_uri
|
33
41
|
end
|
34
42
|
|
35
43
|
def requested_scopes
|
36
|
-
@requested_scopes ||= ([
|
44
|
+
@requested_scopes ||= (['openid'] + OIDCProvider.supported_scopes.map(&:name)) & oauth_request.scope
|
37
45
|
end
|
38
46
|
helper_method :requested_scopes
|
39
47
|
|
40
48
|
def require_response_type_code
|
41
|
-
|
42
|
-
|
49
|
+
return if oauth_request.response_type == :code
|
50
|
+
|
51
|
+
oauth_request.unsupported_response_type!
|
52
|
+
end
|
53
|
+
|
54
|
+
def reset_login_if_necessary
|
55
|
+
if params[:prompt] == "login"
|
56
|
+
# A `prompt=login` param means that we must prompt the user for sign in.
|
57
|
+
# So we will forcibly sign out the user here and then redirect them so they
|
58
|
+
# don't get redirected back to the url that contains `prompt=login`
|
59
|
+
unauthenticate!
|
60
|
+
redirect_to url_for(request.query_parameters.except(:prompt))
|
43
61
|
end
|
44
62
|
end
|
45
63
|
end
|
46
|
-
|
47
|
-
end
|
64
|
+
end
|
@@ -1,5 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module OIDCProvider
|
2
4
|
class IdToken < ApplicationRecord
|
5
|
+
PASSPHRASE_ENV_VAR = 'OIDC_PROVIDER_KEY_PASSPHRASE'
|
6
|
+
|
3
7
|
belongs_to :authorization
|
4
8
|
|
5
9
|
attribute :expires_at, :datetime, default: -> { 1.hour.from_now }
|
@@ -24,8 +28,19 @@ module OIDCProvider
|
|
24
28
|
private
|
25
29
|
|
26
30
|
class << self
|
31
|
+
def config
|
32
|
+
{
|
33
|
+
issuer: OIDCProvider.issuer,
|
34
|
+
jwk_set: JSON::JWK::Set.new(public_jwk)
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
def oidc_provider_key_path
|
39
|
+
Rails.root.join("lib/oidc_provider_key.pem")
|
40
|
+
end
|
41
|
+
|
27
42
|
def key_pair
|
28
|
-
@key_pair ||= OpenSSL::PKey::RSA.new(File.read(
|
43
|
+
@key_pair ||= OpenSSL::PKey::RSA.new(File.read(oidc_provider_key_path), ENV[PASSPHRASE_ENV_VAR])
|
29
44
|
end
|
30
45
|
|
31
46
|
def private_jwk
|
@@ -35,13 +50,6 @@ module OIDCProvider
|
|
35
50
|
def public_jwk
|
36
51
|
JSON::JWK.new key_pair.public_key
|
37
52
|
end
|
38
|
-
|
39
|
-
def config
|
40
|
-
{
|
41
|
-
issuer: OIDCProvider.issuer,
|
42
|
-
jwk_set: JSON::JWK::Set.new(public_jwk)
|
43
|
-
}
|
44
|
-
end
|
45
53
|
end
|
46
54
|
end
|
47
55
|
end
|
data/lib/oidc_provider/client.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module OIDCProvider
|
2
4
|
class Client
|
3
5
|
attr_accessor :identifier, :secret, :redirect_uri, :name
|
@@ -5,10 +7,10 @@ module OIDCProvider
|
|
5
7
|
def initialize(options = {})
|
6
8
|
@identifier = options[:identifier]
|
7
9
|
@secret = options[:secret]
|
8
|
-
@redirect_uri = options[:redirect_uri]
|
10
|
+
@redirect_uri = Array(options[:redirect_uri])
|
9
11
|
@name = options[:name]
|
10
12
|
end
|
11
13
|
end
|
12
14
|
end
|
13
15
|
|
14
|
-
require 'oidc_provider/client/builder'
|
16
|
+
require 'oidc_provider/client/builder'
|
data/lib/oidc_provider/engine.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module OIDCProvider
|
2
4
|
class TokenEndpoint
|
3
5
|
attr_accessor :app
|
6
|
+
|
4
7
|
delegate :call, to: :app
|
5
8
|
|
6
9
|
def initialize
|
@@ -8,26 +11,36 @@ module OIDCProvider
|
|
8
11
|
Rails.logger.info "Client ID: #{req.client_id}"
|
9
12
|
Rails.logger.info "Client secret: #{req.client_secret}"
|
10
13
|
Rails.logger.info "Redirect URI: #{req.redirect_uri}"
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
) || req.invalid_client!
|
16
|
-
|
17
|
-
Rails.logger.info "Found a client!"
|
14
|
+
|
15
|
+
client = find_valid_client_from(req) || req.invalid_client!
|
16
|
+
|
17
|
+
Rails.logger.info 'Found a client!'
|
18
18
|
|
19
19
|
case req.grant_type
|
20
20
|
when :authorization_code
|
21
|
-
Rails.logger.info
|
21
|
+
Rails.logger.info 'Grant type was an authorization code. Correct!'
|
22
22
|
authorization = Authorization.valid.where(client_id: client.identifier, code: req.code).first || req.invalid_grant!
|
23
|
-
Rails.logger.info
|
23
|
+
Rails.logger.info 'We found an authorization matching this code!'
|
24
24
|
res.access_token = authorization.access_token.to_bearer_token
|
25
|
-
res.id_token = authorization.id_token.to_jwt if authorization.scopes.include?(
|
25
|
+
res.id_token = authorization.id_token.to_jwt if authorization.scopes.include?('openid')
|
26
26
|
else
|
27
|
-
Rails.logger.info "Unsupported grant type"
|
27
|
+
Rails.logger.info "Unsupported grant type: #{req.grant_type.inspect}"
|
28
28
|
req.unsupported_grant_type!
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def find_valid_client_from(req)
|
36
|
+
client = ClientStore.new.find_by(
|
37
|
+
identifier: req.client_id,
|
38
|
+
secret: req.client_secret
|
39
|
+
)
|
40
|
+
|
41
|
+
return nil unless client
|
42
|
+
|
43
|
+
client.redirect_uri.include?(req.redirect_uri) ? client : nil
|
44
|
+
end
|
32
45
|
end
|
33
|
-
end
|
46
|
+
end
|
data/lib/oidc_provider.rb
CHANGED
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
namespace :oidc_provider do
|
4
|
+
desc 'Generate the lib/oidc_provider_key.pem key file'
|
5
|
+
task generate_key: :environment do
|
6
|
+
key_filepath = OIDCProvider::IdToken.oidc_provider_key_path
|
7
|
+
|
8
|
+
File.exist?(key_filepath) && raise("ERROR: A key file already exists at #{key_filepath}.")
|
9
|
+
|
10
|
+
passphrase_env_var = OIDCProvider::IdToken::PASSPHRASE_ENV_VAR
|
11
|
+
|
12
|
+
pass_phrase = ENV.fetch(passphrase_env_var, '')
|
13
|
+
|
14
|
+
if pass_phrase == ''
|
15
|
+
puts "\033[33mWARNING: You haven't defined a passphrase to be used to " \
|
16
|
+
'generate the new key which is concidered as insecured. You can ' \
|
17
|
+
"do it by setting the #{passphrase_env_var} environment variable " \
|
18
|
+
"and re-run this task.\033[0m"
|
19
|
+
|
20
|
+
raise
|
21
|
+
end
|
22
|
+
|
23
|
+
key_file_content = OpenSSL::PKey::RSA.new(2048).export(
|
24
|
+
OpenSSL::Cipher.new('AES-128-CBC'),
|
25
|
+
pass_phrase
|
26
|
+
)
|
27
|
+
|
28
|
+
File.write(key_filepath, key_file_content)
|
29
|
+
FileUtils.chmod(0_600, key_filepath)
|
30
|
+
|
31
|
+
puts "SUCCESS: A new key file has been created at #{key_filepath}."
|
32
|
+
end
|
33
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oidc_provider
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- William Carey
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-09-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -73,7 +73,7 @@ files:
|
|
73
73
|
- lib/oidc_provider/token_endpoint.rb
|
74
74
|
- lib/oidc_provider/user_info_builder.rb
|
75
75
|
- lib/oidc_provider/version.rb
|
76
|
-
- lib/tasks/
|
76
|
+
- lib/tasks/oidc_provider.rake
|
77
77
|
homepage: https://github.com/brandnewbox/oidc_provider
|
78
78
|
licenses:
|
79
79
|
- MIT
|