0

我们在本地使用嵌入式 STS 来测试我们的 ASP.Net Web 应用程序。我正在创建一个控制台应用程序来调用一些 WebAPI 方法并对我们的应用程序进行一些负载测试。我想使用一组具有特定权限的用户进行测试。对于我们的本地实例,这意味着针对 EmbeddedSTS 进行身份验证。

如何编写 HttpClient 来针对 EmbeddedSTS 进行身份验证以接收此令牌并针对我的 WebAPI 端点进行身份验证?

编辑:如果我在 HTTP 模式(不是 HTTPS)下运行应用程序时可以获得 SAML 令牌,则可以加分。

4

2 回答 2

1

我想出了如何做到这一点。

警告:这仅用于一次性控制台应用程序,它允许我们针对 EmbeddedSTS 进行身份验证并执行 WebAPI 调用以进行压力测试。

本质上,我们模拟浏览器上会发生什么。这使用 HttpClient 和 HtmlAgilityPack 解析 HTML 响应,选择用户,将其发布回 EmbeddedSTS,然后发布 WS Fed 令牌结果并最终接收 FedAuth cookie。之后,可以使用 HTTP 客户端调用应用程序中的任何 WebAPI 或 MVC 页面。

    public static Task<HttpClient> BuildClient(string authurl, string username)
    {
        var task = Task.Run<HttpClient>(async () =>
        {
            // setup http client an cookie handler
            var handler = new HttpClientHandler();
            handler.AllowAutoRedirect = true;
            handler.CookieContainer = new System.Net.CookieContainer();
            handler.UseCookies = true;
            var client = new HttpClient(handler);
            client.MaxResponseContentBufferSize = 256000;
            client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");
            client.DefaultRequestHeaders.Add("Connection", "Keep-Alive");
            client.DefaultRequestHeaders.ExpectContinue = false;


            // this is the html of the page that has the user dropdown
            var userSelectionPage = await client.GetStringAsync(authurl);
            string actionPathAndQuery = GetAction(userSelectionPage);

            // for the purposes of this sample, we just choose the user called admin
            var postData = new List<KeyValuePair<string, string>>() { 
                new KeyValuePair<string, string>("username", username) 
            };

            // now we post the user name and expect to get the ws fed response
            var wsfedresponse = await client.PostAsync(authurl + actionPathAndQuery, new FormUrlEncodedContent(postData));
            var wsfedcontent = await wsfedresponse.Content.ReadAsStringAsync();

            var namevaluepairs = GetHiddenInputNameValues(wsfedcontent);
            var finalpost = await client.PostAsync(authurl, new FormUrlEncodedContent(namevaluepairs));

            // at this point, the fedauth cookie is set, we are good to go
            return client;
        });
        return task;
    }

    private static string GetAction(string htmlContent)
    {
        var d = new HtmlDocument();
        d.LoadHtml(htmlContent);
        var node = d.DocumentNode.SelectSingleNode("//form[@action]");
        var result = node.GetAttributeValue("action", string.Empty);
        return result;
    }

    private static IEnumerable<KeyValuePair<string, string>> GetHiddenInputNameValues(string htmlContent)
    {
        var d = new HtmlDocument();
        d.LoadHtml(htmlContent);
        var nodes = d.DocumentNode.SelectNodes("//input[@type='hidden']");
        return nodes.Select(p => 
            new KeyValuePair<string, string>(
                p.GetAttributeValue("name", string.Empty),
                System.Web.HttpUtility.HtmlDecode(p.GetAttributeValue("value", string.Empty))
        ));
    }
于 2014-08-01T12:22:08.883 回答
0

EmbeddedSts 执行 ws-federation。这不是为 Web API 设计的。你宁愿想要 Oauth2。

于 2014-08-01T09:27:42.047 回答