无需登录即可登录login.microsoftonline.com

时间:2018-03-22 17:12:37

标签: c# oauth-2.0 active-directory httpwebrequest fiddler

这个问题让我忙了好几天,所以我也可以在这里发帖...在其他主题上搜索给我带来了很多,但我还没到那里。

背景

我的工作是在浏览器中自动化测试:我使用Selenium和.NET来处理这个问题。我们的一个客户使用Active Directory登录Web应用程序。每次测试再次登录需要花费大量时间(每个测试都会启动一个新会话),所以我试图通过编写一个事先登录的类来加速这个阶段,而不需要浏览器。

通过使用Fiddler,我设法在代码中重现大多数webrequests。尽管如此,我不经常使用自定义Web请求,因此我很容易忽略可能出现的问题。在最后一步出现问题,我尝试检索AppServiceAuthSession cookie。我会用图片来说明: enter image description here 在左侧,我使用我的代码创建了Web请求。在右侧,我使用浏览器时会收到Web请求。

Nonce cookie有它的值,标题是正确的......这里唯一的区别是“Expect”标题而不是“Connection”标题,但这是因为我禁用了请求的“AllowAutoRedirect”属性(I如果我启用它,请不要在Fiddler中看到此请求。)

接下来,这两个请求的内容都来了,因为使用Fiddler界面很难显示。

代码请求:

code=AQABAAIAAABHh4kmS_aKT5XrjzxRAtHzZ08Y3xv2A4HxumqfAbR5iIBFEbbm6oYUq5sdHF72ybOkXFz33XVW5uXvuq-Tiz43zQ7y08bAhGH-aR_3HEpugBMAX_Op4O0Z4RjMKOLyd5b-VNVhjqv_CRmgHTEhYnxubjNyaG-5Vsuo7YRa3jXFybBheb73Erp7CDYFCQ-dFjgNAEHEbzrfE64dGVvHCCr-rvpHCTJfW55eYE9l68d7rryVfqC8dX7wplr7A3G8ySS84Tb9_hYxA61L_fQEm22NehWGNKw_MwXWNsIONtwiRd5LQD95iXYwjCw9J1p-WoZw9p6228r8YOuBVJA0k22O_zjqvKGUkVEyVWvAZZvDSO26_m-uuz7ql52ZTfBhmOfF8iXfdgeUPUqSXmTmNtL0LAOgiYKt4DyH1TbgAN2ox-sVcFp0k7bmjE81h0yiY8RgR-a2aONvuIpSR1Dx7VG-1wkllQAkYGV8zMoahs0EVRiDdOEQwwvkegALZNaU_ROKkbxj-H71h7lffkLlZoeM1lQFwgcVyB1_kV04iZKg2x5-VxHRYCDCNdeaxuaZD5dOrxIh_Y6SfQK-VBWsDB1C_i76QQpFI2c-7oxFNn7RLCU5gw7iv8k31ry2-hKSfhcU6LtN--t-eW73ADu0cW9juh1zzgzXAPXz0FqNyh07SyRawPqir9jdZ4GlgU4r-Imm41n4b7LH_nYixE1q-JNTm7TlawW3Xe7i28QMx95wPGlqyYl0PAo0VMwMPgoG3Zi-5BiEFi31qOxCMJNbXWi-YOMMcV3W5-sNbYA44mOUoYnz0hny-PlvKFwTL9RLBxkgAA&
id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IkZTaW11RnJGTm9DMHNKWEdtdjEzbk5aY2VEYyIsImtpZCI6IkZTaW11RnJGTm9DMHNKWEdtdjEzbk5aY2VEYyJ9.eyJhdWQiOiI4NmJiNjljZC04OTQ4LTQ2ZmEtOWQ3NS05YWRiZWRmODI1NWYiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC8xYWNhOGFmYy01YTZlLTRkYWUtOTRhNC0xODIwZDgwNGMxZWIvIiwiaWF0IjoxNTIxNzM2NTM1LCJuYmYiOjE1MjE3MzY1MzUsImV4cCI6MTUyMTc0MDQzNSwiYWlvIjoiQVRRQXkvOEdBQUFBNXhNTk10SUJybUI1Z2dTN0xRNWxmSUNBMnY3RGpBRXIyUzgwS3dBa0VlMlpacVhNQW1hMnE0eG5xeDJ5aGxNZSIsImFtciI6WyJ3aWEiXSwiY19oYXNoIjoiUlUxOHNDNjJldTUyVnd0ZG9CTEItUSIsImVtYWlsIjoiUnViZW4udGVyLk1hdGVuQG1hY2F3Lm5sIiwiaWRwIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvMDViYWVkNGQtZTA0OS00NWM3LWI0N2QtYzk5YzY2ZmRiNTg5LyIsImluX2NvcnAiOiJ0cnVlIiwiaXBhZGRyIjoiODIuMjAxLjExMi40IiwibmFtZSI6IlJ1YmVuIHRlciBNYXRlbiIsIm5vbmNlIjoiYmI2NDU1ZGQzODJkNDRmNGIyNDAwYThjYzY3NmNmNTZfMjAxODAzMjEwOTU3MzAiLCJvaWQiOiI2YjgzMGMyNi1hZGE4LTQyY2MtOTQ3MS1kMzU5NTc1N2IwNDciLCJyb2xlcyI6WyJDb250ZW50RWRpdG9yIl0sInN1YiI6InJIVlJfRFZsWjltN2V5LS02RVE4LUFGY1FVZ3VWa3VRZVdnR3ZVeGdmbE0iLCJ0aWQiOiIxYWNhOGFmYy01YTZlLTRkYWUtOTRhNC0xODIwZDgwNGMxZWIiLCJ1bmlxdWVfbmFtZSI6IlJ1YmVuLnRlci5NYXRlbkBtYWNhdy5ubCIsInV0aSI6InpoRTFLWVRhWGtxS1dWWThqQlFaQUEiLCJ2ZXIiOiIxLjAifQ.xcuSefb-pr21z53eoirQTj3nptW95rQ0RnsxkF6B436Z16bI826UK4wYLvjGl8NrXYV1-sJhlUTUuX31p90GxJthUV1tbzsvFUwNk8f9DJgKls-31X78fNbChkuNDIS9Tj6Lj0cPOlZaC6U8TXYaNsef8qURtvtXzPt7Td1t6rfvuJL29pnow0We7u-eqUR8_TDD9PzY82BdYSbfIn4X-cOw4F79O-OAce9zRebX3V1Cr53gizMUIKKDWlS8fdwKnpdluAgZup-r6RJa7c_ui0NB2REao-PxixkvO-PuCtEfLhRnbRAprVa6ggMlCrtN6Uf7EmLRGLNBGHbl379vgg&
state=redir%3d%252Flogin%252Fcheck&
session_state=4dcbbba5-e8a5-4ad7-9ba9-28f6af570ead

浏览器请求:

code=AQABAAIAAABHh4kmS_aKT5XrjzxRAtHzZT_hGoYPGfSq8uoVwxawNGgqfV8j3-WdO_yha1uD2rspKWZmKjbV4j3YQmg4IQOdNBKzWDYTAST-Shag2D2Ih9EHMThyu7ncE_XRSBDOb_f05q3WCKYtF5ki5VVFcd8Li029KFwEjjutGw4k-_GfPe1rym5CXRvqQzj0wGUN4Q3ndwqrcNXsdvGG6wEXbiTJ8_3aSyuAAsHBMr1l23fjJRe-CKfr7EqKDZLzm_2H6L0MODy_mWkrD715CjU2_mUb1YQ__6MZvhHss41BFPcL3zyK2oh7Z668dJMEK495MhKFt-NPUFUPXsUNwK1fP4F-tdmBIY39BL9vDxzynmcF5A63yb8q3m0CgJOZ0i1aobe1iEX75sNXjIa2385yFw08lmkVJFj9GccvIE5ak4Zi6sdjWhEtS9TyKXc5uBtKxJCYIy52avI6bUAyc5-Xq0amik0Q75wuLK0bSoeIwBofKuJnoHfl1o3_7N2uSZ_2dJx5zPW9VxRz4e6u-mkmDu9F5lK42zo3al8c03zKHhLkTVRx08JV7JZuqpLznz5JFEHp1QUq-KeYNdMXsngPZW3VEegSyu6VGYwvbmL07GYTZ3KWi-dGxej88KvobZF3O40rfISThS4gVpnFoH7UQs_RE_TEjRvUraFBUhjE-1EUd7WXl6NsxQwGO0Uw7W87ZqlY4G-JhN39MOdm4v9UZELmeZph87PWqqy9-6h1pK8wrH8S98HqV1q3DUR68Ue-zCSvV9hgxrkSnPtFDTfCgtOvpNj14GUesMi8L0XPa6DsO0hj27_A1T0STGSHMGg8QMcgAA&
id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IkZTaW11RnJGTm9DMHNKWEdtdjEzbk5aY2VEYyIsImtpZCI6IkZTaW11RnJGTm9DMHNKWEdtdjEzbk5aY2VEYyJ9.eyJhdWQiOiI4NmJiNjljZC04OTQ4LTQ2ZmEtOWQ3NS05YWRiZWRmODI1NWYiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC8xYWNhOGFmYy01YTZlLTRkYWUtOTRhNC0xODIwZDgwNGMxZWIvIiwiaWF0IjoxNTIxNzExMTIxLCJuYmYiOjE1MjE3MTExMjEsImV4cCI6MTUyMTcxNTAyMSwiYWlvIjoiQVRRQXkvOEdBQUFBT1YreEZOcjAwR3R6TG9jdkZaMVZ0SjlIRkYyUjc2VWE4d1V0eGlISkpienU4em1nN2xtRzdPT3ZCelZ6VkpyeiIsImFtciI6WyJ3aWEiXSwiY19oYXNoIjoieThoZUw5RHh3b3ZkUV9IbmtTYzlqZyIsImVtYWlsIjoiUnViZW4udGVyLk1hdGVuQG1hY2F3Lm5sIiwiaWRwIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvMDViYWVkNGQtZTA0OS00NWM3LWI0N2QtYzk5YzY2ZmRiNTg5LyIsImluX2NvcnAiOiJ0cnVlIiwiaXBhZGRyIjoiODIuMjAxLjExMi40IiwibmFtZSI6IlJ1YmVuIHRlciBNYXRlbiIsIm5vbmNlIjoiMDk5MmE5NjQ1N2JiNDA3ZTgxZTYyZjE0YzA0ODg3ZTVfMjAxODAzMjIwOTQxNTIiLCJvaWQiOiI2YjgzMGMyNi1hZGE4LTQyY2MtOTQ3MS1kMzU5NTc1N2IwNDciLCJyb2xlcyI6WyJDb250ZW50RWRpdG9yIl0sInN1YiI6InJIVlJfRFZsWjltN2V5LS02RVE4LUFGY1FVZ3VWa3VRZVdnR3ZVeGdmbE0iLCJ0aWQiOiIxYWNhOGFmYy01YTZlLTRkYWUtOTRhNC0xODIwZDgwNGMxZWIiLCJ1bmlxdWVfbmFtZSI6IlJ1YmVuLnRlci5NYXRlbkBtYWNhdy5ubCIsInV0aSI6IlRFUGhmbG53dGs2YTFKTVJEcHNVQUEiLCJ2ZXIiOiIxLjAifQ.eT25sB0q7a5nEPBS5z2WVFHohBdzgioj6rd5DOMlb30dp1mIAVgvRZxSJhybB6RuHOl86LTkcyH4qzXl8uQ9fq8hapZUdJ2sDDqvk-PmcIWp_Ar6Gyo--4DtUxu7quIe-JaP_HyN_lsNbm0Gxut2VkZuHmCaiBxRriosP2FRg2GyKO75P6V7r0EPmQnS_4HA0WhEUmqNBzrZnbMV4rkc4FkLoMSLgJN69XdBMCQfsnhVcDWFPGj_Q79vlSbSq17Y7EPxn5phkrLGfZGMQj6CNHSzeT76LxR4txUu16QEQLLHckw2aSsESQ8SPFXwk794jEuyFIoFPrGg75hv4XxC7Q&
state=redir%3D%252Flogin%252Fcheck&
session_state=d897cb81-a5db-41f2-8852-8c18a82d36ab

问题

如图所示,Web请求获得没有AppServiceAuthSession的响应,并被重定向到login.windows.net位置。普通的浏览器请求是不同的:此时它是成功的。

问题

有没有人知道这里出了什么问题,或者如何成功调试它?我也对前面请求的输入进行了三重检查,但它们看起来与给浏览器的输入完全相同。即使只是一个指针通常可能有帮助...我在这里有点迷失。如果需要更多信息,请告诉我。提前谢谢!

额外信息

代码,如果有帮助(在需要时进行审查):

class Login
{
    static CookieContainer cookiesNonce = new CookieContainer();
    static CookieContainer cookiesA = new CookieContainer();
    static CookieContainer cookiesB = new CookieContainer();

    public static void DoLogin()
    {
        // CLIENTNAME-api, request for login with redirect
        var url = @"https://CLIENTNAME-api.CLIENTNAME-dev.nl/.auth/login/aad?post_login_redirect_url=/login/check";
        var request = WebRequest.Create(url) as HttpWebRequest;
        request.Accept = @"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8";
        request.UserAgent = @"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36";
        request.Headers.Add("Upgrade-Insecure-Requests", "1");
        request.CookieContainer = new CookieContainer();
        request.KeepAlive = true;
        request.AllowAutoRedirect = false;

        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        {
            cookiesNonce.Add(response.Cookies);
            cookiesA.Add(response.Cookies);

            request = WebRequest.Create(response.Headers[HttpResponseHeader.Location]) as HttpWebRequest;
            request.Accept = @"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8";
            request.UserAgent = @"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36";
            request.Headers.Add("Upgrade-Insecure-Requests", "1");
            request.KeepAlive = true;
            request.Host = @"login.windows.net";
            request.CookieContainer = cookiesA;
        }

        string clientrequestid = "";
        string authorizeUrl = "";
        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        {
            cookiesA = new CookieContainer();
            cookiesA.Add(response.Cookies);
            var reader = new StreamReader(response.GetResponseStream());
            string html = reader.ReadToEnd();
            reader.Close();

            var jsonRegEx = new Regex(@"\$Config=(.*?)(?<=\});");
            var temp = jsonRegEx.Match(html).Groups[1].ToString() ;

            var dict = JObject.Parse(temp);
            var hpgrequestid = response.Headers["x-ms-request-id"];
            var canary = GetValue(dict, "apiCanary");
            clientrequestid = GetClientRequestId(dict);

            authorizeUrl = response.Headers[HttpResponseHeader.Location];

            // Request to microsoft online by credentials
            url = @"https://login.microsoftonline.com/common/GetCredentialType";
            request = WebRequest.Create(url) as HttpWebRequest;
            request.Method = @"POST";
            request.CookieContainer = cookiesB;
            request.KeepAlive = true;
            request.Headers.Add("hpgrequestid", hpgrequestid);
            request.Headers.Add("canary", canary);
            request.Headers.Add("client-request-id", clientrequestid);
            request.Headers.Add("hpgact", "1800");
            request.Headers.Add("hpgid", "1104");
            request.Referer = response.ResponseUri.ToString(); ;
            var reqStream = request.GetRequestStream();
            var buffer = new ASCIIEncoding().GetBytes(@"{""username"":""user@COMPANYNAME.nl"",""isOtherIdpSupported"":true,""checkPhones"":false,""isRemoteNGCSupported"":false,""isCookieBannerShown"":true,""isFidoSupported"":false,""originalRequest"":""rQIIAZ2Qv08UQRzFd26PDaCJxBCD3RUQE83szM7N7s1eQoGCGjEhXAwQLch35wc33rK7zK6i_Ak2YGFjZSwvVlbGP4FGav8CYyOhsvTU-A_YvPeq93l5N_0ojPqLIsmyJJUKi5QLzBMDOFW9GKegMq2MYHFs3NXZOf7jvH3x5dX68Rs2OKYlHaPesGmquk_ISBeFw1DZ8G9S-nlY5CSEZ82Q5OWeLQiAIhLyPAM5-oTQGULfEBq3yITN41iprmCKc8MzxikFIWXSS6SJk11GI0G7LKJp3OvSr60rGyuTVvZbSmeP9EVrxpRuf7cq6-atf81pZd3yErv7BztxOdRyNPav_9u656Aahoe2UOVhHRa6-egvRiBBgJE4hkRjrkDjlAPHkWBUCcplpLNTf76sdGFVp3Klsbnu6H2w-VkbfW9fpn5_enp2zlvwOt7PNno_NfmrXrp08OHJ7dXX714ObnQD73SKkFuDxxUMDF2xxc7W_c2No3zdwc7q5kPxtLmztq22WP3i0ba992BtmfWjkwCdBMF54H2e-d-rfwE1""}");
            reqStream.Write(buffer, 0, buffer.Length);
            reqStream.Close();
        }



        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        {
            cookiesB.Add(response.Cookies);
            var reader = new StreamReader(response.GetResponseStream());
            string html = reader.ReadToEnd();
            reader.Close();

            // Request to sts.COMPANYNAME.nl
            url = @"https://sts.COMPANYNAME.nl/adfs/ls/wia?client-request-id=" + clientrequestid + @"&wa=wsignin1.0&wtrealm=urn%3afederation%3aMicrosoftOnline&wctx=LoginOptions%3D3%26estsredirect%3d2%26estsrequest%3drQIIAZ2QPU8UQRjHd26PDZwmEEOIdldATDSzOzs7uze7CYkoqBETwsUAwYLMzgs33t7uOrt4ykewAQsbK2N5sbIyfgQaqSmtjI2EytJF4xewef5P9X_53bJ9108WaZSmUcwFpDGhkESKwVj0QhgzkUqhKA5DZa515sjP8_bF19frR29x_wgVaAJ6g7ouq8TzhjLPDWSldv9-Qr5w88xz2UE98LJiX-ceY8LjLMtSxoefATgF4DsAk5bXZJMwFCKgWBCiSIoJQoxyHvUirsJoDyOfogD7KA57ATprzW6sNK748hRGH8qL1owqzGivLKr6nb1gpNBmeQnf_xPbKB9IPpzYN_513TesHLhjnYtiXLm5rD_Ziz7jjDLFYcgiCYlgEsaEEehTjARFhPsyPbHni1LmWnRLUyidya4cMZ19s2fNQSrz0Z1RYzJuZp-2wY_2VWQn09OdOeu61bV-tcGHqYZgtXTl-cend1ffvH_Vvxk41smU593u75asr9CKzne2Hm5uHGbrhu2sbj6mz-p7a9tiC1cvn2zrB4_WlnHiHzvg2HHOHevLzP_CP-vMXyKFKIDY76I4CXESkN3f0&cbcxt=&username=user%40COMPANYNAME.nl&mkt=&lc=";
            request = WebRequest.Create(url) as HttpWebRequest;
            cookiesB = new CookieContainer();
            request.CookieContainer = cookiesB;
            request.KeepAlive = true;
            request.Headers.Add("Upgrade-Insecure-Requests", "1");
            request.Referer = response.ResponseUri.ToString(); ;
            request.UserAgent = @"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36";
            request.Credentials = CredentialCache.DefaultNetworkCredentials;
            request.AuthenticationLevel = System.Net.Security.AuthenticationLevel.MutualAuthRequested;
        }

        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        {
            cookiesB.Add(response.Cookies);
            var reader = new StreamReader(response.GetResponseStream());
            string html = reader.ReadToEnd();
            var doc = new HtmlDocument();
            doc.LoadHtml(html);
            var node = doc.DocumentNode.SelectSingleNode("//input[@name='wresult']");
            var value = node.Attributes["value"].Value;
            var decode = HttpUtility.HtmlDecode(value);
            var wresult = HttpUtility.UrlEncode(decode);
            node = doc.DocumentNode.SelectSingleNode("//input[@name='wctx']");
            value = node.Attributes["value"].Value;
            decode = HttpUtility.HtmlDecode(value);
            var wctx = HttpUtility.UrlEncode(decode);
            reader.Close();

            // Logging in to microsoft online
            url = @"https://login.microsoftonline.com/login.srf?client-request-id=" + clientrequestid;
            request = WebRequest.Create(url) as HttpWebRequest;
            request.CookieContainer = cookiesB;
            request.Referer = response.ResponseUri.ToString(); ;
            request.Method = @"POST";
            request.Headers.Add("Upgrade-Insecure-Requests", "1");
            request.KeepAlive = true;
            request.UserAgent = @"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36";
            request.Headers.Add("Origin", "https://sts.COMPANYNAME.nl");
            request.Headers.Add("Cache-Control", "max-age=0");
            request.ContentType = @"application/x-www-form-urlencoded";

            var reqStream = request.GetRequestStream();
            var buffer = new ASCIIEncoding().GetBytes(@"wa=wsignin1.0&wresult=" + wresult + @"&wctx=" + wctx);
            reqStream.Write(buffer, 0, buffer.Length);
            reqStream.Close();
        }

        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        {
            cookiesB = new CookieContainer();
            cookiesB.Add(response.Cookies);
            var reader = new StreamReader(response.GetResponseStream());
            string html = reader.ReadToEnd();
            var doc = new HtmlDocument();
            doc.LoadHtml(html);
            reader.Close();

            var state = GetValue(doc, "state");
            var code = GetValue(doc, "code");
            var idtoken = GetValue(doc, "id_token");
            var session_state = GetValue(doc, "session_state");

            // Callback to .auth/login
            url = @"https://CLIENTNAME-api.CLIENTNAME-dev.nl/.auth/login/aad/callback";
            request = WebRequest.Create(url) as HttpWebRequest;
            request.Method = @"POST";
            request.CookieContainer = new CookieContainer();
            var cookie = cookiesNonce.GetCookies(new Uri("https://CLIENTNAME-api.CLIENTNAME-dev.nl"))["Nonce"];
            request.CookieContainer.Add(cookie);
            request.KeepAlive = true;
            request.Headers.Add("Cache-Control", "max-age=0");
            request.Headers.Add("Origin", "https://login.microsoftonline.com");
            request.Headers.Add("Upgrade-Insecure-Requests", "1");
            request.ContentType = @"application/x-www-form-urlencoded";
            request.UserAgent = @"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36";
            request.Accept = @"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8";
            request.Referer = response.ResponseUri.ToString(); ;
            request.Headers.Add("Accept-Encoding", @"gzip, deflate, br");
            request.Headers.Add("Accept-Language", @"en-US,en;q=0.9");
            request.AllowAutoRedirect = false;

            var reqStream = request.GetRequestStream();
            var buffer = new ASCIIEncoding().GetBytes(@"code=" + code + @"&id_token=" + idtoken + @"&state=" + state + "&session_state=" + session_state);
            reqStream.Write(buffer, 0, buffer.Length);
            reqStream.Close();
        }

        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        {
            var appServiceAuthSession = response.Cookies["AppServiceAuthSession"].ToString();

            var reader = new StreamReader(response.GetResponseStream());
            string html = reader.ReadToEnd();
            reader.Close();
        }
    }

    private static string GetValue(HtmlDocument doc, string name)
    {
        var node = doc.DocumentNode.SelectSingleNode("//input[@name='" + name + @"']");
        var value = node.Attributes["value"].Value;
        var decode = HttpUtility.HtmlDecode(value);
        var result = HttpUtility.UrlEncode(decode);
        return result;
    }

    private static string GetValue(string key, string input, string delimiter)
    {
        var value = RegexHelper.GetValueForKey(input, key, delimiter);
        return value;
    }

    private static string GetValue(JObject container, string key)
    {
        string value = (string)container[key];
        return value;
    }

    private static string GetClientRequestId(JObject container)
    {
        var obj = container["desktopSsoConfig"];
        var value = (string)obj["iwaEndpointUrlFormat"];
        var content = value.Split('&');
        var id = content[content.Length - 1].Replace("client-request-id=", "");
        return id;
    }
}

2 个答案:

答案 0 :(得分:0)

OpenID connect故意不特定于用户身份验证的性质。前提是认证服务将向用户呈现它需要的任何认证,如果这是令人满意的,将发出一个短期代码,该代码被重定向到应用程序。然后,应用程序使用该代码获取令牌。

还有其他流程可用于验证非面向用户的应用程序(如服务)。如果您需要模拟用户登录,那可能对您没有帮助。

由于您已经使用Selenium,为什么不将测试用户凭据输入到Web浏览器窗口中显示的UI中?

答案 1 :(得分:0)

这不是真正的解决方案,但对于我们而言至少是一个有用的解决方法:

  1. 使用浏览器登录。
  2. 导航到“身份验证/我”页面。

示例:假设我必须使用的起始URL是https://company.company-dev.nl。我将网址调整为https://company-api.company-dev.nl/.auth/me并导航到那里。

  1. 从html检索访问令牌。

enter image description here

要读取令牌,我使用了以下代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8" />
  <title>Off-Market-Template</title>
  <link href="./css/idGeneratedStyles.css" rel="stylesheet" type="text/css" />
  <script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
  <script src="./js/script.js" />
  </script>
</head>

<body id="offmarketbrochure-template" lang="en-US">
  <div class="wrapper">
    <header>
      <div id="head_desc">
        <h2>Off-market</h2>
        <p>Confidential </br> Sale Offering</p>
      </div>
      <div id="head_address">
        <h1>Test Address</h1>
        <h2>Chicago IL, 60607</h2>
      </div>
    </header>


    <div class="images">
      <div class="hero-image trailerleft">
        <img src="./Pics/image1.jpg" alt="" class="fillheight" />
      </div>
      <div class="second-image trailerright">
        <img src="./Pics/streetview.jpg" alt="" class="fillwidth" />
      </div>
      <div class="third-image trailerright">
        <img src="./Pics/mapview.png" alt="" class="fillheight" />
      </div>
    </div>

    <div id="greybar" class="Basic-Graphics-Frame _idGenObjectStyleOverride-2">
      <p id="pspecs">
        Property Specifications
      </p>
    </div>

    <div id="contact-section">
      <p class="moreinfo">
        For more information, please contact:
      </p>

      
      <div class="contact-info">
        <h3 class="name">BROKER 1, SIOR</h3>
        <p class="title">Principal</p>
        <p class="phone">312-111-1111</p>
        <p class="email">BROKER EMAIL</p>
      </div>
      
      
      <div class="contact-info">
        <h3 class="name">BROKER 2</h3>
        <p class="title">Principal</p>
        <p class="phone">312-111-1111</p>
        <p class="email">BROKER EMAIL</p>
      </div>
      
      
      <p class="con-address">
        <span>Company <br /></span>
        Address <br />
        Chicago, IL 
      </p>
      <p class="disclaimer">
        All information contained herein is from sources deemed reliable and is submitted subject to errors, omissions and to change of price or terms without notice.
      </p>

    </div>
    <div id="propertyinfo">
      <table id="pitable" cellspacing="0">
        <tbody>
          <!-- Max amount of rows not including comments should be 8 -->
          <!-- Building Size Row -->
          
          
          
          <tr>
            <td class="leftcell">
              Building Size
            </td>
            <td class="rightcell">
              28,106 SF
            </td>
          </tr>
          

          <!-- Land Size Row -->
          
          
          <tr>
            <td class="leftcell">
              Land Size
            </td>
            <td class="rightcell">
              17,860 SF
            </td>
          </tr>
          

          <!-- Stories Row -->
          
          
          <tr>
            <td class="leftcell">
              Stories
            </td>
            <td class="rightcell">
              3
            </td>
          </tr>
          

          <!-- Drive in Row -->
          

          <!-- Docks Row -->
          
          
          <tr>
            <td class="leftcell">
              Loading Docks
            </td>
            <td class="rightcell">
              4 ext
            </td>
          </tr>
          

          <!-- Construction Row -->
          
          
          <tr>
            <td class="leftcell">
              Construction
            </td>
            <td class="rightcell">
              Masonry
            </td>
          </tr>
          

          <!-- Ceiling Height Row -->
          
          
          <tr>
            <td class="leftcell">
              Ceiling Height
            </td>
            <td class="rightcell">
              12'
            </td>
          </tr>
          

          <!-- Elevators Row -->
          <!--  -->

          <!-- Cranes Row -->
          <!-- 
          
          <tr>
            <td class="leftcell">
              Cranes
            </td>
            <td class="rightcell">
              None
            </td>
          </tr>
           -->

          <!-- Power Row -->
          <!--  -->

          <!-- Parking Row -->
          <!-- 
          
          <tr>
            <td class="leftcell">
              Parking
            </td>
            <td class="rightcell">
              8 free Surface Spaces are available; Ratio of 0.28/1,000 SF
            </td>
          </tr>
           -->

          <!-- Ward Row -->
          

          <!-- Zoning Row -->
          
            
            <tr>
              <td class="leftcell">
                Zoning
              </td>
              <td class="rightcell">
                C1-3
              </td>
            </tr>
          

          <!-- Taxes Row -->
          
          
          <tr>
            <td class="leftcell">
              2017 Taxes
            </td>
            <td class="rightcell">
              $46,266.56
            </td>
          </tr>
          

          <!-- Pins Row -->
          


          <!-- Sale Row -->
          
          
          <tr>
            <td class="leftcell">
              Sale Price
            </td>
            <td class="rightcell">
              $2,000,000
            </td>
          </tr>
          


          <!-- lease Row -->
          

          <!-- Comments section -->
          <tr>
            <td class="leftcell comments">
              Comments
            </td>
            <td class="rightcell comments">
              <ul>
                <li>
                  <p>
                    Easily accessible via Ashland Station (Green, Pink Lines), located 0.5 miles away
                  </p>
                </li>
                <li>
                  <p>
                    Located 1.0 miles from the Chicago Ogilvie Transportation Center Commuter station
                  </p>
                </li>
                <li>
                  <p>
                    Excellent location on W Randolph Street
                  </p>
                </li>
              </ul>
            </td>
          </tr>
        </tbody>
      </table>


    </div>
    <footer>

      <div class="footerimage">
        <img src="./Pics/footerlogo.jpg" />
      </div>
      <div class="footerline">

      </div>
      <p id="footerlink">
        www.Website.com
      </p>
    </footer>
  </div>


</body>
</html>
  1. 保存令牌。
  2. 下次测试开始时,请将令牌附加到主网址。

    private string ConvertToken(string html)
    {
        var doc = new HtmlAgilityPack.HtmlDocument();
        doc.LoadHtml(html);
        var timeout = DateTime.Now + TimeSpan.FromSeconds(5);
        dynamic obj = null;
    
        while (obj == null && DateTime.Now < timeout)
        {
            try
            {
                obj = (dynamic)JsonConvert.DeserializeObject(doc.DocumentNode.InnerText);
            }
            catch (Exception ex)
            {
                // Firefox occasionally bugs out if its JSON viewer kicks in too early, so use the according elements if needed
                var element = Driver.FindElementById("rawdata-tab");
                Driver.ClickElement(element);
                var text = Driver.FindElementByClassName("data").Text;
                obj = (dynamic)JsonConvert.DeserializeObject(text);
            }
        }
        return obj[0]["access_token"].ToString();
    }
    

示例:https://company.company-dev.nl/#/login/eyJ0eXAiOiandareallylonglineofcharactershere

这样,您只能进行一个测试登录,而其他登录将使用第一个生成的令牌。您还必须处理其他一些事情(在并行测试中使用令牌,处理令牌超时等),但这是解决方法的核心。