{"action":"opened","issue":{"url":"https://api.github.com/repos/IdentityServer/IdentityServer3/issues/2460","labels_url":"https://api.github.com/repos/IdentityServer/IdentityServer3/issues/2460/labels{/name}","comments_url":"https://api.github.com/repos/IdentityServer/IdentityServer3/issues/2460/comments","events_url":"https://api.github.com/repos/IdentityServer/IdentityServer3/issues/2460/events","html_url":"https://github.com/IdentityServer/IdentityServer3/issues/2460","id":128130576,"number":2460,"title":"Refresh of access token extends lifetime of other access tokens","user":{"login":"urbanhusky","id":2065748,"avatar_url":"https://avatars.githubusercontent.com/u/2065748?v=3","gravatar_id":"","url":"https://api.github.com/users/urbanhusky","html_url":"https://github.com/urbanhusky","followers_url":"https://api.github.com/users/urbanhusky/followers","following_url":"https://api.github.com/users/urbanhusky/following{/other_user}","gists_url":"https://api.github.com/users/urbanhusky/gists{/gist_id}","starred_url":"https://api.github.com/users/urbanhusky/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/urbanhusky/subscriptions","organizations_url":"https://api.github.com/users/urbanhusky/orgs","repos_url":"https://api.github.com/users/urbanhusky/repos","events_url":"https://api.github.com/users/urbanhusky/events{/privacy}","received_events_url":"https://api.github.com/users/urbanhusky/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2016-01-22T10:52:14Z","updated_at":"2016-01-22T10:52:14Z","closed_at":null,"body":"Background:\r\nI've set up some sort of sliding expiration for access tokens because I need users to be logged out after a certain period of inactivity. I am aware that this would allow anyone with a valid token to retain access indefinitely as long as they keep querying our API.\r\nTo achieve this, I keep the refresh token as a claim in our ASP.NET MVC application (owin cookie authentication) and use it when I see that half of the lifetime of the token has been reached.\r\n\r\nIssue:\r\nRefreshing the token, i.e. requesting a new token by using the reference token (which is single use) yields a new access token with a new expiration date (=good). Querying the introspection endpoint now yields the new expiration date for the old token too (=bad).\r\n\r\nExample:\r\nThe initial token:\r\n```\r\ntoken b20199ad2144d730934b22da70cc493b\r\nexp\t1453455304\r\nnbf\t1453455244\r\nauth_time 1453455211\r\nrefresh 402d8e959a5f68131d5341c626d7aeb6 (transformed claim)\r\n```\r\n\r\nThe token after refresh:\r\n```\r\ntoken 3db6f9348bb496f8a3f723cd6c3f25ea\r\nexp\t1453455337\r\nnbf\t1453455277\r\nauth_time 1453455211\r\nrefresh 0e43f1a2e95986751b87b33e547211f7 (transformed claim)\r\n```\r\nThe claims I see on the Web API (IdentityServerBearerTokenAuthentication) changed when I access it with the old token:\r\n```\r\ntoken b20199ad2144d730934b22da70cc493b\r\nexp\t1453455337\r\nnbf\t1453455277\r\nauth_time 1453455211\r\n```\r\n\r\nThis change obviously comes from the identity server, since I see it in the log as well:\r\n```\r\n2016-01-22 10:34:37,106;[22];INFO;IdentityServer3.Core.Validation.TokenValidator;Token validation success\r\n{\r\n  \"ValidateLifetime\": true,\r\n  \"AccessTokenType\": \"Reference\",\r\n  \"TokenHandle\": \"b20199ad2144d730934b22da70cc493b\",\r\n  \"Claims\": {\r\n    \"aud\": \"https://localhost:44334/resources\",\r\n    \"iss\": \"https://localhost:44334\",\r\n    \"nbf\": \"1453455244\",\r\n    \"exp\": \"1453455304\",\r\n    \"client_id\": \"fooclient\",\r\n    \"tokenLifetime\": 60,\r\n    \"scope\": [\r\n      \"Foo\",\r\n      \"email\",\r\n      \"offline_access\",\r\n      \"openid\",\r\n      \"profile\",\r\n      \"roles\"\r\n    ],\r\n    \"sub\": \"Foo@bar.com\",\r\n    \"auth_time\": 1453455211,\r\n    \"idp\": \"idsrv\",\r\n    \"amr\": \"password\",\r\n    \"email\": \"Foo@bar.com\",\r\n    \"name\": \"Foo@bar.com\"\r\n  }\r\n};\r\n\r\n...\r\n\r\n2016-01-22 10:34:37,123;[21];INFO;IdentityServer3.Core.Validation.TokenRequestValidator;Token request validation success\r\n {\r\n  \"ClientId\": \"fooclient\",\r\n  \"ClientName\": \"foo name\",\r\n  \"GrantType\": \"refresh_token\",\r\n  \"RefreshToken\": \"402d8e959a5f68131d5341c626d7aeb6\",\r\n  \"Raw\": {\r\n    \"grant_type\": \"refresh_token\",\r\n    \"refresh_token\": \"402d8e959a5f68131d5341c626d7aeb6\",\r\n    \"client_id\": \"fooclient\",\r\n    \"client_secret\": \"foosecret\"\r\n  }\r\n};\r\n\r\n...\r\n\r\n2016-01-22 10:34:37,141;[22];INFO;IdentityServer3.Core.Validation.TokenValidator;Token validation success\r\n{\r\n  \"ValidateLifetime\": true,\r\n  \"AccessTokenType\": \"Reference\",\r\n  \"TokenHandle\": \"3db6f9348bb496f8a3f723cd6c3f25ea\",\r\n  \"Claims\": {\r\n    \"aud\": \"https://localhost:44334/resources\",\r\n    \"iss\": \"https://localhost:44334\",\r\n    \"nbf\": \"1453455277\",\r\n    \"exp\": \"1453455337\",\r\n    \"client_id\": \"fooclient\",\r\n    \"tokenLifetime\": 60,\r\n    \"scope\": [\r\n      \"Foo\",\r\n      \"email\",\r\n      \"offline_access\",\r\n      \"openid\",\r\n      \"profile\",\r\n      \"roles\"\r\n    ],\r\n    \"sub\": \"Foo@bar.com\",\r\n    \"auth_time\": 1453455211,\r\n    \"idp\": \"idsrv\",\r\n    \"amr\": \"password\",\r\n    \"email\": \"Foo@bar.com\",\r\n    \"name\": \"Foo@bar.com\"\r\n  }\r\n};\r\n2016-01-22 10:34:40,164;[30];INFO;IdentityServer3.Core.Endpoints.IntrospectionEndpointController;Start introspection request;\r\n2016-01-22 10:34:40,164;[30];DEBUG;IdentityServer3.Core.Validation.ScopeSecretValidator;Start scope validation;\r\n2016-01-22 10:34:40,164;[30];DEBUG;IdentityServer3.Core.Validation.X509CertificateSecretParser;Start parsing for X.509 certificate;\r\n2016-01-22 10:34:40,165;[22];DEBUG;IdentityServer3.Core.Validation.X509CertificateSecretParser;client_id is not found in post body;\r\n2016-01-22 10:34:40,165;[22];DEBUG;IdentityServer3.Core.Validation.PostBodySecretParser;Start parsing for secret in post body;\r\n2016-01-22 10:34:40,165;[22];DEBUG;IdentityServer3.Core.Validation.PostBodySecretParser;No secret in post body found;\r\n2016-01-22 10:34:40,166;[22];DEBUG;IdentityServer3.Core.Validation.BasicAuthenticationSecretParser;Start parsing Basic Authentication secret;\r\n2016-01-22 10:34:40,166;[22];DEBUG;IdentityServer3.Core.Validation.ScopeSecretValidator;Parser found scope secret: BasicAuthenticationSecretParser;\r\n2016-01-22 10:34:40,166;[22];INFO;IdentityServer3.Core.Validation.ScopeSecretValidator;Scope name found: Foo;\r\n2016-01-22 10:34:40,166;[22];DEBUG;IdentityServer3.Core.Validation.ScopeSecretValidator;Secret validator success: HashedSharedSecretValidator;\r\n2016-01-22 10:34:40,167;[22];INFO;IdentityServer3.Core.Validation.ScopeSecretValidator;Scope validation success;\r\n2016-01-22 10:34:40,167;[22];INFO;IdentityServer3.Core.Validation.TokenValidator;Start access token validation;\r\n2016-01-22 10:34:40,168;[22];INFO;IdentityServer3.Core.Validation.TokenValidator;Token validation success\r\n{\r\n  \"ValidateLifetime\": true,\r\n  \"AccessTokenType\": \"Reference\",\r\n  \"TokenHandle\": \"b20199ad2144d730934b22da70cc493b\",\r\n  \"Claims\": {\r\n    \"aud\": \"https://localhost:44334/resources\",\r\n    \"iss\": \"https://localhost:44334\",\r\n    \"nbf\": \"1453455277\",\r\n    \"exp\": \"1453455337\",\r\n    \"client_id\": \"fooclient\",\r\n    \"tokenLifetime\": 60,\r\n    \"scope\": [\r\n      \"Foo\",\r\n      \"email\",\r\n      \"offline_access\",\r\n      \"openid\",\r\n      \"profile\",\r\n      \"roles\"\r\n    ],\r\n    \"sub\": \"Foo@bar.com\",\r\n    \"auth_time\": 1453455211,\r\n    \"idp\": \"idsrv\",\r\n    \"amr\": \"password\",\r\n    \"email\": \"Foo@bar.com\",\r\n    \"name\": \"Foo@bar.com\"\r\n  }\r\n};\r\n```"}}