Skip to content

Commit dd9cc4f

Browse files
authored
Merge branch 'master' into fix/select_accont_without_owner
2 parents f539e01 + d9e9eac commit dd9cc4f

6 files changed

Lines changed: 67 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
- Please add here
44
- [#303] execute account selection even without owner
5+
- [#304] allow handle auth_time per grant
56

67
## v1.10.1 (2026-06-03)
78

lib/doorkeeper/openid_connect/config.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ def jws_private_key(*args)
5454
}
5555

5656
option :auth_time_from_session, default: nil
57+
option :auth_time_from_access_token, default: nil
5758

5859
option :reauthenticate_resource_owner, default: lambda { |*_|
5960
raise Errors::InvalidConfiguration, I18n.translate("doorkeeper.openid_connect.errors.messages.reauthenticate_resource_owner_not_configured")

lib/doorkeeper/openid_connect/id_token.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,13 @@ def issued_at
7878
end
7979

8080
def auth_time
81-
Doorkeeper::OpenidConnect.configuration.auth_time_from_resource_owner.call(@resource_owner).try(:to_i)
81+
config = Doorkeeper::OpenidConnect.configuration
82+
83+
if config.auth_time_from_access_token
84+
config.auth_time_from_access_token.call(@access_token).try(:to_i)
85+
else
86+
config.auth_time_from_resource_owner.call(@resource_owner).try(:to_i)
87+
end
8288
rescue Errors::InvalidConfiguration
8389
nil
8490
end

lib/generators/doorkeeper/openid_connect/templates/initializer.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,18 @@
5757
# session[:auth_time]
5858
# end
5959

60+
# Advanced:
61+
# If you store `auth_time` in a custom authentication context record linked
62+
# to the access token, you can configure a block like below to derive it
63+
# from the access token instead of `auth_time_from_resource_owner`.
64+
#
65+
# This allows you to track `auth_time` per grant instead of per user,
66+
# but requires more custom implementation on your part.
67+
#
68+
# auth_time_from_access_token do |access_token|
69+
# access_token.your_custom_authentication_context_record.auth_time
70+
# end
71+
6072
reauthenticate_resource_owner do |resource_owner, return_to|
6173
# Example implementation:
6274
# store_location_for resource_owner, return_to

spec/lib/config_spec.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,22 @@
112112
end
113113
end
114114

115+
describe "auth_time_from_access_token" do
116+
it "defaults to nil" do
117+
described_class.configure {}
118+
119+
expect(subject.auth_time_from_access_token).to be_nil
120+
end
121+
122+
it "sets the block that is accessible via auth_time_from_access_token" do
123+
block = proc {}
124+
described_class.configure do
125+
auth_time_from_access_token(&block)
126+
end
127+
expect(subject.auth_time_from_access_token).to eq(block)
128+
end
129+
end
130+
115131
describe "reauthenticate_resource_owner" do
116132
it "sets the block that is accessible via reauthenticate_resource_owner" do
117133
block = proc {}

spec/lib/id_token_spec.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,36 @@
123123
end
124124
end
125125

126+
context "when auth_time_from_access_token is configured" do
127+
before do
128+
access_token.define_singleton_method(:auth_time_from_custom_mechanism) do
129+
@auth_time_from_custom_mechanism ||= 5.minutes.ago
130+
end
131+
132+
Doorkeeper::OpenidConnect.configure do
133+
issuer "dummy"
134+
135+
resource_owner_from_access_token do |access_token|
136+
User.find_by(id: access_token.resource_owner_id)
137+
end
138+
139+
auth_time_from_access_token do |access_token|
140+
access_token.auth_time_from_custom_mechanism
141+
end
142+
143+
subject do |resource_owner|
144+
resource_owner.id
145+
end
146+
end
147+
end
148+
149+
it "uses auth_time using auth_time_from_access_token" do
150+
expect { subject.claims }.not_to raise_error
151+
expect(subject.claims[:auth_time]).to eq access_token.auth_time_from_custom_mechanism.to_i
152+
expect(subject.as_json).to include(:auth_time)
153+
end
154+
end
155+
126156
context "when a custom claim collides with a protected registered claim" do
127157
before do
128158
Doorkeeper::OpenidConnect.configure do

0 commit comments

Comments
 (0)