Получение кода ошибки 403 при самом первом запуске вызова API HttpURLConnection - PullRequest
0 голосов
/ 29 мая 2019

Я работаю над одним проектом по интеграции Tenable.sc (который является инструментом мониторинга сети) и ServiceNow (инструмент SaaS для создания инцидентов). Я использую API-интерфейсы tenable.sc для получения данных анализа уязвимостей из tenable и их хранения в базе данных Postgres. Мой вопрос связан с Java HttpURLConnection и Cookie manager.

Я использую приведенный ниже код для получения всех данных через API. Основная проблема - когда я запускаю свое приложение Spring-Boot и пытаюсь запустить этот API в первый раз, он выдает ошибку 403. После каждого последующего вызова API я получаю правильные результаты.

Пожалуйста, обратитесь ниже код и шаги:


@ Услуги открытый класс MyAppService {

private CookieManager cookieManager;
static final String COOKIES_HEADER = "Set-Cookie";

@Value("${tenable.analysis.severity}")
private String severities;

public MyAppService() {
    // Setting The CookieHandler so we have access to clear it
    // This also allows us to open separate connections with the same cookies
    cookieManager = new CookieManager();
    CookieHandler.setDefault(cookieManager);
    cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
}

// Fetches all Vulnerabilities for the given asset
public List<VulnerabilitiesRequest> fetchVulnerabilities(String base, String path, String user, String pass, String action, int startOffSet, int endOffSet) throws IOException {
    return fetchRequest(base, path, user, pass, action, startOffSet, endOffSet, new KillerAppzException("Error fetching vulnerabilities"));
}

private List<VulnerabilitiesRequest> fetchRequest(String base, String path, String user, String pass, String action, int startOffSet, int endOffSet, KillerAppzException exception) throws IOException {
    HttpURLConnection conn = request(base, path, user, pass, action, startOffSet, endOffSet);
    if (conn.getResponseCode() == 200) {
        StringBuilder response = HttpUtils.readInputStream(conn);
        conn.disconnect();
        ObjectMapper objectMapper = new ObjectMapper();

        JsonNode rootNode = objectMapper.readTree(response.toString());
        JsonNode locatedNode = rootNode.path("response").path("results");

        Gson gson = new Gson();
        VulnerabilitiesRequest clicks[] = gson.fromJson(locatedNode.toString(), VulnerabilitiesRequest[].class);
        List<VulnerabilitiesRequest> list = Arrays.asList(clicks);

        return list;
    } else {
        conn.disconnect();
        throw exception;
    }
}

private HttpURLConnection request(String base, String path, String user, String pass, String action, int startOffSet, int endOffSet) throws IOException {

    URL baseURL = new URL(base + path);
    HttpURLConnection conn = (HttpURLConnection) baseURL.openConnection();
    conn.setDoOutput(true);
    conn.setRequestProperty("X-SecurityCenter", generateNewToken(user,pass));
    conn.setRequestProperty("Authorization", getAuthorizationHeaderValue(user, pass));
    conn.setRequestProperty("Content-Type", "application/json");
    conn.setRequestProperty("Accept", "application/json");

    conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11");
    conn.setRequestMethod("POST");

    String postJsonData="";
    if(action.equalsIgnoreCase("FETCH")) {
        postJsonData = "{\r\n" + 
            "\"query\": {\r\n" + 
            "\"type\": \"vuln\",\r\n" + 
            "\"tool\": \"vulndetails\",\r\n" + 
            "\"sourceType\": \"cumulative\",\r\n" +
            "\"startOffset\": " + startOffSet + ",\r\n" + 
            "\"endOffset\": " + endOffSet + ",\r\n" +
            "\"filters\": [\r\n" + 
            "   {\r\n" + 
            "        \"filterName\": \"severity\",\r\n" + 
            "        \"operator\": \"=\",\r\n" + 
            "        \"value\": \""+ severities + "\"\r\n" + 
            "   },\r\n" +
            "   {\r\n" + 
            "        \"filterName\": \"lastSeen\",\r\n" + 
            "        \"operator\": \"=\",\r\n" + 
            "        \"value\": \"0:30\"\r\n" + 
            "   }\r\n" +
            "]\r\n" + 
            "},\r\n" + 
            "\"sourceType\": \"cumulative\",\r\n" + 
            "\"sortField\": \"severity\",\r\n" + 
            "\"sortDir\": \"asc\",\r\n" + 
            "\"columns\": [],\r\n" + 
            "\"type\": \"vuln\"\r\n" + 
            "}";    
    }else {
        postJsonData = "{\r\n" + 
            "\"query\": {\r\n" + 
            "\"type\": \"vuln\",\r\n" + 
            "\"tool\": \"vulndetails\",\r\n" + 
            "\"sourceType\": \"patched\",\r\n" +
            "\"startOffset\": " + startOffSet + ",\r\n" + 
            "\"endOffset\": " + endOffSet + ",\r\n" +
            "\"filters\": [\r\n" + 
            "   {\r\n" + 
            "        \"filterName\": \"severity\",\r\n" + 
            "        \"operator\": \"=\",\r\n" + 
            "        \"value\": \""+ severities + "\"\r\n" + 
            "   }\r\n" +
            "]\r\n" + 
            "},\r\n" + 
            "\"sourceType\": \"patched\",\r\n" + 
            "\"sortField\": \"severity\",\r\n" + 
            "\"sortDir\": \"asc\",\r\n" + 
            "\"columns\": [],\r\n" + 
            "\"type\": \"vuln\"\r\n" + 
            "}";
    }

    String cookieValue = "";
    if (cookieManager.getCookieStore().getCookies().size() > 0) {
        List<HttpCookie> cookies = cookieManager.getCookieStore().getCookies();

        if (cookies != null) { 
            for (HttpCookie cookie : cookies) { 
                if(cookie.getName().equals("TNS_SESSIONID")) { 
                    cookieValue = cookie.getValue();
                }
            }
        }
    }
    conn.setRequestProperty("Cookie", "TNS_SESSIONID=" + cookieValue);

    DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
    wr.writeBytes(postJsonData);
    wr.flush();
    wr.close();

    return conn;
}

private String generateNewToken(String user, String pass) throws IOException {

    URL tokenGenerationURL = new URL("https://sc.tenalab.online/rest/token?username="+ user +"&password="+ pass);
    HttpURLConnection tokenConn = (HttpURLConnection) tokenGenerationURL.openConnection();
    tokenConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
    tokenConn.setRequestProperty("Accept", "application/json");
    tokenConn.setDoOutput(true);
    tokenConn.setRequestMethod("POST");

    BufferedReader in = new BufferedReader(new InputStreamReader(tokenConn.getInputStream()));
    String inputLine;
    StringBuffer response = new StringBuffer();

    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
    }
    in.close();

    ObjectNode node = new ObjectMapper().readValue(response.toString(), ObjectNode.class);
    JsonNode generatedToken = node.path("response").path("token");

    tokenConn.disconnect();

    return generatedToken.toString();
}

private String getAuthorizationHeaderValue(String user, String pass) {
    return "username=" + user + "; password=" + pass + ";";
}

}


Шаги:

  1. Первый метод fetchVulnerabilities вызовет метод fetchRequest для соединения и результата.
  2. Метод fetchRequest вызовет метод request, а в методе request я установил HttpURLConnection.
  3. 'conn.setRequestProperty ("X-SecurityCenter", generateNewToken (user, pass));' - эта строка в методе 'request' сгенерирует токен (с помощью API генерации токенов) для основного API, чтобы присоединить этот токен в заголовок. Также будет сгенерирован cookie, который также будет установлен в основной API.

После запуска этого метода 'request' я получаю ошибку в методе 'fetchRequest', где я не получаю responseCode как 200. Эта проблема возникает только при самом первом запуске. Если я попытаюсь запустить этот API второй раз, он будет работать нормально.

...