I'm working on a VB.NET project (Outlook VSTO) that I want to grab data from Cisco AMP via its API. The issue I'm facing is that although I can successfully authenticate, and I receive a 200 status code, the content length of the response is always -1, and the content I get is always this no matter what information I request from the API: �
I know this is an issue with my VB.NET code because I am able to retrieve the actual information with Python requests with like 2 lines of code and absolutely no issues. According to Cisco AMP's documentation, there are two ways to access the api: either by https://APIGUID:[email protected]/v1/requestedinformation or by http://example.com/v1/requestedinformation with the credentials specified in the headers encoded in base64 (RFC 1945). I can get the proper information with Python from either of these methods, but neither of them work with VB.NET so far.
Here are the two main solutions I have tried in VB.NET, but keep in mind, I have tried both connection methods within each solution I have tried.
Attempt 1 Using WebClient:
Public Sub Test()
Dim url As String = "https://" & apiID & ":" & apiKey & "@" & "api.amp.cisco.com/v1/computers"
MsgBox(url) 'Just to make sure I have the URL properly formatted
'These two lines are needed to avoid SSL validation.
'The network I am working on this from sits behind a proxy for logging reasons,
'so the certificate will not match the domain. This is 100% necessary.
Net.ServicePointManager.ServerCertificateValidationCallback = New Net.Security.RemoteCertificateValidationCallback(Function() True)
Net.ServicePointManager.SecurityProtocol = Net.SecurityProtocolType.Tls12
'I have tried with the Uri data type as well as the url in String format
Dim uri As Uri = New Uri(url)
Dim request As Net.WebClient = New Net.WebClient
'Headers, I copied them verbatim from Python since Python was able to get
'the response content
request.Headers.Add("Accept", "*/*") 'I have also tried application/json here
request.Headers.Add("User-Agent", "python-requests/2.26.0")
request.Credentials = New Net.NetworkCredential(apiID, apiKey)
request.Headers.Add("Authorization", "Basic base64string") 'removed the actual base 64 string for privacy reasons, the actual string is in my code.
request.Headers.Add("Accept-Encoding", "gzip, deflate")
'I have tried DownloadData as well as DownloadString
Dim htmlResponse As String = System.Text.Encoding.UTF8.GetString(request.DownloadData(uri))
'Just using this mail item to display the response content
Dim mail As Outlook.MailItem = Me.Application.CreateItem(Outlook.OlItemType.olMailItem)
mail.HTMLBody = htmlResponse
mail.Display()
End Sub
Attempt 2 Using HTTPWebRequest:
Public Sub Test()
Dim url As String = "https://" & apiID & ":" & apiKey & "@" & "api.amp.cisco.com/v1/computers"
MsgBox(url)
'These two lines are needed to avoid SSL validation.
'The network I am working on this from sits behind a proxy for logging reasons,
'so the certificate will not match the domain. This is 100% necessary.
Net.ServicePointManager.ServerCertificateValidationCallback = New Net.Security.RemoteCertificateValidationCallback(Function() True)
Net.ServicePointManager.SecurityProtocol = Net.SecurityProtocolType.Tls12
'Headers, I copied them verbatim from Python since Python was able to get
'the response content
Dim uri As Uri = New Uri(url)
Dim cookies As Net.CookieContainer = New Net.CookieContainer()
Dim request As Net.HttpWebRequest = Net.HttpWebRequest.Create(uri)
request.CookieContainer = cookies
request.ServicePoint.Expect100Continue = False
request.Accept = "*/*" 'I have also tried application/json here
request.UserAgent = "python-requests/2.26.0"
request.KeepAlive = True
request.Credentials = New Net.NetworkCredential(apiID, apiKey)
request.PreAuthenticate = True
request.Headers.Add("Authorization", "Basic base64string")
request.Headers.Add("Accept-Encoding", "gzip, deflate")
Dim response As Net.HttpWebResponse = request.GetResponse()
Dim reader As StreamReader = New StreamReader(response.GetResponseStream())
Dim htmlResponse As String = reader.ReadToEnd()
MsgBox(response.StatusCode)
'Just using this mail item to display the response content
Dim mail As Outlook.MailItem = Me.Application.CreateItem(Outlook.OlItemType.olMailItem)
mail.HTMLBody = htmlResponse
mail.Display()
End Sub
I've been bashing my head against this for the past few hours, I'm out of ideas at this point. Am I doing something stupid or is there some limitation of VB.NET I'm not aware of?
CodePudding user response:
As it turns out, the solution was quite simple. Either of the above will work, I just needed to remove the Accept-Encoding
header.
Note that I added it in the first place because:
- Cisco AMP's API states that the
Accept-Encoding: gzip
header is needed - Python used that exact header and was able to retrieve the data
Really not sure why this is the case, but at any rate, it works now.