Skip to content

Commit cb0c46a

Browse files
committed
Add expires_at, to match OmniAuth auth schema
OmniAuth's [Auth Hash Schema] should return an expires_at field as a timestamp, but this gem returns expires_in. For compatibility with other oauth2 omniauth providers, we should also return expires_at. I'm not sure if the best place to fix it is here or upstream, in OpenIDConnect::AccessToken. On the one hand, the oauth2 gem handles it in OAuth2::AccessToken. On the other hand, the omniauth strategy is the only place we can ensure minimal latency between the server response and expires_at computation. I chose here. 🙂 [Auth Hash Schema]: https://github.com/omniauth/omniauth/wiki/Auth-Hash-Schema n.b. I would have assumed that "timestamp" in the schema meant a Time object, but all of the gems that inherit from `omniauth-oauth2` return Time#to_i, which is also appropriate.
1 parent 147b0ab commit cb0c46a

File tree

2 files changed

+16
-2
lines changed

2 files changed

+16
-2
lines changed

lib/omniauth/strategies/openid_connect.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class OpenIDConnect # rubocop:disable Metrics/ClassLength
6565
},
6666
code_challenge_method: 'S256',
6767
}
68+
option :expires_latency # seconds taken from credentials expires_at
6869

6970
def uid
7071
user_info.raw_attributes[options.uid_field.to_sym] || user_info.sub
@@ -95,6 +96,7 @@ def uid
9596
token: access_token.access_token,
9697
refresh_token: access_token.refresh_token,
9798
expires_in: access_token.expires_in,
99+
expires_at: @access_token_expires_at,
98100
scope: access_token.scope,
99101
}
100102
end
@@ -262,6 +264,11 @@ def access_token
262264
@access_token = client.access_token!(token_request_params)
263265
verify_id_token!(@access_token.id_token) if configured_response_type == 'code'
264266

267+
if @access_token.expires_in
268+
@access_token_expires_at = Time.now.to_i + @access_token.expires_in
269+
@access_token_expires_at -= options.expires_latency if options.expires_latency
270+
end
271+
265272
@access_token
266273
end
267274

test/lib/omniauth/strategies/openid_connect_test.rb

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,7 @@ def test_credentials
522522
strategy.options.issuer = 'example.com'
523523
strategy.options.client_signing_alg = :RS256
524524
strategy.options.client_jwk_signing_key = jwks.to_json
525+
strategy.options.expires_latency = 60
525526

526527
id_token = stub('OpenIDConnect::ResponseObject::IdToken')
527528
id_token.stubs(:verify!).returns(true)
@@ -530,14 +531,20 @@ def test_credentials
530531
access_token = stub('OpenIDConnect::AccessToken')
531532
access_token.stubs(:access_token).returns(SecureRandom.hex(16))
532533
access_token.stubs(:refresh_token).returns(SecureRandom.hex(16))
533-
access_token.stubs(:expires_in).returns(Time.now)
534+
access_token.stubs(:expires_in).returns(3599)
534535
access_token.stubs(:scope).returns('openidconnect')
535536
access_token.stubs(:id_token).returns(jwt.to_s)
536537

537538
client.expects(:access_token!).returns(access_token)
538539
access_token.expects(:refresh_token).returns(access_token.refresh_token)
539540
access_token.expects(:expires_in).returns(access_token.expires_in)
540541

542+
start = Time.now.to_i + access_token.expires_in - 60
543+
creds = strategy.credentials
544+
stop = Time.now.to_i + access_token.expires_in - 60
545+
expires_at = creds.delete(:expires_at)
546+
assert_includes start..stop, expires_at
547+
541548
assert_equal(
542549
{
543550
id_token: access_token.id_token,
@@ -546,7 +553,7 @@ def test_credentials
546553
expires_in: access_token.expires_in,
547554
scope: access_token.scope,
548555
},
549-
strategy.credentials
556+
creds
550557
)
551558
end
552559

0 commit comments

Comments
 (0)