rodauth-oauth 1.6.7 → 1.7.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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 86f6ed47ccab8da1af7b8be2bd1929e24c12f1fd6fa959a5edfdee273bd0b70d
|
|
4
|
+
data.tar.gz: 10e0c26c907bfb5027ce2f77d67f4a85135cae1bf487a33c0847914084423896
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8564ff9e316d23f319b3f26746175971c0ac5d027f50ceade63728aaddd5013edf8b36ab9547be421525e15856234a69505c69c0cfa8176f24a770e7817b9a2e
|
|
7
|
+
data.tar.gz: d1e4d2f419de9dda4eafb7d91d320e3cbc80eae5ab511ad45ab5f52c4ec38f7b0c8c18b8154fd743f53b87028d77f789278530235ab336d0ee638a6b3f80f73f
|
data/README.md
CHANGED
|
@@ -55,6 +55,7 @@ This gem implements the following RFCs and features of OAuth:
|
|
|
55
55
|
* `oauth_dynamic_client_registration` - [Dynamic Client Registration Protocol](https://datatracker.ietf.org/doc/html/rfc7591) and [Dynamic Client Registration Management](https://www.rfc-editor.org/rfc/rfc7592);
|
|
56
56
|
* OAuth application and token management dashboards;
|
|
57
57
|
* The recommendations for [Native Apps](https://www.rfc-editor.org/rfc/rfc8252);
|
|
58
|
+
* `oauth_client_id_metadata_document` - [Client ID Metadata Document](https://datatracker.ietf.org/doc/draft-ietf-oauth-client-id-metadata-document/);
|
|
58
59
|
|
|
59
60
|
It also implements several components of [OpenID Connect](https://openid.net/connect/) on top of the OAuth features it provides, including:
|
|
60
61
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# 1.7.0
|
|
2
|
+
|
|
3
|
+
## Features
|
|
4
|
+
|
|
5
|
+
### Client ID Metadata Document Support
|
|
6
|
+
|
|
7
|
+
`rodauth-oauth` supports the Client ID Metadata Document Standard (also known as CIMD), via the `oauth_client_id_metadata_document` feature. In a nutshell, this provides a way by which a Client Application can identify itself to the authorization server, without prior dynamic client registration or other existing registration.
|
|
8
|
+
|
|
9
|
+
More info about the feature [in the docs](https://gitlab.com/os85/rodauth-oauth/-/wikis/Client-ID-Metadata-Document).
|
|
@@ -9,7 +9,8 @@ class CreateRodauthOauth < ActiveRecord::Migration<%= migration_version %>
|
|
|
9
9
|
t.string :redirect_uri, null: false
|
|
10
10
|
t.string :client_id, null: false, index: { unique: true }
|
|
11
11
|
# change `:null` contraints to false if you want to support confidential clients only, and
|
|
12
|
-
# no scheme relying on JWT private keys advertised by the JWKs uri
|
|
12
|
+
# no scheme relying on JWT private keys advertised by the JWKs uri; keep this as true if
|
|
13
|
+
# supporting public clients or CIMD.
|
|
13
14
|
t.string :client_secret, null: true, index: { unique: true }
|
|
14
15
|
t.string :registration_access_token, null: true
|
|
15
16
|
t.string :scopes, null: false
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rodauth/oauth"
|
|
4
|
+
|
|
5
|
+
module Rodauth
|
|
6
|
+
Feature.define(:oauth_client_id_metadata_document, :OauthClientIdMetadataDocument) do
|
|
7
|
+
depends :oauth_authorize_base
|
|
8
|
+
|
|
9
|
+
DOT_SEGMENTS = %w[. ..].freeze
|
|
10
|
+
|
|
11
|
+
FORBIDDEN_TOKEN_AUTH_METHODS = %w[client_secret_post client_secret_basic client_secret_jwt].freeze
|
|
12
|
+
|
|
13
|
+
def oauth_application
|
|
14
|
+
super || begin
|
|
15
|
+
client_id = param_or_nil("client_id")
|
|
16
|
+
|
|
17
|
+
return unless client_id && valid_cimd_url?(client_id)
|
|
18
|
+
|
|
19
|
+
return if @client_id_lookup
|
|
20
|
+
|
|
21
|
+
@client_id_lookup = true
|
|
22
|
+
|
|
23
|
+
client_metadata = http_request_with_cache(client_id)
|
|
24
|
+
|
|
25
|
+
# 4.1 The client metadata document MUST contain a client_id property whose value MUST match the URL of the document
|
|
26
|
+
redirect_response_error("invalid_request") unless client_metadata[:client_id] == client_id
|
|
27
|
+
|
|
28
|
+
validate_client_metadata_document(client_metadata)
|
|
29
|
+
|
|
30
|
+
@client_id_lookup = false
|
|
31
|
+
|
|
32
|
+
# rewrite metadata params into column names
|
|
33
|
+
create_params = Hash[
|
|
34
|
+
client_metadata.map do |k, v|
|
|
35
|
+
k = case k
|
|
36
|
+
when :redirect_uris
|
|
37
|
+
v = v.join(" ")
|
|
38
|
+
:redirect_uri
|
|
39
|
+
when :client_uri
|
|
40
|
+
:homepage_url
|
|
41
|
+
when :grant_types, :response_types, :contacts
|
|
42
|
+
v = v.join(" ")
|
|
43
|
+
k
|
|
44
|
+
when :client_name
|
|
45
|
+
:name
|
|
46
|
+
when :scope
|
|
47
|
+
:scopes
|
|
48
|
+
else
|
|
49
|
+
k
|
|
50
|
+
end
|
|
51
|
+
[send(:"oauth_applications_#{k}_column"), v]
|
|
52
|
+
end
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
applications_ds = db[oauth_applications_table]
|
|
56
|
+
application_columns = applications_ds.columns
|
|
57
|
+
|
|
58
|
+
create_params.delete_if { |k, _| !application_columns.include?(k) }
|
|
59
|
+
@oauth_application = __insert_or_do_nothing_and_return__(
|
|
60
|
+
applications_ds,
|
|
61
|
+
oauth_applications_id_column,
|
|
62
|
+
[oauth_applications_client_id_column],
|
|
63
|
+
create_params
|
|
64
|
+
)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
private
|
|
69
|
+
|
|
70
|
+
def valid_cimd_url?(client_id)
|
|
71
|
+
return false unless URI::DEFAULT_PARSER.make_regexp("https").match?(client_id)
|
|
72
|
+
|
|
73
|
+
uri = URI(client_id)
|
|
74
|
+
# Client identifier URLs MUST have an "https" scheme,
|
|
75
|
+
return false unless uri.scheme == "https"
|
|
76
|
+
|
|
77
|
+
path = uri.path
|
|
78
|
+
# MUST contain a path component
|
|
79
|
+
return false if path.empty? ||
|
|
80
|
+
# MUST NOT contain single-dot or double-dot path segments
|
|
81
|
+
path.split("/").any? { |seg| DOT_SEGMENTS.include?(seg) }
|
|
82
|
+
|
|
83
|
+
return false unless
|
|
84
|
+
# MUST NOT contain a fragment component
|
|
85
|
+
(uri.fragment.nil? || uri.fragment.empty?) &&
|
|
86
|
+
# MUST NOT contain a username or password Client identifier URLs
|
|
87
|
+
(uri.userinfo.nil? || uri.userinfo.empty?) &&
|
|
88
|
+
# SHOULD NOT include a query string component, and MAY contain a port.
|
|
89
|
+
(uri.query.nil? || uri.query.empty?)
|
|
90
|
+
|
|
91
|
+
true
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def validate_client_metadata_document(metadata)
|
|
95
|
+
if (token_endpoint_auth_method = metadata[:token_endpoint_auth_method]) &&
|
|
96
|
+
FORBIDDEN_TOKEN_AUTH_METHODS.include?(token_endpoint_auth_method)
|
|
97
|
+
# the token_endpoint_auth_method property MUST NOT include client_secret_post, client_secret_basic, client_secret_jwt,
|
|
98
|
+
# or any other method based around a shared symmetric secret
|
|
99
|
+
redirect_response_error("invalid_request")
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# the client_secret and client_secret_expires_at properties MUST NOT be used
|
|
103
|
+
redirect_response_error("invalid_request") if metadata.key?(:client_secret) || metadata.key?(:client_secret_expires_at)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def oauth_server_metadata_body(*)
|
|
107
|
+
super.tap do |data|
|
|
108
|
+
data[:client_id_metadata_document_supported] = true
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rodauth-oauth
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tiago Cardoso
|
|
@@ -95,6 +95,7 @@ extra_rdoc_files:
|
|
|
95
95
|
- doc/release_notes/1_6_5.md
|
|
96
96
|
- doc/release_notes/1_6_6.md
|
|
97
97
|
- doc/release_notes/1_6_7.md
|
|
98
|
+
- doc/release_notes/1_7_0.md
|
|
98
99
|
files:
|
|
99
100
|
- CHANGELOG.md
|
|
100
101
|
- LICENSE.txt
|
|
@@ -148,6 +149,7 @@ files:
|
|
|
148
149
|
- doc/release_notes/1_6_5.md
|
|
149
150
|
- doc/release_notes/1_6_6.md
|
|
150
151
|
- doc/release_notes/1_6_7.md
|
|
152
|
+
- doc/release_notes/1_7_0.md
|
|
151
153
|
- lib/generators/rodauth/oauth/install_generator.rb
|
|
152
154
|
- lib/generators/rodauth/oauth/templates/app/models/oauth_application.rb
|
|
153
155
|
- lib/generators/rodauth/oauth/templates/app/models/oauth_grant.rb
|
|
@@ -169,6 +171,7 @@ files:
|
|
|
169
171
|
- lib/rodauth/features/oauth_authorize_base.rb
|
|
170
172
|
- lib/rodauth/features/oauth_base.rb
|
|
171
173
|
- lib/rodauth/features/oauth_client_credentials_grant.rb
|
|
174
|
+
- lib/rodauth/features/oauth_client_id_metadata_document.rb
|
|
172
175
|
- lib/rodauth/features/oauth_device_code_grant.rb
|
|
173
176
|
- lib/rodauth/features/oauth_dpop.rb
|
|
174
177
|
- lib/rodauth/features/oauth_dynamic_client_registration.rb
|