Unable to get FEDAuth via VBA (Excel O365) from SharePoint Online - vba

I am trying - since days - to get an FEDAuth cookie from my SharePoint Online Server via VBA.
As a guide i use https://allthatjs.com/2012/03/28/remote-authentication-in-sharepoint-online/
From STS i get the response and the BinarySecurityToken.
With this token i build my POST-request to https://yourdomain.sharepoint.com/_forms/default.aspx?wa=wsignin1.0
The response (status 200) is every time an access deny-page without any cookie.
Here ist the VBA-code for this request:
Private Function GetAuthCookies(token, tendant, hostnameServer As String) As String
'implemented here: (->)
'1. Send SAML Request including username, password to Microsoft Online {STS}
'2. recieve Response including security token
'3. -> send secutity Token to SharePoint Online
'4. -> recieve authentication token
'5. send the request including athentication token... thats it!
Dim Request As Object
Dim RequestStr, Cookie As String
Dim DomainURL As String
Set Request = CreateObject("WinHttp.WinHttpRequest.5.1")
DomainURL = "https://" & tendant & ".sharepoint.com/_forms/default.aspx?wa=wsignin1.0"
RequestStr = "t=" & token
Request.Open "POST", DomainURL, False
Request.setRequestHeader "Host", hostnameServer
Request.setRequestHeader "User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)"
'Request.setRequestHeader "Content-Type", "text/html; charset=UTF-8"
Request.setRequestHeader "Content-Type", "text/html"
Request.setRequestHeader "Content-Length", CStr(Len(RequestStr))
Request.send (RequestStr)
Debug.Print RequestStr
Debug.Print Request.Status
Debug.Print Len(RequestStr)
If Request.Status = 200 Then
GetAuthCookies = Request.responseText
Debug.Print Request.responseText
'extract cookies tbd after positive response
End If
End Function
The RequestStr looks like:
t=EwDwAk6hBwAU... ...HwYSZL5gNgI=&p=
and hostnameServer looks like:
tendant & ".sharepoint.com"
If i go to my server via browser, i see the same behavior for the root-page (access deny page). But on the subsites e.g /sites/CA-AZ/ i have my access and in my browser i see the FEDAuth-cookie when i examine the website via edge browser.
I think the basic issue is: no access on the root-site - maybe i have to add something to identify my "point of interest" in the POST-request (/sites/CA-AZ/) ?
For the solutions i am resticted to VBA in Excel - company restrictions for my issues.
Thanks for support :-)

Related

Http request VBA response

Making my first steps on HTTP within VBA.
Already managed to get cookie value in order to make a request. The problem I'm having is that the file I want to download is not in the first response. When I analyse using HTTP Header Live, the browser receives several responses and only the last one is the file, a PDF that is generated after a query sent by the user. The only thing I'm getting is the first response that I'm displaying with a MsgBox. Can someone help me solving this problem. Made some searches through the web but haven't found yet, a solution.
The code I am using is:
Sub Test()
Dim WinHttpReq As Object
Set WinHttpReq = CreateObject("WinHTTP.WinHTTPrequest.5.1")
With WinHttpReq
.Open "POST", myURL, False ', "username", "password"
.send
x = .getResponseHeader("Set-Cookie")
i = InStr(x, ";")
x = Left(x, i - 1)
MsgBox x
End With
With WinHttpReq
.Open "GET", myURL, False
.Option(WinHttpRequestOption_EnableRedirects) = True
.SetRequestHeader "Content-Type", "application/pdf"
.SetRequestHeader "Accept-Encoding", "gzip, deflate, br"
.SetRequestHeader "Cookie", x
.SetRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0"
.send
End With
MsgBox (WinHttpReq.getAllResponseHeaders())
If WinHttpReq.Status = 200 Then
Set oStream = CreateObject("ADODB.Stream")
With oStream
.Type = 1
.Open
.Write WinHttpReq.responseBody
.SaveToFile "C:\Users\xxx\Desktop\file.pdf", 2
.Close
End With
End If
Set WinHttpReq = Nothing
Set oStream = Nothing
End Sub
Analyzing with Firefox, when I enter the URL, I receive two responses with 200 OK. I wonder how can I get the second response? The site uses a javascript that interprets the query I send and returns a PDF file. The file name changes according to the user and the query.
Now, i reached the following point. I make a first request to get the cookie, then a second to get an ETag from a diferent address. The problem is that when i make the third request to download the file, the filename is apparently generated by the server (APACHE?), based on the ETag and something I'm not being able to find. The last 5 numbers from the ETag change in the filename.
For example:
ETag - 1543932096000
File - 1543932095115.xxxxx.address.com.5245.idp.pdf
Since I don't have the filename, i cannot download the file with an httprequest.
Help?

How do I receive and send messages through Bot Telegram in Excel VBA?

I wish I could use some macros to send Dashboard summary text over the work Telegram. I know that for me to send by telegram through webhook (GET and POST html) and I researched and found this topic here:
How can I send an HTTP POST request to a server from Excel using VBA?
Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP")
URL = "https://api.telegram.org/bot<token>/METHOD_NAME"
objHTTP.Open "POST", URL, False
objHTTP.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
objHTTP.send("")
Replacing < Token > and < Method_name >
https://core.telegram.org/bots/api
However, when I debug the code it locks up excel and does not come back anymore. Any idea what that might be?
It worked when I deployed MSXML2.ServerXMLHTTP to MSXML2.ServerHTTP60.
Sub fff()
Set objHTTP = CreateObject("MSXML2.ServerHTTP60")
URL = "https://api.telegram.org/bot<token>/sendMessage?chat_id="id"&text=test"
objHTTP.Open "POST", URL, False
objHTTP.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
objHTTP.send ("")
Cells(1, 1).Value = objHTTP.ResponseText
End Sub

403 Error on HTTP request

I have searched for similar "403" threads but could not find an answer.
I have the following URL which is valid and working -
www.investing.com/equities/apple-computer-inc-earnings
And my code:
Sub GetSourceCode()
Dim XMLHTTP As Object
Dim URL As String
Dim data As String
URL = "http://www.investing.com/equities/apple-computer-inc-earnings"
Set XMLHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
XMLHTTP.Open "GET", URL, False
XMLHTTP.send
data = XMLHTTP.responseText
End Sub
However, The string "data" is returned with a "403 Forbidden" error instead of the source code, which is what I am trying to achieve.
Any solution or a workaround (or a duplicate reference) would be highly appreciated.
Thanks
set request header just before .send
XMLHTTP.SetRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"

WinHTTP Request GET is not retrieving the response in Excel VBA

I have a macro which is triggering a GET call to the portal. Below is the URL structure:
https://{P_URL_PORT}/ibm/console/status?text=true&type=cluster&name={P_CELL}&time={tStamp}
Here is my macro.
Dim WinHttpReq As Object
Set WinHttpReq = CreateObject("WinHttp.WinHttpRequest.5.1")
WinHttpReq.Open "GET", strURL, False, userNTID, userPassword
WinHttpReq.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
WinHttpReq.Send
result1 = WinHttpReq.responseText
But I am not getting expected response. It is displaying the Login Screen response. I have tried adding POST method where it will send the Login URL, Username, and password. But still the GET call is not retrieving the actual response.
The open function for WinHttpRequest does not take username and password as parameters. If you are able to automatically login to the site in Internet Explorer then you may use those settings by SetAutoLogonPolicy()
Caveat: Automatic login would imply not due to cookie but by the proxy settings. At times you can auto-login to a site because browser has remembered your last login.
To be sure:- Close all browser windows. Open Private Window. If you auto-login now it means it is set in Internet Options and SetAutoLogonPolicy() should work.
Dim URL As String
URL = "" 'provide URL
Dim HDoc As HTMLDocument
Dim whr As New WinHttpRequest
whr.Open "GET", URL, False
whr.SetRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
whr.SetAutoLogonPolicy AutoLogonPolicy_Always
whr.Send
In case you need to login you supply the credentials, then use SetCredentials(). A good example of such request can be found here

xmlHttp to download file

Using google chrome i fill in a form and upon pressing the submit button a spreadhsheet automatically starts downloading. I have identified the POST sent to the server but somehow when i send the same request from my script the response is not a file but the original web form. Please see below the request as shown in Chrome :
Remote Address: ****** -- Request URL:* --
Request Method: POST -- Status Code: 200 OK --**
Request Headers
-Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
-Accept-Encoding:gzip,deflate,sdch
-Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
-Cache-Control:max-age=0
-Connection:keep-alive
-Content-Length:207
-Content-Type:application/x-www-form-urlencoded
-Cookie:JSESSIONID=*******; ssoLang=en
-Host:*******
-Origin:******
-Referer:*******
-User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36
Query String Parameters
Form Data : REQUEST
Response Headers
-Content-Disposition: filename="xxx.xlsx"
-Content-Type:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
-Date:Sat, 31 May 2014 14:28:25 GMT
-Server:Apache-Coyote/1.1
-Transfer-Encoding:chunked
The response headers I am getting are different :
-Cache-Control: no-cache, no-store
-Date: Sat, 31 May 2014 14:55:38 GMT
-Pragma: no-cache Transfer-Encoding: chunked
-Content-Type: text/html;charset=UTF-8 Expires: Thu, 01 Jan 1970 00:00:00 GMT
-Server: Apache-Coyote/1.1
The script i attempted to do the above is below, can anybody please point out what is wrong here ?
Sub Download_File()
Dim localFile As String, URL As String, request As String
localFile = ThisWorkbook.Path & "\test.xlsx"
URL = ****SENSITIVE***
Dim XMLreq As Object
Set XMLreq = CreateObject("MSXML2.XMLHTTP")
request = ****REQUEST*****
Dim fileNum As Integer, bytes() As Byte
With XMLreq
.Open "POST", URL, False
.setRequestHeader "Host", ****SENSITIVE***
.setRequestHeader "Connection", "keep-alive"
.setRequestHeader "Content-Length", "207"
.setRequestHeader "Cache-Control", "max-age=0"
.setRequestHeader "Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
.setRequestHeader "Origin", ****SENSITIVE***
.setRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36"
.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
.setRequestHeader "Referer", ****SENSITIVE***
.setRequestHeader "Accept-Encoding", "gzip,deflate,sdch"
.setRequestHeader "Accept-Language", "en-GB,en-US;q=0.8,en;q=0.6"
.setRequestHeader "Cookie", "JSESSIONID=****SENSITIVE***; ssoLang=en"
.send (Escape(request))
While .readyState <> 4: DoEvents: Wend
If .Status = 200 Then
Debug.Print .getAllResponseHeaders
fileNum = FreeFile
Open localFile For Binary Access Write As #fileNum
bytes = .responseBody
Put #fileNum, , bytes
Close #fileNum
Else
MsgBox "XMLhttp POST error " & .statusText & vbCrLf & "Status = " & .Status & vbCrLf & "URL = " & URL
End If
End With
End Sub
Private Function Escape(ByVal URL As String) As String
Dim i As Integer, BadChars As String
BadChars = "<>%=&!##£$^()+{[}]|\;:'"",/?"
For i = 1 To Len(BadChars)
URL = Replace(URL, Mid(BadChars, i, 1), "%" & Hex(Asc(Mid(BadChars, i, 1))))
Next i
URL = Replace(URL, " ", "+")
Escape = URL
End Function
This is not a complete answer but more like a comment. I do not have enough reputation to leave a comment.
The response looks like you are redirected to the web form when some checks or authentication fails. Did you check the JSESSIONID cookie? That should be different for each time you logon to the server. Once you manually login and then capture the JSESSIONID cookie (either using Fiddler as Alex mentioned) or by typing javascript:alert(document.cookie); in the browser address bar and pressing enter, you might be able to reuse the same session token.
Also check the content length to ensure that the url-encoded content length matches this value. You can use the composer feature in Fiddler to test POST queries to the server to get the request parameters correct.
BTW, Fiddler installation folder can be copied to a USB stick and used as a portable installation. You might try that as well.
Edit: Looking further, the issue seems to be that the site requires a correct Referer header for sending out the excel file. As unsafe headers like Referer cannot be set for XMLHttp request, this might cause server side authentication failure and it might send you the initial landing page which is the web form here. Check this answer here