diff --git a/lib/omniauth/strategies/openid_connect.rb b/lib/omniauth/strategies/openid_connect.rb index cc857876..7831101f 100644 --- a/lib/omniauth/strategies/openid_connect.rb +++ b/lib/omniauth/strategies/openid_connect.rb @@ -65,6 +65,7 @@ class OpenIDConnect # rubocop:disable Metrics/ClassLength }, code_challenge_method: 'S256', } + option :expires_latency # seconds taken from credentials expires_at def uid user_info.raw_attributes[options.uid_field.to_sym] || user_info.sub @@ -95,6 +96,7 @@ def uid token: access_token.access_token, refresh_token: access_token.refresh_token, expires_in: access_token.expires_in, + expires_at: @access_token_expires_at, scope: access_token.scope, } end @@ -262,6 +264,11 @@ def access_token @access_token = client.access_token!(token_request_params) verify_id_token!(@access_token.id_token) if configured_response_type == 'code' + if @access_token.expires_in + @access_token_expires_at = Time.now.to_i + @access_token.expires_in + @access_token_expires_at -= options.expires_latency if options.expires_latency + end + @access_token end diff --git a/test/lib/omniauth/strategies/openid_connect_test.rb b/test/lib/omniauth/strategies/openid_connect_test.rb index f49c5bd6..df98bf56 100644 --- a/test/lib/omniauth/strategies/openid_connect_test.rb +++ b/test/lib/omniauth/strategies/openid_connect_test.rb @@ -522,6 +522,7 @@ def test_credentials strategy.options.issuer = 'example.com' strategy.options.client_signing_alg = :RS256 strategy.options.client_jwk_signing_key = jwks.to_json + strategy.options.expires_latency = 60 id_token = stub('OpenIDConnect::ResponseObject::IdToken') id_token.stubs(:verify!).returns(true) @@ -530,7 +531,7 @@ def test_credentials access_token = stub('OpenIDConnect::AccessToken') access_token.stubs(:access_token).returns(SecureRandom.hex(16)) access_token.stubs(:refresh_token).returns(SecureRandom.hex(16)) - access_token.stubs(:expires_in).returns(Time.now) + access_token.stubs(:expires_in).returns(3599) access_token.stubs(:scope).returns('openidconnect') access_token.stubs(:id_token).returns(jwt.to_s) @@ -538,6 +539,12 @@ def test_credentials access_token.expects(:refresh_token).returns(access_token.refresh_token) access_token.expects(:expires_in).returns(access_token.expires_in) + start = Time.now.to_i + access_token.expires_in - 60 + creds = strategy.credentials + stop = Time.now.to_i + access_token.expires_in - 60 + expires_at = creds.delete(:expires_at) + assert_includes start..stop, expires_at + assert_equal( { id_token: access_token.id_token, @@ -546,7 +553,7 @@ def test_credentials expires_in: access_token.expires_in, scope: access_token.scope, }, - strategy.credentials + creds ) end