在具有外部身份验证的 iframe 中使用 Datazen

Using Datazen in an iframe with external authentication

我能够通过 VB.NET 的代码隐藏通过 HTTPWEBREQUEST 成功地使用 datazen 的外部身份验证,但我不清楚如何将其与 iframe 甚至 div 一起使用。我在想也许授权 cookies/token 没有跟随 iframe? datazen 开始正确加载,但随后它重定向回登录页面,就好像它没有经过身份验证一样。不知道该怎么做,这些东西对我来说很新,任何帮助将不胜感激!!

网页错误包括:

-OPTIONS url send @ jquery.min.js:19b.extend.ajax @jquery.min.js:19Viewer.Controls.List.ajax @Scripts?page=list:35Viewer.Controls.List.load @Scripts?page=list:35h.callback @Scripts?page=list:35 VM11664 about:srcdoc:1

XMLHttpRequest 无法加载 http://datazenserver.com/viewer/jsondata。预检响应具有无效的 HTTP 状态代码 405Scripts?page=list:35

load(): 无法加载 JSON 数据。 V…r.C…s.List {version: "2.0", description: "KPI & dashboard list loader & controller", url: "/viewer/jsondata", index: "/viewer/", json: null…}(匿名函数) @Scripts?page=list:35c @ jquery.min.js:4p.fireWith @ jquery.min.js:4k @ jquery.min.js:19r @ jquery.min.js:19 脚本?page=list:35

GET http://datazenserver.com/viewer/login 403(禁止)(匿名函数)@Scripts?page=list:35c @jquery.min.js:4p.fireWith @jquery.min.js :4k @ jquery.min.js:19r @ jquery.min.js:19

            ' ''//////////////////////////////////
            Dim myHttpWebRequest As HttpWebRequest = CType(WebRequest.Create("http://datazenserver.com/"), HttpWebRequest)
            myHttpWebRequest.CookieContainer = New System.Net.CookieContainer()

            Dim authInfo As String = Session("Email")


            myHttpWebRequest.AllowAutoRedirect = False

            myHttpWebRequest.Headers.Add("headerkey", authInfo)
            myHttpWebRequest.Headers.Add("Access-Control-Allow-Origin", "*")
            myHttpWebRequest.Headers.Add("Access-Control-Allow-Headers", "Accept, Content-Type, Origin")
            myHttpWebRequest.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")

            Dim myHttpWebResponse As HttpWebResponse = CType(myHttpWebRequest.GetResponse(), HttpWebResponse)
            Response.AppendHeader("Access-Control-Allow-Origin", "*")

            ' Create a new 'HttpWebRequest' Object to the mentioned URL.

            ' Assign the response object of 'HttpWebRequest' to a 'HttpWebResponse' variable.
 
            Dim streamResponse As Stream = myHttpWebResponse.GetResponseStream()
            Dim streamRead As New StreamReader(streamResponse)


            frame1.Page.Response.AppendHeader("Access-Control-Allow-Origin", "*")
            frame1.Page.Response.AppendHeader("headerkey", authInfo)
            frame1.Attributes("srcdoc") = "<head><base href='http://datazenserver.com/viewer/' target='_blank'/></head>" & streamRead.ReadToEnd()

您可能需要做更多这样的事情 client-side,出于安全考虑,我不知道您是否能够这样做。

Datazen 中的外部身份验证如下所示:

User-Agent         |  Proxy               |  Server
-------------------|----------------------|------------------------------------
1. /viewer/home   --> 2.  Append header  --> 3.  Check cookie (not present)
                  <-- 5.  Forward        <-- 4.  Redirect to /viewer/login

6. /viewer/login  --> 7.  Append header  --> 8.  Append cookie
                  <-- 10. Forward        <-- 9.  Redirect to /viewer/home

11. /viewer/home  --> 12. Append header  --> 13. Check cookie (valid)
                  <-- 15. Forward        <-- 14. Give content

16. .................. Whatever the user wanted ..........................

因此,即使您正在使用 header 代理,您仍然会得到它使用的 cookie。

现在,这只是上下文。

根据您对症状的描述,我的猜测是 myHttpWebResponse 应该有一个 cookie 集(DATAZEN_AUTH_TOKEN,我相信),但它基本上被扔掉了——您没有在任何地方使用它。

您需要告诉您的浏览器客户端将该 cookie 附加到对您的 Datazen 服务器域的任何后续 (iframe-based) 请求中,但由于安全限制,我认为这是不可能的。不过,我对 CORS 了解不多,所以可能有办法允许它。

我不知道这里有没有什么好的方法可以做你想做的事。充其量,我也许能想到一个可行的 hack 的开始,但我什至找不到一个好的方法来实现它,你真的不想去那里。

基本上,如果您希望将 Datazen 嵌入到 iframe 中,我会回避外部身份验证。无论如何我都会回避它,但尤其是那里。

但是,如果您绝对确定您需要它而不是像 ADFS 这样的东西,您将需要一些方法将该 cookie 放入您的 iframe 请求中。


我能想到的唯一方法是将所有内容放在同一个域中:

  • www.example.com
  • datazen.example.com(可能是你的代理)

然后您可以根据您的响应设置一个 cookie,该 cookie 存储某种加密(并且可能过期)形式的 Session("Email"),并将其传回您的 html。

这使您的 iframe 相对简单,因为您可以告诉它加载查看器主页。效果为:

<iframe src="//datazen.example.com/viewer/home"></iframe>

在您的代理中,您将检测您的网络服务器设置的 cookie,解密电子邮件令牌,确保它没有过期,然后在 Datazen 服务器的后续请求中设置 header。

这可以在几个地方进行简化,但这应该尽可能符合您的原始实施,只要您可以弄乱 DNS 设置。


我想这个的另一个版本可能涉及将参数传递给您的代理,并共享一些通用的加密密钥。这将使您不必在同一域中。

所以如果你有类似的东西:

var emailEncrypted = encrypt(Session("Email") + ":somesalt:" + DateTime.UtcNow.ToString("O"));

然后使用您想设置 iframe 的任何模板语言:

<iframe src="//{{ customDomain }}/viewer/home?emailkey={{ emailEncrypted }}"></iframe>

然后您的代理检测到 emailkey 参数,对其进行解密,并检查是否过期,这可能会起作用。

现在你可以选择如何处理这个问题,因为 Datazen 会给你一个 302 到 /viewer/login 来获取 cookie,你需要确保传递正确的 emailkey 通过那个。

  1. 我会做的是,您可以在代理中接受 emailkey 参数,自己设置一个全新的 cookie,然后在后续请求中观察该 cookie。

    尽管到那时,将您的外部身份验证模式切换为仅使用 cookie 可能是合理的。无论如何,这可能是一个更好的版本,假设这是您唯一使用 Datazen 的地方,并且您可以安全地更改如此基本的东西。这将大大减少您的业务逻辑。

    但是,您不必这样做。如果你不想改变它,你可以只检查 cookie,然后把它变成 header.

  2. 你应该做 (1),但为了更好的衡量,有一件事我不确定,你是否可以将用户直接传递给 /viewer/login 以从中获取 cookie数据禅。通常你不会,但看起来你应该可以。

    假设它按预期工作,您可以将 URL 换掉。据我所知(虽然我必须 double-check 这个),header 实际上只需要一次,来设置 cookie。所以如果你这样做了,你应该得到cookie,然后就不再需要URL参数了,所以强制导航就不用担心了。

当然,您会希望确保您拥有良好的加密形式,并且过期模式很重要。但如果你做对了,你应该能够确保这一点。

我最后只抓取了用户名和密码字段并用 javascript 输入它们。但是这个 piece 对我帮助很大。您必须确保设置

document.domain ='basedomain.com';

在两个站点的 javascript 中才能访问 iframe 内容,否则您将 运行 陷入跨域问题。