Jupyterhub: Embedding jupyterhub in iframe

Created on 13 Jan 2016  路  53Comments  路  Source: jupyterhub/jupyterhub

I have embedded jupyter notebook inside iframe, It's working fine. Now, I am trying to embed Jupyterhub inside iframe. But, getting error "Blocked by Content Security Policy". Is Any way to do this?

Most helpful comment

I found out the easiest way to config, it should work in almost all situation.
add this to your jupyterhub_config.py:

c.Spawner.args = ['--NotebookApp.tornado_settings={"headers":{"Content-Security-Policy": "frame-ancestors * self host_ip:port"}}']   

c.JupyterHub.tornado_settings = { 'headers': { 'Content-Security-Policy': "frame-ancestors * self host_ip:port"} }

change host_ip and port .It works for me.

@djknight1

All 53 comments

@rgbkrk do you remember any gotchas for this one?

@minrk @rgbkrk I have tried configuration setting:

c.JupyterHub.tornado_settings = { 'headers': { 'Content-Security-Policy': "frame-ancestors 'self' 'ec2-url:9000/analytics/notebook' " } }

It didn't work. Same thing i have tried in notebook it is working fine.

The single user notebook servers will also need the Content Security Policy set.

The notebook config for each server will need to have the same setting:

c.NotebookApp.tornado_settings = {
    'headers': {
        'Content-Security-Policy': "frame-ancestors 'self' 'ec2-url:9000/analytics/notebook' "
  }
}

@rgbkrk Where, I will set this config ?

How are you launching the single user servers? Is this the default JupyterHub setup or are you using one of the custom spawners?

@rgbkrk I am using the default JupyterHub setup.

Hi JupyterHUB team, our development team is really stuck and was wondering if there is someway you can help or point us to perhaps a consultant that we can hire that could help us troubleshoot the issue that @satendrakumar06 posted above. We are getting error "Blocked by Content Security Policy" when embedding JupyterHub in an IFRAME. Any help you can provide us would be greatly appreciated. Thank you.

+1 for this. We are trying to get jupyterhub in an iframe. We tried the

'Content-Security-Policy': "frame-ancestors 'self' 'ec2-url:9000/analytics/notebook' "

Maybe I don't have the url right? Jupyterhub is being served at port 8000, with a base url of ipython.

@jerowe did you have any luck on this? I am not sure or posts are going noticed.

Sorry for the slow response. I tested this myself a bit, and I discovered a few things:

  1. I don't think a path should be in the
  2. when I test, I cannot seem to get both 'self' _and_ an alternate host to work.

So while the following doesn't work:

'Content-Security-Policy': "frame-ancestors 'self' 'ec2-url:9000/analytics/notebook' "

This does:

'Content-Security-Policy': "frame-ancestors 'ec2-url:9000' "

Full config:

c.JupyterHub.tornado_settings = {
    'headers': {
        'Content-Security-Policy': "frame-ancestors 'ec2-url:9000'",
    }
}

Note that you will have to set this for _both_ the Hub itself and the single-user servers (e.g. in /etc/jupyter/jupyter_notebook_config.py)

@minrk Thanks!!! It is working fine.

Thanks for confirming that it works!

I can't understand _why_ 'self' 'host'doesn't work, since the src-list spec seems to suggest that it should, but I've at least tested both 'self' 'host' and 'host' 'self', and in both cases the first value was used and the second ignored, in both Chrome and Firefox. Maybe it's a bug, and maybe it's my misunderstanding of the spec.

No joy for me. I'm still getting a Blocked by Content Security Policy.

Tested and working with 7.2

jupyter_notebook_config.py:

c.NotebookApp.tornado_settings = {
    'headers': {
        'Content-Security-Policy': "frame-ancestors 'self' http://parenturl.com "
    }
}

jupyterhub_config.py:

c.JupyterHub.tornado_settings = {
    'headers': {
        'Content-Security-Policy': "frame-ancestors 'self' http://parenturl.com"
  }
}

May I know which location to edit the jupyter_notebook_config.py? I was able to embed the login in iFrame (after editing jupyterhub_config.py) but after user logs in, I got the content-security-policy issue. I edited the jupyter_notebook_config.py inside /root/.jupyter.

It depends on how you run your notebook server, by default it's ~/.jupyter. See http://jupyter.readthedocs.io/en/latest/projects/jupyter-directories.html for more info. How have you configured jupyterhub to spawn new notebooks?

@shusson ,Thank you very much ,your setting is work for me !

I am trying to embed the jupyterhub in an iframe in a portal. After logging into the jupyterhub I am getting the error :
Refused to display 'http://host_ip:8000/user/user_name/tree?redirects=1' in a frame because an ancestor violates the following Content Security Policy directive: "frame-ancestors 'self'".

I have put the below tornado settings in notebook as well as jupyterhub .py files
jupyter_notebook_config.py:
c.NotebookApp.tornado_settings = {
'headers': {
'Content-Security-Policy': "frame-ancestors 'self' "
}
}
jupyterhub_config.py:
c.JupyterHub.tornado_settings = {
'headers': {
'Content-Security-Policy': "frame-ancestors 'self' "
}
}

The same setting was working for jupyter notebook but login was not there.

Any clue for this ?

@TapasSpark : Hi
Try this:

c.NotebookApp.tornado_settings = {
'headers': {
'Content-Security-Policy': "frame-ancestors 'host_ip:8000' "
}
c.JupyterHub.tornado_settings = {
    'headers': {
        'Content-Security-Policy': "frame-ancestors 'host_ip:8000'",
    }
}

Hi satendrakumar,
with the suggested settings the login page itself is not getting loaded into iframe. I tried with below type of tornado settings for jupyterhub.
1)
c.JupyterHub.tornado_settings = {
'headers': {
'Content-Security-Policy': "frame-ancestors 'http://host_ip:8000'",
}
}
2)
c.JupyterHub.tornado_settings = {
'headers': {
'Content-Security-Policy': "frame-ancestors 'host_ip:8000'",
}
}

@satendrakumar ,
With the below settings the login page is getting embedded in iframe but after login it becomes blank and the error appears in console: Refused to display 'http://host_ip:8000/user/user_name/tree?redirects=1' in a frame because an ancestor violates the following Content Security Policy directive: "frame-ancestors 'self'".

c.JupyterHub.tornado_settings = {
'headers': {
'Content-Security-Policy': "frame-ancestors * 'self' "
}
}

Have you tried this ?

c.JupyterHub.tornado_settings = {
'headers': {
'Content-Security-Policy': "frame-ancestors 'host_ip:8000'",
}
}

@satendrakumar,
Yes I had tried that one too.

It is working for me. @minrk Any suggestion ?

@TapasSpark,
in order for this configuration to work, the host hostname:ip should not be single quoted.

So use

'Content-Security-Policy': "frame-ancestors host_ip:8000 ;",

instead of

'Content-Security-Policy': "frame-ancestors 'host_ip:8000'",

I got the same problem with @TapasSpark . By using

'Content-Security-Policy': "frame-ancestors host_ip:8000 ;",

Error
Refused to display 'http://ABC:8713/user/yucol/tree?' in a frame because an ancestor violates the following Content Security Policy directive: "frame-ancestors 'self'".

Any suggestions?

Hi @minrk,

I have installed jupyterhub on Linux machine on EC2 within user name ec2-user. In the jupyterhub configuration I allowed to add user as a Linux machine user when we add user in jupyterhub using API. After adding the user I created the new notebook and generate the token of the same user. I used Iframe to show the notebook with another user but getting the content security policy issue. I tried to all suggested solution but not success please provide the solution of this issue.

I had the same issue and came up with this configuration after reading the answers above. Might be helpful for those of you trying to run JupyterHub on Kubernetes.

Hi @satendrakumar ,

I have same issue.
Have you find a solution?

embedding https://dmain/hub/login is okay
but https://dmain/user/user_name/tree?redirects=1 got error, "an ancestor violates the following Content Security Policy directive: "frame-ancestors 'self'".

My jupyterhub_config.py setting file:

c.JupyterHub.tornado_settings={
  'headers':{
    'Content-Security-Policy': "frame-ancestors *;"
  }
}

c.NotebookApp.tornado_settings={
  'headers':{
    'Content-Security-Policy': "frame-ancestors *;"
  }
}

I'm guessing I need to edit some place other than jupyterhub_config.py because my config file even don't have "self".

Thanks, I figured out my problem.

It turned out I needed to set _c.NotebookApp.tornado_settings_ in docker images' jupyter_notebook_config.py.

And looks like avoiding double quotation marks make src-list work.

Worked

c.JupyterHub.tornado_settings = {
    'headers': {
        'Content-Security-Policy': 'frame-ancestors self http://localhost:3000',
    }
}

Not worked. 2nd src was not taken

c.JupyterHub.tornado_settings = {
    'headers': {
        'Content-Security-Policy': "frame-ancestors 'self' 'http://localhost:3000'",
    }
}

Hi ,
I have embedded jupyterhub with LDAP authentication in iframe of my web application. But eeverytime jupyterhub loads the login page is prompted. I want the users should login seamlessly without the login page presented to them and simultaneously the LDAP authetication of jupyterhub should happen. Is this achievable ? If somebody has already done this, please suggest some ways to do this.

Thanks

None of these suggestions worked work for me except for this one:
'Content-Security-Policy': "frame-ancestors * 'self' "

all of this does not work for me.
My environment is created by virtualenv, c.NotebookApp.tornado_settings has no effect on this problem when I add this to jupyterhub_config.py. Where can I set this attribute since there is no jupyter_notebook_config.py ?
or can I pass it by c.Spawner.args?

@kouohhashi it still cant work.. Would you mind post your both jupyterhub and jupyter notebook code?

@2efPer yeah. It happens to me now. Do you solve this yet?

@2efPer @djknight1 For me putting jupyter_notebook_config.py at /etc/jupyter/jupyter_notebook_config.py worked. To test maybe you can use "frame-ancestors *;" (might be easier to check if it works at all)

@vladmihaisima Thanks for replying.It works only if using jupyter notebook锛宨t failed when i use jupyterhub.

@djknight1 I have used the docker image at https://hub.docker.com/r/jupyterhub/jupyterhub/, changed both the jupyterhub config (at /srv/jupyterhub/jupyterhub_config.py) and the jupyter notebooks config (at /etc/jupyter/jupyter_notebook_config.py), without any other change (local spawner) and it worked for me to be accessed via an iframe.

@vladmihaisima Thanks.I will try.

I found out the easiest way to config, it should work in almost all situation.
add this to your jupyterhub_config.py:

c.Spawner.args = ['--NotebookApp.tornado_settings={"headers":{"Content-Security-Policy": "frame-ancestors * self host_ip:port"}}']   

c.JupyterHub.tornado_settings = { 'headers': { 'Content-Security-Policy': "frame-ancestors * self host_ip:port"} }

change host_ip and port .It works for me.

@djknight1

@2efPer I tried this and restarted docker, but this did not work for me.

In kubernetes:

hub:
  extraConfig:
    hub: |
      c.JupyterHub.tornado_settings = { "headers": { "Content-Security-Policy": "frame-ancestors 'self' http://www.my_address.com:80"}}   <---  or https and any other port
     spawner: >-
       c.Spawner.args = ["--NotebookApp.tornado_settings={\"headers\":{\"Content-Security-Policy\": \"frame-ancestors 'self' http://www.my_address.com:80\"}}" ] 

@taposh I guess we have to use same domains for both the sites..

In kubernetes:

hub:
  extraConfig:
    hub: |
      c.JupyterHub.tornado_settings = { "headers": { "Content-Security-Policy": "frame-ancestors 'self' http://www.my_address.com:80"}}   <---  or https and any other port
     spawner: >-
       c.Spawner.args = ["--NotebookApp.tornado_settings={\"headers\":{\"Content-Security-Policy\": \"frame-ancestors 'self' http://www.my_address.com:80\"}}" ] 

^^ this worked for me. Wondering, how do you include multiple iframe URLs (not just www.my_address.com)?

@maluhoss I believe you can just separate each URL with a space:

frame-ancestors 'self' http://www.my_address.com:80 http://www.myotheraddress.com

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors#Syntax

If you are using nginx as a reverse proxy you can rewrite the policy there without having to fiddle with the jupyterhub machinery

proxy_hide_header Content-Security-Policy;  
proxy_set_header Content-Security-Policy "frame-ancestors 'self' http://parenturl.com;";

In kubernetes:

hub:
  extraConfig:
    hub: |
      c.JupyterHub.tornado_settings = { "headers": { "Content-Security-Policy": "frame-ancestors 'self' http://www.my_address.com:80"}}   <---  or https and any other port
     spawner: >-
       c.Spawner.args = ["--NotebookApp.tornado_settings={\"headers\":{\"Content-Security-Policy\": \"frame-ancestors 'self' http://www.my_address.com:80\"}}" ] 

Need remove \" and reformat yaml.

This below works for me:

hub:
  extraConfig:
    hub: |
      c.JupyterHub.tornado_settings = { 'headers': { 'Content-Security-Policy': 'frame-ancestors self http://domain.com'}}
    spawner: |
      c.Spawner.args = ['--NotebookApp.tornado_settings={"headers":{"Content-Security-Policy": "frame-ancestors * self http://domain.com"}}']

I found out the easiest way to config, it should work in almost all situation.
add this to your jupyterhub_config.py:

c.Spawner.args = ['--NotebookApp.tornado_settings={"headers":{"Content-Security-Policy": "frame-ancestors * self host_ip:port"}}']   

c.JupyterHub.tornado_settings = { 'headers': { 'Content-Security-Policy': "frame-ancestors * self host_ip:port"} }

change host_ip and port .It works for me.

@djknight1

THANKS !!!!

I found out the easiest way to config, it should work in almost all situation.
add this to your jupyterhub_config.py:

c.Spawner.args = ['--NotebookApp.tornado_settings={"headers":{"Content-Security-Policy": "frame-ancestors * self host_ip:port"}}']   

c.JupyterHub.tornado_settings = { 'headers': { 'Content-Security-Policy': "frame-ancestors * self host_ip:port"} }

change host_ip and port .It works for me.
@djknight1

THANKS !!!!

Can you please share the .py file for reference.

ok, so I guess in the "frame-ancestors 'self' http://www.my_address.com:80" from the example http://www.my_address.com:80 would just be the https://<renku-host>, at least whenever we use path based routing?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

spalkovits picture spalkovits  路  22Comments

ponomarevsy picture ponomarevsy  路  42Comments

AndreWin picture AndreWin  路  23Comments

statueofmike picture statueofmike  路  27Comments

elgalu picture elgalu  路  47Comments