diff --git a/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/handlers/DefaultKeyValidationHandler.java b/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/handlers/DefaultKeyValidationHandler.java index 38011173f7df..95da9b98a5a7 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/handlers/DefaultKeyValidationHandler.java +++ b/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/handlers/DefaultKeyValidationHandler.java @@ -33,6 +33,7 @@ import org.wso2.carbon.apimgt.impl.utils.APIUtil; import org.wso2.carbon.apimgt.keymgt.APIKeyMgtException; import org.wso2.carbon.apimgt.keymgt.SubscriptionDataHolder; +import org.wso2.carbon.apimgt.keymgt.internal.ServiceReferenceHolder; import org.wso2.carbon.apimgt.keymgt.model.SubscriptionDataStore; import org.wso2.carbon.apimgt.keymgt.model.entity.API; import org.wso2.carbon.apimgt.keymgt.service.TokenValidationContext; @@ -212,14 +213,53 @@ public boolean validateScopes(TokenValidationContext validationContext) throws A return scopesValidated; } + private boolean isAccessTokenExpired(long validityPeriod, long issuedTime) { + + long timestampSkew = + ServiceReferenceHolder.getInstance().getOauthServerConfiguration().getTimeStampSkewInSeconds() * 1000; + long currentTime = System.currentTimeMillis(); + + //If the validity period is not an never expiring value + if (validityPeriod != Long.MAX_VALUE && + // For cases where validityPeriod is closer to Long.MAX_VALUE (then issuedTime + validityPeriod would spill + // over and would produce a negative value) + (currentTime - timestampSkew) > validityPeriod) { + //check the validity of cached OAuth2AccessToken Response + + if ((currentTime - timestampSkew) > (issuedTime + validityPeriod)) { + return true; + } + } + + return false; + } + + private AccessTokenInfo getAccessTokenInfo(TokenValidationContext validationContext) throws APIManagementException { Object cachedAccessTokenInfo = CacheProvider.createIntrospectionCache().get(validationContext.getAccessToken()); - if (cachedAccessTokenInfo != null) { - log.debug("AccessToken available in introspection Cache."); - return (AccessTokenInfo) cachedAccessTokenInfo; + AccessTokenInfo cachedAccessTokenInfoObject = null; + + if (cachedAccessTokenInfo instanceof AccessTokenInfo) { + cachedAccessTokenInfoObject = (AccessTokenInfo) cachedAccessTokenInfo; + + // Since validationInfoDTO object is not passed into isAccessTokenExpired(), + // validation status need to be set explicitly. + if (isAccessTokenExpired(cachedAccessTokenInfoObject.getValidityPeriod(), + cachedAccessTokenInfoObject.getIssuedTime())) { + + if (log.isDebugEnabled()) { + log.debug("Invalid OAuth Token in Introspect Cache : Access Token " + + APIUtil.getMaskedToken(validationContext.getAccessToken()) + " has been expired."); + } + // if token is expired remove cache entry from introspection cache + CacheProvider.getGatewayIntrospectCache().remove(validationContext.getAccessToken()); + cachedAccessTokenInfoObject.setErrorcode(APIConstants.KeyValidationStatus.API_AUTH_INVALID_CREDENTIALS); + cachedAccessTokenInfoObject.setTokenValid(false); + } + return cachedAccessTokenInfoObject; } String electedKeyManager = null; // Obtaining details about the token. diff --git a/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/internal/APIKeyMgtServiceComponent.java b/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/internal/APIKeyMgtServiceComponent.java index 3426b49bb2ea..613898a37927 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/internal/APIKeyMgtServiceComponent.java +++ b/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/internal/APIKeyMgtServiceComponent.java @@ -34,6 +34,7 @@ import org.wso2.carbon.apimgt.keymgt.service.KeyManagerDataServiceImpl; import org.wso2.carbon.apimgt.keymgt.util.APIKeyMgtDataHolder; import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService; +import org.wso2.carbon.identity.oauth.config.OAuthServerConfiguration; import org.wso2.carbon.registry.core.service.RegistryService; import org.wso2.carbon.user.core.service.RealmService; @@ -236,5 +237,25 @@ protected void removeKeyValidationHandler(KeyValidationHandler keyValidationHand ServiceReferenceHolder.getInstance().removeKeyValidationHandler(tenantDomain); } } + + @Reference( + name = "oauth.config.service", + service = OAuthServerConfiguration.class, + cardinality = ReferenceCardinality.MANDATORY, + policy = ReferencePolicy.DYNAMIC, + unbind = "unsetOauthServerConfiguration") + protected void setOauthServerConfiguration(OAuthServerConfiguration oauthServerConfiguration) { + ServiceReferenceHolder.getInstance().setOauthServerConfiguration(oauthServerConfiguration); + } + + /** + * De-reference the Oauth Server configuration Service dependency. + * + * @param oAuthServerConfiguration + */ + protected void unsetOauthServerConfiguration(OAuthServerConfiguration oAuthServerConfiguration) { + ServiceReferenceHolder.getInstance().setOauthServerConfiguration(null); + } + } diff --git a/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/internal/ServiceReferenceHolder.java b/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/internal/ServiceReferenceHolder.java index f68bda877f74..ae07b7e569e1 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/internal/ServiceReferenceHolder.java +++ b/components/apimgt/org.wso2.carbon.apimgt.keymgt/src/main/java/org/wso2/carbon/apimgt/keymgt/internal/ServiceReferenceHolder.java @@ -25,6 +25,7 @@ import org.wso2.carbon.apimgt.keymgt.handlers.DefaultKeyValidationHandler; import org.wso2.carbon.apimgt.keymgt.handlers.KeyValidationHandler; import org.wso2.carbon.event.output.adapter.core.OutputEventAdapterService; +import org.wso2.carbon.identity.oauth.config.OAuthServerConfiguration; import org.wso2.carbon.user.core.service.RealmService; import java.util.Map; @@ -38,6 +39,7 @@ public class ServiceReferenceHolder { private OutputEventAdapterService outputEventAdapterService; private Map keyValidationHandlerMap = new ConcurrentHashMap<>(); private RealmService realmService; + private OAuthServerConfiguration oauthServerConfiguration; private ServiceReferenceHolder() { @@ -102,4 +104,14 @@ public RealmService getRealmService() { public void setRealmService(RealmService realmService) { this.realmService = realmService; } + + public void setOauthServerConfiguration(OAuthServerConfiguration oauthServerConfiguration) { + this.oauthServerConfiguration = oauthServerConfiguration; + } + + public OAuthServerConfiguration getOauthServerConfiguration() { + + return oauthServerConfiguration; + } + }