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); }
private SpoAuthUtility(Uri spSiteUrl, string username, string password, bool useIntegratedWindowsAuth, bool verbose) { this.verbose = verbose; this.spSiteUrl = spSiteUrl; this.username = username; this.password = password; this.useIntegratedWindowsAuth = useIntegratedWindowsAuth; stsAuthToken = new SamlSecurityToken(); }
public async Task <CookieContainer> GetCookieContainer() { if (stsAuthToken != null) { if (DateTime.Now > stsAuthToken.Expires) { this.stsAuthToken = await GetMsoStsSAMLToken(); SPOAuthCookies cookies = await GetSPOAuthCookies(this.stsAuthToken); CookieContainer cc = new CookieContainer(); Cookie samlAuthCookie = new Cookie("FedAuth", cookies.FedAuth) { Path = "/", Expires = this.stsAuthToken.Expires, Secure = cookies.Host.Scheme.Equals("https"), HttpOnly = true, Domain = cookies.Host.Host }; cc.Add(this.spSiteUrl, samlAuthCookie); Cookie rtFACookie = new Cookie("rtFA", cookies.RtFA) { Path = "/", Expires = this.stsAuthToken.Expires, Secure = cookies.Host.Scheme.Equals("https"), HttpOnly = true, Domain = cookies.Host.Host }; cc.Add(this.spSiteUrl, rtFACookie); this.cookieContainer = cc; } } return(this.cookieContainer); }
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); }
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; }
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; }
public async Task<CookieContainer> GetCookieContainer() { if (stsAuthToken != null) { if (DateTime.Now > stsAuthToken.Expires) { this.stsAuthToken = await GetMsoStsSAMLToken(); SPOAuthCookies cookies = await GetSPOAuthCookies(this.stsAuthToken); CookieContainer cc = new CookieContainer(); Cookie samlAuthCookie = new Cookie("FedAuth", cookies.FedAuth) { Path = "/", Expires = this.stsAuthToken.Expires, Secure = cookies.Host.Scheme.Equals("https"), HttpOnly = true, Domain = cookies.Host.Host }; cc.Add(this.spSiteUrl, samlAuthCookie); Cookie rtFACookie = new Cookie("rtFA", cookies.RtFA) { Path = "/", Expires = this.stsAuthToken.Expires, Secure = cookies.Host.Scheme.Equals("https"), HttpOnly = true, Domain = cookies.Host.Host }; cc.Add(this.spSiteUrl, rtFACookie); this.cookieContainer = cc; } } return this.cookieContainer; }