在具有外部身份验证的 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
通过那个。
我会做的是,您可以在代理中接受 emailkey
参数,自己设置一个全新的 cookie,然后在后续请求中观察该 cookie。
尽管到那时,将您的外部身份验证模式切换为仅使用 cookie 可能是合理的。无论如何,这可能是一个更好的版本,假设这是您唯一使用 Datazen 的地方,并且您可以安全地更改如此基本的东西。这将大大减少您的业务逻辑。
但是,您不必这样做。如果你不想改变它,你可以只检查 cookie,然后把它变成 header.
你应该做 (1),但为了更好的衡量,有一件事我不确定,你是否可以将用户直接传递给 /viewer/login
以从中获取 cookie数据禅。通常你不会,但看起来你应该可以。
假设它按预期工作,您可以将 URL 换掉。据我所知(虽然我必须 double-check 这个),header 实际上只需要一次,来设置 cookie。所以如果你这样做了,你应该得到cookie,然后就不再需要URL参数了,所以强制导航就不用担心了。
当然,您会希望确保您拥有良好的加密形式,并且过期模式很重要。但如果你做对了,你应该能够确保这一点。
我最后只抓取了用户名和密码字段并用 javascript 输入它们。但是这个 piece 对我帮助很大。您必须确保设置
document.domain ='basedomain.com';
在两个站点的 javascript 中才能访问 iframe 内容,否则您将 运行 陷入跨域问题。
我能够通过 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
通过那个。
我会做的是,您可以在代理中接受
emailkey
参数,自己设置一个全新的 cookie,然后在后续请求中观察该 cookie。尽管到那时,将您的外部身份验证模式切换为仅使用 cookie 可能是合理的。无论如何,这可能是一个更好的版本,假设这是您唯一使用 Datazen 的地方,并且您可以安全地更改如此基本的东西。这将大大减少您的业务逻辑。
但是,您不必这样做。如果你不想改变它,你可以只检查 cookie,然后把它变成 header.
你应该做 (1),但为了更好的衡量,有一件事我不确定,你是否可以将用户直接传递给
/viewer/login
以从中获取 cookie数据禅。通常你不会,但看起来你应该可以。假设它按预期工作,您可以将 URL 换掉。据我所知(虽然我必须 double-check 这个),header 实际上只需要一次,来设置 cookie。所以如果你这样做了,你应该得到cookie,然后就不再需要URL参数了,所以强制导航就不用担心了。
当然,您会希望确保您拥有良好的加密形式,并且过期模式很重要。但如果你做对了,你应该能够确保这一点。
我最后只抓取了用户名和密码字段并用 javascript 输入它们。但是这个 piece 对我帮助很大。您必须确保设置
document.domain ='basedomain.com';
在两个站点的 javascript 中才能访问 iframe 内容,否则您将 运行 陷入跨域问题。