我正在一个项目中集成Tenable.sc(这是网络监视工具)和ServiceNow(用于事件创建的SaaS工具)。我正在使用tenable.sc API从Tenable获取漏洞分析数据并将其存储在Postgres DB中。我的问题与Java HttpURLConnection和Cookie管理器有关。
我正在使用以下代码通过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 + ";";
}
}
步骤:
运行此“请求”方法后,我在“ fetchRequest”方法中遇到错误,但没有得到responseCode为200。仅在第一次运行时才出现此问题。如果我第二次尝试启动此API,则效果很好。