use of org.wso2.carbon.apimgt.impl.dto.APIKeyValidationInfoDTO in project carbon-apimgt by wso2.
the class InboundWebsocketProcessorUtilTest method testDoThrottleFail.
@Test
public void testDoThrottleFail() throws ParseException {
InboundMessageContext inboundMessageContext = new InboundMessageContext();
int msgSize = 100;
VerbInfoDTO verbInfoDTO = new VerbInfoDTO();
verbInfoDTO.setThrottling("Gold");
verbInfoDTO.setRequestKey("liftStatusChange");
String operationId = "1";
APIKeyValidationInfoDTO apiKeyValidationInfoDTO = new APIKeyValidationInfoDTO();
apiKeyValidationInfoDTO.setApplicationTier(APIConstants.UNLIMITED_TIER);
apiKeyValidationInfoDTO.setTier(APIConstants.UNLIMITED_TIER);
apiKeyValidationInfoDTO.setSubscriberTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
apiKeyValidationInfoDTO.setSubscriber("admin");
apiKeyValidationInfoDTO.setApiName("GraphQLAPI");
apiKeyValidationInfoDTO.setApplicationId("12");
inboundMessageContext.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
inboundMessageContext.setApiContext("/graphql");
inboundMessageContext.setVersion("1.0.0");
inboundMessageContext.setUserIP("198.162.10.2");
inboundMessageContext.setInfoDTO(apiKeyValidationInfoDTO);
String subscriptionLevelThrottleKey = apiKeyValidationInfoDTO.getApplicationId() + ":" + inboundMessageContext.getApiContext() + ":" + inboundMessageContext.getVersion();
String applicationLevelThrottleKey = apiKeyValidationInfoDTO.getApplicationId() + ":" + apiKeyValidationInfoDTO.getSubscriber() + "@" + apiKeyValidationInfoDTO.getSubscriberTenantDomain();
Mockito.when(dataPublisher.tryPublish(Mockito.anyObject())).thenReturn(true);
PowerMockito.when(WebsocketUtil.isThrottled(verbInfoDTO.getRequestKey(), subscriptionLevelThrottleKey, applicationLevelThrottleKey)).thenReturn(true);
InboundProcessorResponseDTO inboundProcessorResponseDTO = InboundWebsocketProcessorUtil.doThrottleForGraphQL(msgSize, verbInfoDTO, inboundMessageContext, operationId);
Assert.assertTrue(inboundProcessorResponseDTO.isError());
Assert.assertEquals(inboundProcessorResponseDTO.getErrorMessage(), WebSocketApiConstants.FrameErrorConstants.THROTTLED_OUT_ERROR_MESSAGE);
Assert.assertEquals(inboundProcessorResponseDTO.getErrorCode(), WebSocketApiConstants.FrameErrorConstants.THROTTLED_OUT_ERROR);
Assert.assertFalse(inboundProcessorResponseDTO.isCloseConnection());
JSONParser jsonParser = new JSONParser();
JSONObject errorJson = (JSONObject) jsonParser.parse(inboundProcessorResponseDTO.getErrorResponseString());
org.junit.Assert.assertEquals(errorJson.get(GraphQLConstants.SubscriptionConstants.PAYLOAD_FIELD_NAME_TYPE), GraphQLConstants.SubscriptionConstants.PAYLOAD_FIELD_TYPE_ERROR);
org.junit.Assert.assertEquals(errorJson.get(GraphQLConstants.SubscriptionConstants.PAYLOAD_FIELD_NAME_ID), "1");
JSONObject payload = (JSONObject) errorJson.get(GraphQLConstants.SubscriptionConstants.PAYLOAD_FIELD_NAME_PAYLOAD);
org.junit.Assert.assertEquals(payload.get(WebSocketApiConstants.FrameErrorConstants.ERROR_MESSAGE), WebSocketApiConstants.FrameErrorConstants.THROTTLED_OUT_ERROR_MESSAGE);
org.junit.Assert.assertEquals(String.valueOf(payload.get(WebSocketApiConstants.FrameErrorConstants.ERROR_CODE)), String.valueOf(WebSocketApiConstants.FrameErrorConstants.THROTTLED_OUT_ERROR));
}
use of org.wso2.carbon.apimgt.impl.dto.APIKeyValidationInfoDTO in project carbon-apimgt by wso2.
the class OAuthOpaqueAuthenticatorImpl method isAccessTokenExpired.
private boolean isAccessTokenExpired(OAuthTokenInfo accessTokenInfo) {
APIKeyValidationInfoDTO infoDTO = new APIKeyValidationInfoDTO();
infoDTO.setValidityPeriod(accessTokenInfo.getValidityPeriod());
infoDTO.setIssuedTime(accessTokenInfo.getIssuedTime());
return APIUtil.isAccessTokenExpired(infoDTO);
}
use of org.wso2.carbon.apimgt.impl.dto.APIKeyValidationInfoDTO in project carbon-apimgt by wso2.
the class InboundWebsocketProcessorUtil method isAuthenticated.
/**
* Authenticate inbound websocket request handshake.
*
* @param inboundMessageContext InboundMessageContext
* @return whether authenticated or not
* @throws APIManagementException if an internal error occurs
* @throws APISecurityException if authentication fails
*/
public static boolean isAuthenticated(InboundMessageContext inboundMessageContext) throws APISecurityException, APIManagementException {
try {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(inboundMessageContext.getTenantDomain(), true);
APIKeyValidationInfoDTO info;
String authorizationHeader = inboundMessageContext.getRequestHeaders().get(HttpHeaders.AUTHORIZATION);
inboundMessageContext.getRequestHeaders().put(HttpHeaders.AUTHORIZATION, authorizationHeader);
String[] auth = authorizationHeader.split(StringUtils.SPACE);
List<String> keyManagerList = DataHolder.getInstance().getKeyManagersFromUUID(inboundMessageContext.getElectedAPI().getUuid());
if (APIConstants.CONSUMER_KEY_SEGMENT.equals(auth[0])) {
String cacheKey;
boolean isJwtToken = false;
String apiKey = auth[1];
if (WebsocketUtil.isRemoveOAuthHeadersFromOutMessage()) {
inboundMessageContext.getRequestHeaders().remove(HttpHeaders.AUTHORIZATION);
}
// Initial guess of a JWT token using the presence of a DOT.
if (StringUtils.isNotEmpty(apiKey) && apiKey.contains(APIConstants.DOT)) {
try {
// Check if the header part is decoded
if (StringUtils.countMatches(apiKey, APIConstants.DOT) != 2) {
log.debug("Invalid JWT token. The expected token format is <header.payload.signature>");
throw new APISecurityException(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, "Invalid JWT token");
}
inboundMessageContext.setSignedJWTInfo(getSignedJwtInfo(apiKey));
String keyManager = ServiceReferenceHolder.getInstance().getJwtValidationService().getKeyManagerNameIfJwtValidatorExist(inboundMessageContext.getSignedJWTInfo());
if (StringUtils.isNotEmpty(keyManager)) {
if (log.isDebugEnabled()) {
log.debug("KeyManager " + keyManager + "found for authenticate token " + GatewayUtils.getMaskedToken(apiKey));
}
if (keyManagerList.contains(APIConstants.KeyManager.API_LEVEL_ALL_KEY_MANAGERS) || keyManagerList.contains(keyManager)) {
if (log.isDebugEnabled()) {
log.debug("Elected KeyManager " + keyManager + "found in API level list " + String.join(",", keyManagerList));
}
isJwtToken = true;
} else {
if (log.isDebugEnabled()) {
log.debug("Elected KeyManager " + keyManager + " not found in API level list " + String.join(",", keyManagerList));
}
throw new APISecurityException(APISecurityConstants.API_AUTH_INVALID_CREDENTIALS, "Invalid JWT token");
}
} else {
if (log.isDebugEnabled()) {
log.debug("KeyManager not found for accessToken " + GatewayUtils.getMaskedToken(apiKey));
}
}
} catch (ParseException e) {
log.debug("Not a JWT token. Failed to decode the token header.", e);
} catch (APIManagementException e) {
log.error("Error while checking validation of JWT", e);
throw new APISecurityException(APISecurityConstants.API_AUTH_GENERAL_ERROR, APISecurityConstants.API_AUTH_GENERAL_ERROR_MESSAGE);
}
}
// Find the authentication scheme based on the token type
if (isJwtToken) {
log.debug("The token was identified as a JWT token");
if (APIConstants.GRAPHQL_API.equals(inboundMessageContext.getElectedAPI().getApiType())) {
return InboundWebsocketProcessorUtil.authenticateGraphQLJWTToken(inboundMessageContext);
} else {
return InboundWebsocketProcessorUtil.authenticateWSJWTToken(inboundMessageContext);
}
} else {
log.debug("The token was identified as an OAuth token");
// If the key have already been validated
if (WebsocketUtil.isGatewayTokenCacheEnabled()) {
cacheKey = WebsocketUtil.getAccessTokenCacheKey(apiKey, inboundMessageContext.getApiContext(), inboundMessageContext.getMatchingResource());
info = WebsocketUtil.validateCache(apiKey, cacheKey);
if (info != null) {
inboundMessageContext.setKeyType(info.getType());
inboundMessageContext.setInfoDTO(info);
return info.isAuthorized();
}
}
info = getApiKeyDataForWSClient(apiKey, inboundMessageContext.getTenantDomain(), inboundMessageContext.getApiContext(), inboundMessageContext.getVersion(), keyManagerList);
if (info == null || !info.isAuthorized()) {
return false;
}
if (WebsocketUtil.isGatewayTokenCacheEnabled()) {
cacheKey = WebsocketUtil.getAccessTokenCacheKey(apiKey, inboundMessageContext.getApiContext(), inboundMessageContext.getMatchingResource());
WebsocketUtil.putCache(info, apiKey, cacheKey);
}
inboundMessageContext.setKeyType(info.getType());
inboundMessageContext.setToken(info.getEndUserToken());
inboundMessageContext.setInfoDTO(info);
return true;
}
} else {
return false;
}
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
use of org.wso2.carbon.apimgt.impl.dto.APIKeyValidationInfoDTO in project carbon-apimgt by wso2.
the class InboundWebsocketProcessorUtil method validateAuthenticationContext.
/**
* Validates AuthenticationContext and set APIKeyValidationInfoDTO to InboundMessageContext.
*
* @param authenticationContext Validated AuthenticationContext
* @param inboundMessageContext InboundMessageContext
* @return true if authenticated
*/
public static boolean validateAuthenticationContext(AuthenticationContext authenticationContext, InboundMessageContext inboundMessageContext) {
if (authenticationContext == null || !authenticationContext.isAuthenticated()) {
return false;
}
// The information given by the AuthenticationContext is set to an APIKeyValidationInfoDTO object
// so to feed information analytics and throttle data publishing
APIKeyValidationInfoDTO info = new APIKeyValidationInfoDTO();
info.setAuthorized(authenticationContext.isAuthenticated());
info.setApplicationTier(authenticationContext.getApplicationTier());
info.setTier(authenticationContext.getTier());
info.setSubscriberTenantDomain(authenticationContext.getSubscriberTenantDomain());
info.setSubscriber(authenticationContext.getSubscriber());
info.setStopOnQuotaReach(authenticationContext.isStopOnQuotaReach());
info.setApiName(authenticationContext.getApiName());
info.setApplicationId(authenticationContext.getApplicationId());
info.setType(authenticationContext.getKeyType());
info.setApiPublisher(authenticationContext.getApiPublisher());
info.setApplicationName(authenticationContext.getApplicationName());
info.setConsumerKey(authenticationContext.getConsumerKey());
info.setEndUserName(authenticationContext.getUsername());
info.setApiTier(authenticationContext.getApiTier());
info.setGraphQLMaxDepth(authenticationContext.getGraphQLMaxDepth());
info.setGraphQLMaxComplexity(authenticationContext.getGraphQLMaxComplexity());
inboundMessageContext.setKeyType(info.getType());
inboundMessageContext.setInfoDTO(info);
inboundMessageContext.setAuthContext(authenticationContext);
inboundMessageContext.setInfoDTO(info);
return authenticationContext.isAuthenticated();
}
use of org.wso2.carbon.apimgt.impl.dto.APIKeyValidationInfoDTO in project carbon-apimgt by wso2.
the class JWTValidator method validateScopes.
/**
* Validate scopes bound to the resource of the API being invoked against the scopes specified
* in the JWT token payload.
*
* @param apiContext API Context
* @param apiVersion API Version
* @param matchingResource Accessed API resource
* @param httpMethod API resource's HTTP method
* @param jwtValidationInfo Validated JWT Information
* @param jwtToken JWT Token
* @throws APISecurityException in case of scope validation failure
*/
private void validateScopes(String apiContext, String apiVersion, String matchingResource, String httpMethod, JWTValidationInfo jwtValidationInfo, SignedJWTInfo jwtToken) throws APISecurityException {
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
// Generate TokenValidationContext
TokenValidationContext tokenValidationContext = new TokenValidationContext();
APIKeyValidationInfoDTO apiKeyValidationInfoDTO = new APIKeyValidationInfoDTO();
Set<String> scopeSet = new HashSet<>();
scopeSet.addAll(jwtValidationInfo.getScopes());
apiKeyValidationInfoDTO.setScopes(scopeSet);
tokenValidationContext.setValidationInfoDTO(apiKeyValidationInfoDTO);
tokenValidationContext.setAccessToken(jwtToken.getToken());
tokenValidationContext.setHttpVerb(httpMethod);
tokenValidationContext.setMatchingResource(matchingResource);
tokenValidationContext.setContext(apiContext);
tokenValidationContext.setVersion(apiVersion);
boolean valid = this.apiKeyValidator.validateScopes(tokenValidationContext, tenantDomain);
if (valid) {
if (log.isDebugEnabled()) {
log.debug("Scope validation successful for the resource: " + matchingResource + ", user: " + jwtValidationInfo.getUser());
}
} else {
String message = "User is NOT authorized to access the Resource: " + matchingResource + ". Scope validation failed.";
log.debug(message);
throw new APISecurityException(APISecurityConstants.INVALID_SCOPE, message);
}
}
Aggregations