使用SAML令牌中的FedAuth cookie调用UI控制器

时间:2016-05-11 21:52:51

标签: cookies session-cookies saml-2.0 adfs ws-federation

我们正在尝试自动化一些集成测试。因此,我们希望能够以编程方式调用UI控制器,以便像卷轴用户那样使用子句。我们不希望出于不同的原因使用UI测试套件。

问题是我们正在使用带有WIF的WS-Federation安全性的SSO Windows身份验证。在配置中,我们使用passiveRedirectEnabled =“true”,这样每次会话cookie不存在,无效或过期时,页面都会被重定向到AD FS STS端点(“/ adfs / ls /”)。结果再次重定向回Web.config文件的“reply”属性中指定的页面。

当我查看Fiddler时,我清楚地看到第二个重定向(从AD FS STS返回)以302状态向浏览器返回“Set-Cookie:FedAuth = 77u / PD94bWwg ...”指令。调用带有FedAuth cookie的回复页面,从那里一切正常。

有没有办法模拟这种行为,并能够使用正确的FedAuth cookie调用UI控制器?请不要SharePoint,这与它无关。

1 个答案:

答案 0 :(得分:0)

我终于能够重现我在Fiddler中看到的模仿浏览器的步骤。我将代码放在这里,希望它可以帮助你们中的一些人。它不是很干净,它在POC模式下更多,但它仍然可以提供帮助。请注意,在某些请求中,我必须允许自动重定向,其他一些我必须阻止它。

致我的同事多米尼克·波蒂埃(Dominique Pothier)的信任,他帮助了我很多。

//First request to the secured site
        var request =
            (HttpWebRequest)WebRequest.Create("https://mysite.mycompany.ca/");
        request.Method = "GET";
        request.UseDefaultCredentials = true;
        request.PreAuthenticate = true;
        request.AllowAutoRedirect = false;

        var httpResponse = (HttpWebResponse)request.GetResponse();

//Redirects to the STS based on the response from the first call, posting the ws-federations infos along
        request =
            (HttpWebRequest)WebRequest.Create(httpResponse.Headers["Location"]);

        request.UseDefaultCredentials = true;
        request.PreAuthenticate = true;
        request.Host = "sts.mycompany.ca";
        request.AllowAutoRedirect = true;
        request.UserAgent =
            "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36";
        request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";

        var nameValueCollection = new NameValueCollection { { "Cache-Control", "max-age=0" } };
        request.Headers.Add(nameValueCollection);
        nameValueCollection = new NameValueCollection { { "Upgrade-Insecure-Requests", "1" } };
        request.Headers.Add(nameValueCollection);
        nameValueCollection = new NameValueCollection { { "Accept-Encoding", "gzip, deflate, sdch" } };
        request.Headers.Add(nameValueCollection);
        nameValueCollection = new NameValueCollection { { "Accept-Language", "fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4" } };
        request.Headers.Add(nameValueCollection);

        httpResponse = (HttpWebResponse)request.GetResponse();


//Parse the response to get ws-federation infos
        var responseStream = new StreamReader(httpResponse.GetResponseStream());
        var responseData = responseStream.ReadToEnd();
        var xmlReader = XmlReader.Create(new StringReader(responseData));


        var wa = "";
        var wresult = "";
        var wctx = "";

        while (xmlReader.Read())
        {
            if (xmlReader.GetAttribute("name") == "wa")
                wa = xmlReader.GetAttribute("value");
            if (xmlReader.GetAttribute("name") == "wresult")
                wresult = xmlReader.GetAttribute("value");
            if (xmlReader.GetAttribute("name") == "wctx")
                wctx = xmlReader.GetAttribute("value");
        }

        httpResponse.Close();

//Redirects to the controller method we want to hit
        request =
            (HttpWebRequest)WebRequest.Create("https://mysite.mycompany.ca/Home/GetStates");
        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        request.AllowAutoRedirect = false;
        //Add the cookie container to the response so that we can get the FedAuth cookie after the response
        request.CookieContainer = new CookieContainer();

        //Add the ws-federation infos from the last http request to the body of the new request
        using (var streamWriter = new StreamWriter(request.GetRequestStream()))
        {

            if (wa != null)
            {
                var waEncoded = HttpUtility.UrlEncode(wa);
                var wresultEncoded = HttpUtility.UrlEncode(wresult);
                var wctxEncoded = HttpUtility.UrlEncode(wctx);
                var urlEncoded = "wa=" + waEncoded + "&wresult=" + wresultEncoded + "&wctx=" + wctxEncoded;

                streamWriter.Write(urlEncoded);
                streamWriter.Flush();
                streamWriter.Close();
            }
        }
        request.Referer = httpResponse.ResponseUri.OriginalString;

        httpResponse = (HttpWebResponse)request.GetResponse();
        var cookieContainer = request.CookieContainer;

//Use the FedAuth cookie that we got from last http call and add it to a new request to the controller and voila !
        request =
            (HttpWebRequest)WebRequest.Create("https://mysite.mycompany.ca/Home/GetStates");
        request.Method = "GET";
        nameValueCollection = new NameValueCollection { { "X-Requested-With", "XMLHttpRequest" } };
        request.Headers.Add(nameValueCollection);
        //Add the FedAuthCookie from last request
        request.CookieContainer = cookieContainer;
        request.Referer = "https://proacces-dev1.universitas.ca/";

        httpResponse = (HttpWebResponse)request.GetResponse();
        responseStream = new StreamReader(httpResponse.GetResponseStream());
        responseData = responseStream.ReadToEnd();

        Console.WriteLine(responseData);
        Console.ReadLine();