如何从 OKTA 获取 SAML 响应以进行单元/集成测试

Ty *_*don 5 c# integration-testing unit-testing saml okta

我正在开发一个项目,他们通过 OKTA 的 SAML 进行身份验证。我已成功完成集成工作,其中 SAMLResponse 发送(通过 POST 方法)到网站。

以真正的 TDD 方式,我首先编写一些单元测试。我的单元测试接受 SAMLResponse(采用 Base64 编码)。然而,我的所有单元测试都有效,因为 SAMLResponse 的生命周期(过期)只有几分钟,所以我的单元测试会在几分钟后中断。

因此,我需要定期登录 OKTA,然后使用 Chrome 开发工具捕获发送到我的开发站点的流量。然后,我将 SAMLResponse 复制并粘贴到我的单元测试中,然后继续通过单元测试。显然这不是一个理想的情况。

所以我的问题是如何以自动方式(最好是用 C#)登录 Okta 以获得 SAMLResponse?我假设有一些 URL,我可以使用用户名和密码 POST 并获取 SAMLReponse。我所有的 Fiddler 试图理解所需通信的尝试都让我感到沮丧。我正在寻找您可能有的任何指导。提前致谢。

Ty *_*don 5

我提出了一个可行的解决方案,并想与社区分享。 我不确定根据其他作者(Jo\xc3\xabl Franusic)的有用反馈来回答我自己的问题的协议。如果我违反了协议,请告诉我。

\n\n

感谢 Jo\xc3\xabl Franusic 的指点。我实现了他的 1.2 解决方案(带有 Okta 客户端的用户代理) 在他的参考资料和 Okta 网站上的其他一些文档之间,我最终能够拼凑出工作代码。

\n\n
private static async Task<string> GetTestSamlResponse()\n    {\n        try\n        {\n            // settings specific to my Okta instance\n            string username = "USERNAME GOES HERE";\n            string password = "PASSWORD GOES HERE";\n            var apiToken = "API TOKEN GOES HERE";\n\n            // this is the unique domain issued to your account.  \n            // If you setup a dev account you\'ll have a domain in the form https://dev-<AccountNumber>.oktapreview.com.\n            // account number is a unique number issues by Okta when you sign up for the account\n            var baseUrl = "YOUR BASE URL GOES HERE";\n\n            // In Okta Admin UI, click "Applications" in main menu, choose your app, click "Sign On" tab.  Under Sign On Methods, then under SAML 2.0, click "View Setup Instructions"\n            // Get the url called "Identity Provider Single Sign-On URL", paste it in th below line\n            var ssoUrl = "YOUR SSO URL GOES HERE";\n\n            // construct an Okta settings object\n            var settings = new Okta.Core.OktaSettings\n            {\n                ApiToken = apiToken,\n                BaseUri = new Uri(baseUrl)\n            };\n\n            // get session token from Okta\n            var authClient = new Okta.Core.Clients.AuthClient(settings);\n            var authResponse = authClient.Authenticate(username, password);\n            var sessionToken = authResponse.SessionToken;\n\n            // start session and get a cookie token\n            var sessionsClient = new Okta.Core.Clients.SessionsClient(settings);\n            var session = sessionsClient.CreateSession(sessionToken);\n            var cookieToken = session.CookieToken;\n\n            // using the cookie token, get the SAMLResponse from Okta via a HTTP GET.\n            var httpClient = new System.Net.Http.HttpClient();\n\n            // add User-Agent header, because apparently Okta is expecting this information.  \n            // If you don\'t pass something, the Okta site will return a 500 - Internal Server error\n            httpClient.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "UnitTest");\n\n            // add the cookie token to the URL query string\n            string url = string.Format("{0}?onetimetoken={1}", ssoUrl, cookieToken);\n\n            // do the HTTP GET\n            using (var response = await httpClient.GetAsync(url))\n            {\n                if (response.StatusCode == HttpStatusCode.OK)\n                {\n                    // read the HTML returned\n                    string html = await response.Content.ReadAsStringAsync();\n\n                    // parse the HTML to get the SAMLResponse (using HtmlAgilityPack from NuGet)\n                    HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();\n                    htmlDoc.LoadHtml(html);\n                    // from the input field called SAMLResponse, get the "value" attribute\n                    string samlResponse = htmlDoc.DocumentNode.SelectSingleNode("//input[@name=\'SAMLResponse\']").Attributes["value"].Value;\n                    return samlResponse;\n                }\n                else\n                    throw new Exception(string.Format("Error getting SAML Response {0}", response.StatusCode));\n            }\n        }\n        catch (Exception ex)\n        {\n            throw;\n        }\n    }\n
Run Code Online (Sandbox Code Playgroud)\n