Ejemplo n.º 1
0
        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);
        }