private SamlSecurityToken GetMsoStsSAMLToken() { // Makes a request that conforms with the WS-Trust standard to // Microsoft Online Services Security Token Service to get a SAML // security token back so we can then use it to sign the user to SPO SamlSecurityToken samlST = new SamlSecurityToken(); byte[] saml11RTBytes = null; string logonToken = null; // find out whether the user's domain is a federated domain this.adfsAuthUrl = GetAdfsAuthUrl(); // get logon token using windows integrated auth when the user is connected to the corporate network if (this.adfsAuthUrl != null && this.useIntegratedWindowsAuth) { UriBuilder ub = new UriBuilder(); ub.Scheme = this.adfsAuthUrl.Scheme; ub.Host = this.adfsAuthUrl.Host; ub.Path = string.Format("{0}auth/integrated/", this.adfsAuthUrl.LocalPath); // specify in the query string we want a logon token to present to the Microsoft Federation Gateway // for the corresponding user ub.Query = String.Format("{0}&wa=wsignin1.0&wtrealm=urn:federation:MicrosoftOnline", this.adfsAuthUrl.Query.Remove(0, 1)). Replace("&username="******"&username={0}", this.username)); this.adfsIntegratedAuthUrl = ub.Uri; // get the logon token from the corporate ADFS using Windows Integrated Auth logonToken = GetAdfsSAMLTokenWinAuth(); if (!string.IsNullOrEmpty(logonToken)) { // generate the WS-Trust security token request SOAP message passing in the logon token we got from the corporate ADFS // and the site we want access to saml11RTBytes = Encoding.UTF8.GetBytes(ParameterizeSoapRequestTokenMsgWithAssertion( this.spSiteUrl.ToString(), logonToken, msoStsUrl)); } } // get logon token using the user's corporate credentials. Likely when not connected to the corporate network if (logonToken == null && this.adfsAuthUrl != null && !string.IsNullOrEmpty(password)) { logonToken = GetAdfsSAMLTokenUsernamePassword(); // get the logon token from the corporate ADFS proxy usernamemixed enpoint if (logonToken != null) { // generate the WS-Trust security token request SOAP message passing in the logon token we got from the corporate ADFS // and the site we want access to saml11RTBytes = Encoding.UTF8.GetBytes(ParameterizeSoapRequestTokenMsgWithAssertion( this.spSiteUrl.ToString(), logonToken, msoStsUrl)); } } if (logonToken == null && this.adfsAuthUrl == null && !string.IsNullOrEmpty(password)) // login with O365 credentials. Not a federated login. { // generate the WS-Trust security token request SOAP message passing in the user's credentials and the site we want access to saml11RTBytes = Encoding.UTF8.GetBytes(ParameterizeSoapRequestTokenMsgWithUsernamePassword( this.spSiteUrl.ToString(), this.username, this.password, msoStsUrl)); } if (saml11RTBytes != null) { Uri MsoSTSUri = new Uri(msoStsUrl); HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(MsoSTSUri); byte[] responseData = HttpHelper.SendHttpRequest( MsoSTSUri, "POST", saml11RTBytes, "application/soap+xml; charset=utf-8", request, null).Response; StreamReader sr = new StreamReader(new MemoryStream(responseData), Encoding.GetEncoding("utf-8")); XPathNavigator nav = new XPathDocument(sr).CreateNavigator(); XmlNamespaceManager nsMgr = new XmlNamespaceManager(nav.NameTable); nsMgr.AddNamespace("wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"); XPathNavigator binarySecurityToken = nav.SelectSingleNode("//wsse:BinarySecurityToken", nsMgr); if (binarySecurityToken != null) { string binaryST = binarySecurityToken.InnerXml; nsMgr.AddNamespace("wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"); XPathNavigator expires = nav.SelectSingleNode("//wsu:Expires", nsMgr); if (!String.IsNullOrEmpty(binarySecurityToken.InnerXml) && !String.IsNullOrEmpty(expires.InnerXml)) { samlST.Token = Encoding.UTF8.GetBytes(binarySecurityToken.InnerXml); samlST.Expires = DateTime.Parse(expires.InnerXml); } } else { // We didn't get security token } } return(samlST); }