简体   繁体   English

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

[英]Using Datazen in an iframe with external authentication

I was able to successfully use external authentication with datazen via HTTPWEBREQUEST from code-behind with VB.NET, but I am unclear how to use this with an iframe or even a div. 我能够通过VB.NET的后台代码通过HTTPWEBREQUEST成功地对datazen使用外部身份验证,但是我不清楚如何在iframe甚至div中使用它。 I'm thinking maybe the authorization cookies/token isn't following the iframe around? 我在想,授权cookie /令牌是否不遵循iframe? The datazen starts to load correctly, but then it redirects back to the login page as if it's not being authenticated. datazen开始正确加载,但随后将重定向回登录页面,就像未通过身份验证一样。 Not sure how to do that part, this stuff is pretty new to me and any help would be greatly appreciated!! 不知道该怎么做,这东西对我来说还很新,任何帮助将不胜感激!

Web page errors include: 网页错误包括:

-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 -OPTIONS url发送@ 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 =列表:35 VM11664关于:srcdoc:1

XMLHttpRequest cannot load http://datazenserver.com/viewer/jsondata . XMLHttpRequest无法加载http://datazenserver.com/viewer/jsondata Response for preflight has invalid HTTP status code 405Scripts?page=list:35 飞行前响应具有无效的HTTP状态代码405Scripts?page = list:35

load(): Failed to load JSON data. load():无法加载JSON数据。 V…rC…s.List {version: "2.0", description: "KPI & dashboard list loader & controller", url: "/viewer/jsondata", index: "/viewer/", json: null…}(anonymous function) @ Scripts?page=list:35c @ jquery.min.js:4p.fireWith @ jquery.min.js:4k @ jquery.min.js:19r @ jquery.min.js:19 Scripts?page=list:35 V…rC…s.List {版本:“ 2.0”,描述:“ KPI和仪表板列表加载器和控制器”,网址:“ / viewer / jsondata”,索引:“ / viewer /”,json:null…}(匿名函数)@ Scripts?page = list:35c @ jquery.min.js:4p.fireWith @ jquery.min.js:4k @ jquery.min.js:19r @ jquery.min.js:19 Scripts?page = list: 35

GET http://datazenserver.com/viewer/login 403 (Forbidden)(anonymous function) @ Scripts?page=list:35c @ jquery.min.js:4p.fireWith @ jquery.min.js:4k @ jquery.min.js:19r @ jquery.min.js:19 GET http://datazenserver.com/viewer/login 403(禁止使用)(匿名函数)@脚本?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() 

You might have to do more of this client-side, and I don't know whether you'll be able to because of security concerns. 您可能需要在此客户端上做更多的事情,并且由于安全问题,我不知道您是否能够这样做。

External authentication in Datazen looks something like this: 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 ..........................

So even though you're working off a proxy with a header, you're still getting a cookie back that it uses. 因此,即使您正在使用带有标头的代理,也仍在获取它使用的cookie。

Now, that's just context. 现在,这只是上下文。

My guess, from your description of the symptoms, is that myHttpWebResponse should have a cookie set ( DATAZEN_AUTH_TOKEN , I believe), but it's essentially getting thrown out--you aren't using it anywhere. 根据症状的描述,我的猜测是myHttpWebResponse应该具有cookie集( DATAZEN_AUTH_TOKEN ,我相信),但是它实际上已经被淘汰了-您在任何地方都没有使用它。

You would need to tell your browser client to append that cookie to any subsequent (iframe-based) requests to the domain of your Datazen server, but I don't believe that's possible due to security restrictions. 您需要告诉浏览器客户端将该Cookie附加到对Datazen服务器域的任何后续(基于iframe)请求中,但是由于安全限制,我认为这是不可能的。 I don't know a whole lot about CORS, though, so there might be a way to permit it. 但是,我对CORS并不了解很多,因此可能有一种允许的方式。

I don't know whether there's any good way to do what you're looking to do here. 我不知道是否有什么好的方法可以完成您要在这里做的事情。 At best, I can maybe think of a start to a hack that would work, but I can't even find a good way to make that work, and you really wouldn't want to go there. 充其量,我也许可以想到一个可以奏效的骇客,但我什至找不到找到实现该目的的好方法,而且您真的不想去那里。

Essentially, if you're looking to embed Datazen in an iframe, I would shy away from external authentication. 本质上,如果您希望将Datazen嵌入到iframe中,则可以避免使用外部身份验证。 I'd shy away from it regardless, but especially there. 无论如何,我都会回避它,尤其是在那里。

But, if you're absolutely sure you need it over something like ADFS, you'll need some way to get that cookie into your iframe requests. 但是,如果您绝对确定需要ADFS之类的东西,那么您将需要某种方式将Cookie放入iframe请求中。


The only way I can think to make this work would be to put everything on the same domain: 我能想到的唯一方法是将所有内容都放在同一个域中:

  • www.example.com
  • datazen.example.com (which is probably your proxy) datazen.example.com (可能是您的代理)

You could then set a cookie from your response that stores some encrypted (and likely expiring) form of Session("Email") , and passes it back down in your html. 然后,您可以从响应中设置一个cookie,该cookie存储一些加密的(可能已过期) Session("Email") ,并将其传递回html中。

That makes your iframe relatively simple, because you can just tell it to load the viewer home. 这使您的iframe相对简单,因为您可以告诉它将查看器加载到首页。 Something to the effect of: 效果:

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

In your proxy, you'll detect the cookie set by your web server, decrypt the email token, ensure it isn't expired, then set a header on the subsequent request onto the Datazen server. 在您的代理中,您将检测到Web服务器设置的cookie,解密电子邮件令牌,确保它没有过期,然后在对Datazen服务器的后续请求上设置标头。

This could be simplified at a couple places, but this should hold as true as possible to your original implementation, as long as you can mess with DNS settings. 这可以在几个地方进行简化,但是只要您可以破坏DNS设置,它就应该尽可能符合您最初的实现。


I suppose another version of this could involve passing a parameter to your proxy, and sharing some common encryption key. 我想这的另一个版本可能涉及将参数传递给您的代理,并共享一些通用的加密密钥。 That would get you past having to be on the same domain. 那将使您过去不必在同一域中。

So if you had something like: 因此,如果您有类似以下内容:

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

Then used whatever templating language you want to set your iframe up with: 然后使用您要设置iframe的任何模板语言:

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

Then your proxy detected that emailkey parameter, decrypted it, and checked for expiration, that could work. 然后,您的代理检测到该emailkey参数,对其进行解密,然后检查其有效期,该参数可以正常工作。

Now you'd have a choice to make on how to handle this, because Datazen will give you a 302 to /viewer/login to get a cookie, and you need to make sure to pass the correct emailkey on through that. 现在,您可以选择如何处理此问题,因为Datazen将为您提供一个302到/viewer/login来获取cookie,并且您需要确保将正确的emailkey传递给它。

  1. What I would do, you could accept that emailkey parameter in your proxy, set a completely new cookie yourself, then watch for that cookie on subsequent requests. 我要做的是,您可以在代理中接受该emailkey参数,自己设置一个全新的cookie,然后在后续请求中监视该cookie。

    Although at that point, it would probably be reasonable to switch your external authentication mode to just use cookies. 尽管在那时,将外部身份验证模式切换为仅使用cookie可能是合理的。 That's probably a better version of this anyway, assuming this is the only place you use Datazen, and you'd be safe to change something so fundamental. 无论如何,这可能是一个更好的版本,假设这是您唯一使用Datazen的地方,并且可以安全地更改如此基本的内容。 That would substantially reduce your business logic. 那会大大减少您的业务逻辑。

    But, you wouldn't have to. 但是,您不必。 If you didn't want to change that, you could just check for the cookie, and turn it into a header. 如果您不想更改它,则只需检查cookie,然后将其转换为标题即可。

  2. You should do (1), but just for good measure, one thing I'm not sure on, is whether you can pass users directly to /viewer/login to get a cookie from Datazen. 您应该执行(1),但出于很好的考虑,我不确定是否可以将用户直接传递到/viewer/login来从Datazen获取cookie,这只是出于很好的考虑。 Normally you wouldn't, but it seems like you should be able to. 通常您不会,但是似乎应该可以。

    Assuming it works as expected, you could just swap that URL out for that. 假设它能按预期工作,则只需为此替换掉该URL。 As far as I know (although I'd have to double-check this), the header is actually only necessary once, to set up the cookie. 据我所知(尽管我必须仔细检查),标题实际上只需要设置一次cookie。 So if you did that, you should get the cookie, then not need the URL parameter anymore, so the forced navigation would be no concern. 因此,如果这样做了,您应该获取cookie,然后不再需要URL参数,因此不必担心强制导航。

You'll, of course, want to make sure you've got a good form of encryption there, and the expiration pattern is important. 当然,您将要确保那里有一个良好的加密形式,并且到期模式很重要。 But you should be able to secure that if you do it right. 但是,如果您做对了,您应该能够确保这一点。

I ended up just grabbing the username and password fields and entering them in with javascript. 我最终只是抓住了用户名和密码字段,并使用javascript输入它们。 But this piece helped me a ton. 但是这件作品帮助了我很多。 You have to make sure you set the 您必须确保设置了

 document.domain ='basedomain.com'; 

in javascript on both sites in order to access the iframe contents else you'll run into the cross-domain issues. 在这两个网站上的javascript中,为了访问iframe内容,否则您将遇到跨域问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM