Skip to content

Commit eb3ac40

Browse files
committed
Check and remove expired tokens from introspection cache.
1 parent 5ee9d1e commit eb3ac40

File tree

3 files changed

+76
-3
lines changed

3 files changed

+76
-3
lines changed

Diff for: components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/handlers/DefaultKeyValidationHandler.java

+43-3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.wso2.carbon.apimgt.impl.utils.APIUtil;
3434
import org.wso2.carbon.apimgt.keymgt.APIKeyMgtException;
3535
import org.wso2.carbon.apimgt.keymgt.SubscriptionDataHolder;
36+
import org.wso2.carbon.apimgt.keymgt.internal.ServiceReferenceHolder;
3637
import org.wso2.carbon.apimgt.keymgt.model.SubscriptionDataStore;
3738
import org.wso2.carbon.apimgt.keymgt.model.entity.API;
3839
import org.wso2.carbon.apimgt.keymgt.service.TokenValidationContext;
@@ -212,14 +213,53 @@ public boolean validateScopes(TokenValidationContext validationContext) throws A
212213
return scopesValidated;
213214
}
214215

216+
private boolean isAccessTokenExpired(long validityPeriod, long issuedTime) {
217+
218+
long timestampSkew =
219+
ServiceReferenceHolder.getInstance().getOauthServerConfiguration().getTimeStampSkewInSeconds() * 1000;
220+
long currentTime = System.currentTimeMillis();
221+
222+
//If the validity period is not an never expiring value
223+
if (validityPeriod != Long.MAX_VALUE &&
224+
// For cases where validityPeriod is closer to Long.MAX_VALUE (then issuedTime + validityPeriod would spill
225+
// over and would produce a negative value)
226+
(currentTime - timestampSkew) > validityPeriod) {
227+
//check the validity of cached OAuth2AccessToken Response
228+
229+
if ((currentTime - timestampSkew) > (issuedTime + validityPeriod)) {
230+
return true;
231+
}
232+
}
233+
234+
return false;
235+
}
236+
237+
215238
private AccessTokenInfo getAccessTokenInfo(TokenValidationContext validationContext)
216239
throws APIManagementException {
217240

218241
Object cachedAccessTokenInfo =
219242
CacheProvider.createIntrospectionCache().get(validationContext.getAccessToken());
220-
if (cachedAccessTokenInfo != null) {
221-
log.debug("AccessToken available in introspection Cache.");
222-
return (AccessTokenInfo) cachedAccessTokenInfo;
243+
AccessTokenInfo cachedAccessTokenInfoObject = null;
244+
245+
if (cachedAccessTokenInfo instanceof AccessTokenInfo) {
246+
cachedAccessTokenInfoObject = (AccessTokenInfo) cachedAccessTokenInfo;
247+
248+
// Since validationInfoDTO object is not passed into isAccessTokenExpired(),
249+
// validation status need to be set explicitly.
250+
if (isAccessTokenExpired(cachedAccessTokenInfoObject.getValidityPeriod(),
251+
cachedAccessTokenInfoObject.getIssuedTime())) {
252+
253+
if (log.isDebugEnabled()) {
254+
log.debug("Invalid OAuth Token in Introspect Cache : Access Token " +
255+
APIUtil.getMaskedToken(validationContext.getAccessToken()) + " has been expired.");
256+
}
257+
// if token is expired remove cache entry from introspection cache
258+
CacheProvider.getGatewayIntrospectCache().remove(validationContext.getAccessToken());
259+
cachedAccessTokenInfoObject.setErrorcode(APIConstants.KeyValidationStatus.API_AUTH_INVALID_CREDENTIALS);
260+
cachedAccessTokenInfoObject.setTokenValid(false);
261+
}
262+
return cachedAccessTokenInfoObject;
223263
}
224264
String electedKeyManager = null;
225265
// Obtaining details about the token.

Diff for: components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/internal/APIKeyMgtServiceComponent.java

+21
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.wso2.carbon.apimgt.keymgt.service.KeyManagerDataServiceImpl;
3535
import org.wso2.carbon.apimgt.keymgt.util.APIKeyMgtDataHolder;
3636
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService;
37+
import org.wso2.carbon.identity.oauth.config.OAuthServerConfiguration;
3738
import org.wso2.carbon.registry.core.service.RegistryService;
3839
import org.wso2.carbon.user.core.service.RealmService;
3940

@@ -236,5 +237,25 @@ protected void removeKeyValidationHandler(KeyValidationHandler keyValidationHand
236237
ServiceReferenceHolder.getInstance().removeKeyValidationHandler(tenantDomain);
237238
}
238239
}
240+
241+
@Reference(
242+
name = "oauth.config.service",
243+
service = OAuthServerConfiguration.class,
244+
cardinality = ReferenceCardinality.MANDATORY,
245+
policy = ReferencePolicy.DYNAMIC,
246+
unbind = "unsetOauthServerConfiguration")
247+
protected void setOauthServerConfiguration(OAuthServerConfiguration oauthServerConfiguration) {
248+
ServiceReferenceHolder.getInstance().setOauthServerConfiguration(oauthServerConfiguration);
249+
}
250+
251+
/**
252+
* De-reference the Oauth Server configuration Service dependency.
253+
*
254+
* @param oAuthServerConfiguration
255+
*/
256+
protected void unsetOauthServerConfiguration(OAuthServerConfiguration oAuthServerConfiguration) {
257+
ServiceReferenceHolder.getInstance().setOauthServerConfiguration(null);
258+
}
259+
239260
}
240261

Diff for: components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/internal/ServiceReferenceHolder.java

+12
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.wso2.carbon.apimgt.keymgt.handlers.DefaultKeyValidationHandler;
2626
import org.wso2.carbon.apimgt.keymgt.handlers.KeyValidationHandler;
2727
import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService;
28+
import org.wso2.carbon.identity.oauth.config.OAuthServerConfiguration;
2829
import org.wso2.carbon.user.core.service.RealmService;
2930

3031
import java.util.Map;
@@ -38,6 +39,7 @@ public class ServiceReferenceHolder {
3839
private OutputEventAdapterService outputEventAdapterService;
3940
private Map<String, KeyValidationHandler> keyValidationHandlerMap = new ConcurrentHashMap<>();
4041
private RealmService realmService;
42+
private OAuthServerConfiguration oauthServerConfiguration;
4143

4244
private ServiceReferenceHolder() {
4345

@@ -102,4 +104,14 @@ public RealmService getRealmService() {
102104
public void setRealmService(RealmService realmService) {
103105
this.realmService = realmService;
104106
}
107+
108+
public void setOauthServerConfiguration(OAuthServerConfiguration oauthServerConfiguration) {
109+
this.oauthServerConfiguration = oauthServerConfiguration;
110+
}
111+
112+
public OAuthServerConfiguration getOauthServerConfiguration() {
113+
114+
return oauthServerConfiguration;
115+
}
116+
105117
}

0 commit comments

Comments
 (0)