Esempio n. 1
0
  private APIInfoDTO doGetAPIInfo(String context, String apiVersion) {
    APIInfoDTO apiInfoDTO = new APIInfoDTO();
    try {
      ArrayList<URITemplate> uriTemplates = getAllURITemplates(context, apiVersion);

      apiInfoDTO.setApiName(context);
      apiInfoDTO.setContext(context);
      apiInfoDTO.setVersion(apiVersion);
      apiInfoDTO.setResources(new HashSet<ResourceInfoDTO>());

      ResourceInfoDTO resourceInfoDTO = null;
      VerbInfoDTO verbInfoDTO = null;
      int i = 0;
      for (URITemplate uriTemplate : uriTemplates) {
        if (resourceInfoDTO != null
            && resourceInfoDTO.getUrlPattern().equalsIgnoreCase(uriTemplate.getUriTemplate())) {
          HashSet<VerbInfoDTO> verbs = (HashSet<VerbInfoDTO>) resourceInfoDTO.getHttpVerbs();
          verbInfoDTO = new VerbInfoDTO();
          verbInfoDTO.setHttpVerb(uriTemplate.getHTTPVerb());
          verbInfoDTO.setAuthType(uriTemplate.getAuthType());
          verbs.add(verbInfoDTO);
          resourceInfoDTO.setHttpVerbs(verbs);
          apiInfoDTO.getResources().add(resourceInfoDTO);
        } else {
          resourceInfoDTO = new ResourceInfoDTO();
          resourceInfoDTO.setUrlPattern(uriTemplate.getUriTemplate());
          verbInfoDTO = new VerbInfoDTO();
          verbInfoDTO.setHttpVerb(uriTemplate.getHTTPVerb());
          verbInfoDTO.setAuthType(uriTemplate.getAuthType());
          HashSet<VerbInfoDTO> httpVerbs2 = new HashSet();
          httpVerbs2.add(verbInfoDTO);
          resourceInfoDTO.setHttpVerbs(httpVerbs2);
          apiInfoDTO.getResources().add(resourceInfoDTO);
        }
      }
    } catch (APIManagementException e) {
      log.error("Loading URI templates for " + context + ":" + apiVersion + " failed", e);
    } catch (APISecurityException e) {
      log.error("Loading URI templates for " + context + ":" + apiVersion + " failed", e);
    }
    return apiInfoDTO;
  }
  private APIInfoDTO doGetAPIInfo(String context, String apiVersion) throws APISecurityException {
    APIInfoDTO apiInfoDTO = new APIInfoDTO();

    ArrayList<URITemplate> uriTemplates = getAllURITemplates(context, apiVersion);

    apiInfoDTO.setApiName(context);
    apiInfoDTO.setContext(context);
    apiInfoDTO.setVersion(apiVersion);
    apiInfoDTO.setResources(new LinkedHashSet<ResourceInfoDTO>());

    ResourceInfoDTO resourceInfoDTO = null;
    VerbInfoDTO verbInfoDTO = null;

    // The following map is used to retrieve already created ResourceInfoDTO rather than iterating -
    // the resource Set in apiInfoDTO.
    LinkedHashMap<String, ResourceInfoDTO> resourcesMap =
        new LinkedHashMap<String, ResourceInfoDTO>();
    for (URITemplate uriTemplate : uriTemplates) {
      resourceInfoDTO = resourcesMap.get(uriTemplate.getUriTemplate());
      if (null == resourceInfoDTO) {
        resourceInfoDTO = new ResourceInfoDTO();
        resourceInfoDTO.setUrlPattern(uriTemplate.getUriTemplate());
        resourceInfoDTO.setHttpVerbs(new LinkedHashSet());
        apiInfoDTO.getResources().add(resourceInfoDTO);
        resourcesMap.put(uriTemplate.getUriTemplate(), resourceInfoDTO);
      }
      verbInfoDTO = new VerbInfoDTO();
      verbInfoDTO.setHttpVerb(uriTemplate.getHTTPVerb());
      verbInfoDTO.setAuthType(uriTemplate.getAuthType());
      verbInfoDTO.setThrottling(uriTemplate.getThrottlingTier());
      verbInfoDTO.setThrottlingConditions(uriTemplate.getThrottlingConditions());
      verbInfoDTO.setConditionGroups(uriTemplate.getConditionGroups());
      verbInfoDTO.setApplicableLevel(uriTemplate.getApplicableLevel());
      resourceInfoDTO.getHttpVerbs().add(verbInfoDTO);
    }

    return apiInfoDTO;
  }
  /**
   * @param context API context of API
   * @param apiVersion Version of API
   * @param requestPath Incoming request path
   * @param httpMethod http method of request
   * @return verbInfoDTO which contains throttling tier for given resource and verb+resource key
   */
  public VerbInfoDTO getVerbInfoDTOFromAPIData(
      String context, String apiVersion, String requestPath, String httpMethod)
      throws APISecurityException {

    String cacheKey = context + ':' + apiVersion;
    APIInfoDTO apiInfoDTO = null;
    if (isGatewayAPIResourceValidationEnabled) {
      apiInfoDTO = (APIInfoDTO) getResourceCache().get(cacheKey);
    }
    if (apiInfoDTO == null) {
      apiInfoDTO = doGetAPIInfo(context, apiVersion);
      getResourceCache().put(cacheKey, apiInfoDTO);
    }

    // Match the case where the direct api context is matched
    if ("/".equals(requestPath)) {
      String requestCacheKey = context + '/' + apiVersion + requestPath + ':' + httpMethod;

      // Get decision from cache.
      VerbInfoDTO matchingVerb = null;
      if (isGatewayAPIResourceValidationEnabled) {
        matchingVerb = (VerbInfoDTO) getResourceCache().get(requestCacheKey);
      }
      // On a cache hit
      if (matchingVerb != null) {
        matchingVerb.setRequestKey(requestCacheKey);
        return matchingVerb;
      } else {
        if (apiInfoDTO.getResources() != null) {
          for (ResourceInfoDTO resourceInfoDTO : apiInfoDTO.getResources()) {
            String urlPattern = resourceInfoDTO.getUrlPattern();

            // If the request patch is '/', it can only be matched with a resource whose url-context
            // is '/*'
            if ("/*".equals(urlPattern)) {
              for (VerbInfoDTO verbDTO : resourceInfoDTO.getHttpVerbs()) {
                if (verbDTO.getHttpVerb().equals(httpMethod)) {
                  // Store verb in cache
                  getResourceCache().put(requestCacheKey, verbDTO);
                  verbDTO.setRequestKey(requestCacheKey);
                  return verbDTO;
                }
              }
            }
          }
        }
      }
    }

    // Remove the ending '/' from request
    requestPath = RESTUtils.trimTrailingSlashes(requestPath);

    while (requestPath.length() > 1) {

      String requestCacheKey = context + '/' + apiVersion + requestPath + ':' + httpMethod;

      // Get decision from cache.
      VerbInfoDTO matchingVerb = null;
      if (isGatewayAPIResourceValidationEnabled) {
        matchingVerb = (VerbInfoDTO) getResourceCache().get(requestCacheKey);
      }

      // On a cache hit
      if (matchingVerb != null) {
        matchingVerb.setRequestKey(requestCacheKey);
        return matchingVerb;
      }
      // On a cache miss
      else {
        for (ResourceInfoDTO resourceInfoDTO : apiInfoDTO.getResources()) {
          String urlPattern = resourceInfoDTO.getUrlPattern();
          if (urlPattern.endsWith("/*")) {
            // Remove the ending '/*'
            urlPattern = urlPattern.substring(0, urlPattern.length() - 2);
          }
          // If the urlPattern ends with a '/', remove that as well.
          urlPattern = RESTUtils.trimTrailingSlashes(urlPattern);

          if (requestPath.endsWith(urlPattern)) {

            for (VerbInfoDTO verbDTO : resourceInfoDTO.getHttpVerbs()) {
              if (verbDTO.getHttpVerb().equals(httpMethod)) {
                // Store verb in cache
                getResourceCache().put(requestCacheKey, verbDTO);
                verbDTO.setRequestKey(requestCacheKey);
                return verbDTO;
              }
            }
          }
        }
      }

      // Remove the section after the last occurrence of the '/' character
      int index = requestPath.lastIndexOf('/');
      requestPath = requestPath.substring(0, index <= 0 ? 0 : index);
    }
    // nothing found. return the highest level of security
    return null;
  }
  public VerbInfoDTO findMatchingVerb(MessageContext synCtx)
      throws ResourceNotFoundException, APISecurityException {

    VerbInfoDTO verb = null;

    // This function is used by more than one handler. If on one execution of this function, it has
    // found and placed
    // the matching verb in the cache, the same can be re-used from all handlers since all handlers
    // share the same
    // MessageContext. The API_RESOURCE_CACHE_KEY property will be set in the MessageContext to
    // indicate that the
    // verb has been put into the cache.
    String resourceCacheKey = (String) synCtx.getProperty(APIConstants.API_RESOURCE_CACHE_KEY);
    if (resourceCacheKey != null) {
      verb = (VerbInfoDTO) getResourceCache().get(resourceCacheKey);
      // Cache hit
      if (verb != null) {
        if (log.isDebugEnabled()) {
          log.debug("Found resource in Cache for key: ".concat(resourceCacheKey));
        }
        return verb;
      }
      if (log.isDebugEnabled()) {
        log.debug("Resource not found in cache for key: ".concat(resourceCacheKey));
      }
    }
    String resourceString = (String) synCtx.getProperty(APIConstants.API_ELECTED_RESOURCE);
    String apiContext = (String) synCtx.getProperty(RESTConstants.REST_API_CONTEXT);
    String apiVersion = (String) synCtx.getProperty(RESTConstants.SYNAPSE_REST_API_VERSION);
    String fullRequestPath = (String) synCtx.getProperty(RESTConstants.REST_FULL_REQUEST_PATH);
    String apiName = (String) synCtx.getProperty(RESTConstants.SYNAPSE_REST_API);

    String requestPath = Utils.getRequestPath(synCtx, fullRequestPath, apiContext, apiVersion);
    if ("".equals(requestPath)) {
      requestPath = "/";
    }

    if (log.isDebugEnabled()) {
      log.debug("Setting REST_SUB_REQUEST_PATH in msg context: ".concat(requestPath));
    }
    synCtx.setProperty(RESTConstants.REST_SUB_REQUEST_PATH, requestPath);

    String httpMethod =
        (String)
            ((Axis2MessageContext) synCtx)
                .getAxis2MessageContext()
                .getProperty(Constants.Configuration.HTTP_METHOD);
    if (resourceString == null) {
      API selectedApi = synCtx.getConfiguration().getAPI(apiName);
      Resource selectedResource = null;

      if (selectedApi != null) {
        Resource[] selectedAPIResources = selectedApi.getResources();

        Set<Resource> acceptableResources = new HashSet<Resource>();

        for (Resource resource : selectedAPIResources) {
          // If the requesting method is OPTIONS or if the Resource contains the requesting method
          if (RESTConstants.METHOD_OPTIONS.equals(httpMethod)
              || (resource.getMethods() != null
                  && Arrays.asList(resource.getMethods()).contains(httpMethod))) {
            acceptableResources.add(resource);
          }
        }

        if (acceptableResources.size() > 0) {
          for (RESTDispatcher dispatcher : RESTUtils.getDispatchers()) {
            Resource resource = dispatcher.findResource(synCtx, acceptableResources);
            if (resource != null && Arrays.asList(resource.getMethods()).contains(httpMethod)) {
              selectedResource = resource;
              break;
            }
          }
        }
      }

      if (selectedResource == null) {
        // No matching resource found.
        String msg = "Could not find matching resource for " + requestPath;
        log.error(msg);
        throw new ResourceNotFoundException(msg);
      }

      resourceString = selectedResource.getDispatcherHelper().getString();
      resourceCacheKey =
          APIUtil.getResourceInfoDTOCacheKey(apiContext, apiVersion, resourceString, httpMethod);

      if (log.isDebugEnabled()) {
        log.debug("Selected Resource: ".concat(resourceString));
      }
      // Set the elected resource
      synCtx.setProperty(APIConstants.API_ELECTED_RESOURCE, resourceString);
    }
    verb = (VerbInfoDTO) getResourceCache().get(resourceCacheKey);

    // Cache hit
    if (verb != null) {
      if (log.isDebugEnabled()) {
        log.debug("Got Resource from cache for key: ".concat(resourceCacheKey));
      }
      // Set cache key in the message context so that it can be used by the subsequent handlers.
      synCtx.setProperty(APIConstants.API_RESOURCE_CACHE_KEY, resourceCacheKey);
      return verb;
    }

    if (log.isDebugEnabled()) {
      log.debug("Cache miss for Resource for key: ".concat(resourceCacheKey));
    }

    String apiCacheKey = APIUtil.getAPIInfoDTOCacheKey(apiContext, apiVersion);
    APIInfoDTO apiInfoDTO = null;
    apiInfoDTO = (APIInfoDTO) getResourceCache().get(apiCacheKey);

    // Cache miss
    if (apiInfoDTO == null) {
      if (log.isDebugEnabled()) {
        log.debug("Could not find API object in cache for key: ".concat(apiCacheKey));
      }
      apiInfoDTO = doGetAPIInfo(apiContext, apiVersion);
      getResourceCache().put(apiCacheKey, apiInfoDTO);
    }
    if (apiInfoDTO.getResources() != null) {
      for (ResourceInfoDTO resourceInfoDTO : apiInfoDTO.getResources()) {
        if ((resourceString.trim()).equalsIgnoreCase(resourceInfoDTO.getUrlPattern().trim())) {
          for (VerbInfoDTO verbDTO : resourceInfoDTO.getHttpVerbs()) {
            if (verbDTO.getHttpVerb().equals(httpMethod)) {
              if (log.isDebugEnabled()) {
                log.debug("Putting resource object in cache with key: ".concat(resourceCacheKey));
              }
              verbDTO.setRequestKey(resourceCacheKey);
              // Store verb in cache
              getResourceCache().put(resourceCacheKey, verbDTO);
              // Set cache key in the message context so that it can be used by the subsequent
              // handlers.
              synCtx.setProperty(APIConstants.API_RESOURCE_CACHE_KEY, resourceCacheKey);
              return verbDTO;
            }
          }
        }
      }
    }
    return null;
  }
Esempio n. 5
0
  public String getResourceAuthenticationScheme(
      String context, String apiVersion, String requestPath, String httpMethod) {

    String cacheKey = context + ":" + apiVersion;
    APIInfoDTO apiInfoDTO = null;
    if (isGatewayAPIKeyValidationEnabled) {
      apiInfoDTO = (APIInfoDTO) resourceCache.get(cacheKey);
    }

    if (apiInfoDTO == null) {
      apiInfoDTO = doGetAPIInfo(context, apiVersion);
      resourceCache.put(cacheKey, apiInfoDTO);
    }

    // Match the case where the direct api context is matched
    if ("/".equals(requestPath)) {
      String requestCacheKey = context + "/" + apiVersion + requestPath + ":" + httpMethod;

      // Get decision from cache.
      VerbInfoDTO matchingVerb = null;
      if (isGatewayAPIKeyValidationEnabled) {
        matchingVerb = (VerbInfoDTO) resourceCache.get(requestCacheKey);
      }
      // On a cache hit
      if (matchingVerb != null) {
        return matchingVerb.getAuthType();
      } else {
        for (ResourceInfoDTO resourceInfoDTO : apiInfoDTO.getResources()) {
          String urlPattern = resourceInfoDTO.getUrlPattern();

          // If the request patch is '/', it can only be matched with a resource whose url-context
          // is '/*'
          if ("/*".equals(urlPattern)) {
            for (VerbInfoDTO verbDTO : resourceInfoDTO.getHttpVerbs()) {
              if (verbDTO.getHttpVerb().equals(httpMethod)) {
                // Store verb in cache
                resourceCache.put(requestCacheKey, verbDTO);
                return verbDTO.getAuthType();
              }
            }
          }
        }
      }
    }

    // Remove the ending '/' from request
    requestPath = RESTUtils.trimTrailingSlashes(requestPath);

    while (requestPath.length() > 1) {

      String requestCacheKey = context + "/" + apiVersion + requestPath + ":" + httpMethod;

      // Get decision from cache.
      VerbInfoDTO matchingVerb = null;
      if (isGatewayAPIKeyValidationEnabled) {
        matchingVerb = (VerbInfoDTO) resourceCache.get(requestCacheKey);
      }

      // On a cache hit
      if (matchingVerb != null) {
        return matchingVerb.getAuthType();
      }
      // On a cache miss
      else {
        for (ResourceInfoDTO resourceInfoDTO : apiInfoDTO.getResources()) {
          String urlPattern = resourceInfoDTO.getUrlPattern();
          if (urlPattern.endsWith("/*")) {
            // Remove the ending '/*'
            urlPattern = urlPattern.substring(0, urlPattern.length() - 2);
          }
          // If the urlPattern ends with a '/', remove that as well.
          urlPattern = RESTUtils.trimTrailingSlashes(urlPattern);

          if (requestPath.endsWith(urlPattern)) {

            for (VerbInfoDTO verbDTO : resourceInfoDTO.getHttpVerbs()) {
              if (verbDTO.getHttpVerb().equals(httpMethod)) {
                // Store verb in cache
                resourceCache.put(requestCacheKey, verbDTO);
                return verbDTO.getAuthType();
              }
            }
          }
        }
      }

      // Remove the section after the last occurrence of the '/' character
      int index = requestPath.lastIndexOf("/");
      requestPath = requestPath.substring(0, index <= 0 ? 0 : index);
    }
    // nothing found. return the highest level of security
    return APIConstants.NO_MATCHING_AUTH_SCHEME;
  }