Skip to content

Instantly share code, notes, and snippets.

@sanatgersappa
Created November 7, 2012 10:10
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save sanatgersappa/4030649 to your computer and use it in GitHub Desktop.
Save sanatgersappa/4030649 to your computer and use it in GitHub Desktop.
Querying Sharepoint on Office365 with Go
package main
import (
"fmt"
"io/ioutil"
"net/http"
"log"
"regexp"
"strings"
)
//set credentials and site endpoint here.
var options = map[string]string{
"username": "user@mysite.onmicrosoft.com",
"password": "mypassword",
"endpoint": "https://mysite.sharepoint.com/_forms/default.aspx?wa=wsignin1.0",
"siteservice": "https://mysite.sharepoint.com/_vti_bin/ListData.svc/",
}
func main() {
getData()
}
//generate the saml xml string to be sent to the auth service.
func generateSAML() string {
content := `<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><s:Header><a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</a:Action><a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></a:ReplyTo><a:To s:mustUnderstand="1">https://login.microsoftonline.com/extSTS.srf</a:To><o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><o:UsernameToken><o:Username>[username]</o:Username><o:Password>[password]</o:Password></o:UsernameToken></o:Security></s:Header><s:Body><t:RequestSecurityToken xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust"><wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"><a:EndpointReference><a:Address>[endpoint]</a:Address></a:EndpointReference></wsp:AppliesTo><t:KeyType>http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey</t:KeyType><t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType><t:TokenType>urn:oasis:names:tc:SAML:1.0:assertion</t:TokenType></t:RequestSecurityToken></s:Body></s:Envelope>`
for key, val := range options {
content = strings.Replace(content, "["+key+"]", val, -1)
}
return content
}
//send the saml and receive the auth token
func getToken() string {
saml := generateSAML()
resp, err := http.Post("https://login.microsoftonline.com/extSTS.srf", "text/xml", strings.NewReader(saml))
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
token := regexp.MustCompile("<wsse:BinarySecurityToken Id=\"Compact0\">(.*?)</wsse:BinarySecurityToken>")
return token.FindStringSubmatch(string(body))[1]
}
//send the auth token to the sharepoint site auth endpoint and receive auth cookies
func getAuthCookies() []*http.Cookie {
token := getToken()
resp, err := http.Post(options["endpoint"], "text/plain", strings.NewReader(token))
if err != nil {
log.Fatal(err)
}
return resp.Cookies()
}
//send a request to the sharepoint list service using the auth cookies
func getData() {
client := new(http.Client)
cookies := getAuthCookies()
req, _ := http.NewRequest("GET", options["siteservice"], nil)
req.Header = map[string][]string{
"Accept": {"application/json"},
}
req.AddCookie(cookies[1]) //rtFa cookie
req.AddCookie(cookies[2]) //FedAuth cookie
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment