SendHttpRequest() public static method

Sends an http request to the specified uri and returns the response as a byte array
public static SendHttpRequest ( Uri uri, HttpMethod method, Stream requestContent = null, string contentType = null, HttpClientHandler clientHandler = null, string>.Dictionary headers = null ) : Task
uri System.Uri The request uri
method HttpMethod The http method
requestContent Stream A stream containing the request content
contentType string The content type of the http request
clientHandler System.Net.Http.HttpClientHandler The request client handler
headers string>.Dictionary The http headers to append to the request
return Task
Esempio n. 1
0
        private async Task <SPOAuthCookies> GetSPOAuthCookies(SamlSecurityToken stsToken)
        {
            // signs in to SPO with the security token issued by MSO STS and gets the fed auth cookies
            // the fed auth cookie needs to be attached to all SPO REST services requests
            Uri siteUri     = this.spSiteUrl;
            Uri wsSigninUrl = new Uri(String.Format("{0}://{1}/{2}", siteUri.Scheme, siteUri.Authority, spowssigninUri));
            HttpClientHandler clientHandler;

            if (WebRequest.DefaultWebProxy.GetProxy(siteUri).ToString() != siteUri.ToString())
            {
                if (verbose)
                {
                    Console.WriteLine("Using proxy...[" + WebRequest.DefaultWebProxy.GetProxy(siteUri).ToString() + "]");
                }
                clientHandler = new HttpClientHandler();
                WebProxy proxy = new WebProxy((WebRequest.DefaultWebProxy.GetProxy(siteUri)));
                proxy.Credentials           = CredentialCache.DefaultCredentials;
                proxy.UseDefaultCredentials = true;
                clientHandler.UseCookies    = true;
                clientHandler.UseProxy      = true;
                clientHandler.Proxy         = proxy;
            }
            else
            {
                clientHandler = new HttpClientHandler();
            }
            SPOAuthCookies spoAuthCookies = null;

            if (verbose)
            {
                Console.Write("Retrieving Cookies....");
            }
            try
            {
                await HttpUtility.SendHttpRequest(
                    wsSigninUrl,
                    HttpMethod.Post,
                    new MemoryStream(stsToken.Token),
                    "application/x-www-form-urlencoded",
                    clientHandler);

                spoAuthCookies = new SPOAuthCookies();

                spoAuthCookies.FedAuth = clientHandler.CookieContainer.GetCookies(wsSigninUrl)["FedAuth"].Value;
                spoAuthCookies.RtFA    = clientHandler.CookieContainer.GetCookies(wsSigninUrl)["rtFA"].Value;
                spoAuthCookies.Expires = stsToken.Expires;
                spoAuthCookies.Host    = wsSigninUrl;
                if (verbose)
                {
                    Console.WriteLine("[OK]");
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("[ERROR]:" + e.Message);
                throw new Exception("Problems retrieving Cookies.");
            }
            return(spoAuthCookies);
        }
Esempio n. 2
0
        private async Task <string> GetAdfsSAMLTokenUsernamePassword()
        {
            // makes a seurity token request to the corporate ADFS proxy usernamemixed endpoint using
            // the user's corporate credentials. The logon token is used to talk to MSO STS to get
            // an O365 service token that can then be used to sign into SPO.
            string samlAssertion = null;

            // the corporate ADFS proxy endpoint that issues SAML seurity tokens given username/password credentials
            string stsUsernameMixedUrl = String.Format("https://{0}/adfs/services/trust/2005/usernamemixed/", this.adfsAuthUrl.Host);

            // generate the WS-Trust security token request SOAP message passing in the user's corporate credentials
            // and the site we want access to. We send the token request to the corporate ADFS proxy usernamemixed endpoint.
            byte[] requestBody = Encoding.UTF8.GetBytes(ParameterizeSoapRequestTokenMsgWithUsernamePassword(
                                                            "urn:federation:MicrosoftOnline", // we are requesting a logon token to talk to the Microsoft Federation Gateway
                                                            this.username,
                                                            this.password,
                                                            stsUsernameMixedUrl));
            if (verbose)
            {
                Console.Write("Logging in and retrieving SAML Token...");
            }

            try
            {
                byte[] response = await HttpUtility.SendHttpRequest(
                    new Uri(stsUsernameMixedUrl),
                    HttpMethod.Post,
                    new MemoryStream(requestBody),
                    "application/soap+xml; charset=utf-8",
                    null);

                // the logon token is in the SAML assertion element of the message body
                XDocument xDoc      = XDocument.Parse(Encoding.UTF8.GetString(response, 0, response.Length), LoadOptions.PreserveWhitespace);
                var       assertion = from e in xDoc.Descendants()
                                      where e.Name == XName.Get("Assertion", saml)
                                      select e;

                samlAssertion = assertion.FirstOrDefault().ToString();

                // for some reason the assertion string needs to be loaded into an XDocument
                // and written out for for the XML to be valid. Otherwise we get an invalid
                // XML error back from ADFSs
                XDocument doc1 = XDocument.Parse(samlAssertion);
                samlAssertion = doc1.ToString(SaveOptions.DisableFormatting);
                if (verbose)
                {
                    Console.WriteLine("[OK]");
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("[ERROR]:" + e.Message);
                throw new Exception("Problems with authentication or SAML token retrieval");
            }

            return(samlAssertion);
        }
Esempio n. 3
0
        private async Task <Uri> GetAdfsAuthUrl()
        {
            // make a post request with the user's login name to MSO HRD (Home Realm Discovery) service
            // so it can find out the url of the federation service (corporate ADFS) responsible for authenticating the user
            Uri corpAdfsProxyUrl = null;

            if (verbose)
            {
                Console.Write("Retrieving ADFS URL...");
            }

            try
            {
                byte[] response = await HttpUtility.SendHttpRequest(
                    new Uri(msoHrdUrl),
                    HttpMethod.Post,
                    new MemoryStream(Encoding.UTF8.GetBytes(String.Format("handler=1&login={0}", this.username))), // pass in the login name in the body of the form
                    "application/x-www-form-urlencoded",
                    null);

                var serializer           = new JavaScriptSerializer();
                var deserializedResponse = serializer.Deserialize <Dictionary <string, object> >(Encoding.UTF8.GetString(response, 0, response.Length));
                corpAdfsProxyUrl = deserializedResponse.ContainsKey("AuthURL") ? new Uri(deserializedResponse["AuthURL"] as string) : null;
                if (verbose)
                {
                    if (corpAdfsProxyUrl != null)
                    {
                        Console.WriteLine("[OK]");
                    }
                    else
                    {
                        Console.WriteLine("[KO] (Probably not ADFS Federated)");
                    }
                }
            }
            catch (Exception e)
            {
                if (verbose)
                {
                    Console.WriteLine("[ERROR]:" + e.Message);
                }
            }
            if (debug)
            {
                Console.WriteLine("ADFS PROXY URL=[" + corpAdfsProxyUrl + "]");
            }
            return(corpAdfsProxyUrl);
        }
Esempio n. 4
0
        private async Task <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;

            try
            { // find out whether the user's domain is a federated domain
                this.adfsAuthUrl = await 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 = await 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 = await 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)
                {
                    // make the post request to MSO STS with the WS-Trust payload
                    byte[] response = await HttpUtility.SendHttpRequest(
                        new Uri(msoStsUrl),
                        HttpMethod.Post,
                        new MemoryStream(saml11RTBytes),
                        "application/soap+xml; charset=utf-8",
                        null);

                    StreamReader sr = new StreamReader(new MemoryStream(response));

                    // the SAML security token is in the BinarySecurityToken element of the message body
                    XDocument xDoc     = XDocument.Parse(sr.ReadToEnd());
                    var       binaryST = from e in xDoc.Descendants()
                                         where e.Name == XName.Get("BinarySecurityToken", wsse)
                                         select e;

                    // get the security token expiration date from the message body
                    var expires = from e in xDoc.Descendants()
                                  where e.Name == XName.Get("Expires", wsu)
                                  select e;

                    if (binaryST.FirstOrDefault() != null && expires.FirstOrDefault() != null)
                    {
                        samlST.Token   = Encoding.UTF8.GetBytes(binaryST.FirstOrDefault().Value);
                        samlST.Expires = DateTime.Parse(expires.FirstOrDefault().Value);
                    }
                }
                if (verbose)
                {
                    Console.WriteLine("Retrieving STS Token...[OK]");
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Retrieving STS Token...[ERROR]:" + e.Message);
                throw new Exception("Problems retrieving STS Token");
            }
            return(samlST);
        }
Esempio n. 5
0
        private async Task <string> GetAdfsSAMLTokenWinAuth()
        {
            // makes a security token request to the corporate ADFS proxy integrated auth endpoint.
            // If the user is logged on to a machine joined to the corporate domain with her Windows credentials and connected
            // to the corporate network Kerberos automatically takes care of authenticating the security token
            // request to ADFS.
            // The logon token is used to talk to MSO STS to get an O365 service token that can then be used to sign into SPO.

            string samlAssertion = null;

            HttpClientHandler handler = new HttpClientHandler();

            handler.UseDefaultCredentials = true; // use the default credentials so Kerberos can take care of authenticating our request
            if (verbose)
            {
                Console.Write("Logging in and retrieving SAML Token...");
            }
            try
            {
                byte[] stsresponse = await HttpUtility.SendHttpRequest(
                    this.adfsIntegratedAuthUrl,
                    HttpMethod.Get,
                    null,
                    "text/html; charset=utf-8",
                    handler);

                StreamReader sr   = new StreamReader(new MemoryStream(stsresponse));
                XDocument    xDoc = XDocument.Parse(sr.ReadToEnd(), LoadOptions.PreserveWhitespace);

                var body = from e in xDoc.Descendants()
                           where e.Name == XName.Get("body")
                           select e;

                var form = from e in body.FirstOrDefault().Descendants()
                           where e.Name == XName.Get("form")
                           select e;

                // the security token response we got from ADFS is in the wresult input element
                var wresult = from e in form.FirstOrDefault().Descendants()
                              where e.Name == XName.Get("input") &&
                              e.Attribute(XName.Get("name")) != null &&
                              e.Attribute(XName.Get("name")).Value == "wresult"
                              select e;

                if (wresult.FirstOrDefault() != null)
                {
                    // the logon token is in the SAML assertion element
                    XDocument xDoc1     = XDocument.Parse(wresult.FirstOrDefault().Attribute(XName.Get("value")).Value, LoadOptions.PreserveWhitespace);
                    var       assertion = from e in xDoc1.Descendants()
                                          where e.Name == XName.Get("Assertion", saml)
                                          select e;

                    samlAssertion = assertion.FirstOrDefault().ToString();

                    // for some reason the assertion string needs to be loaded into an XDocument
                    // and written out for for the XML to be valid. Otherwise we get an invalid
                    // XML error back from ADFSs
                    XDocument doc1 = XDocument.Parse(samlAssertion);
                    samlAssertion = doc1.ToString(SaveOptions.DisableFormatting);
                }
                if (verbose)
                {
                    Console.WriteLine("[OK]");
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("[ERROR]:" + e.Message);
                throw new Exception("Problems with authentication or SAML token retrieval");
            }

            return(samlAssertion);
        }