# oauth-azure login's 'hang' after token is returned

**URL:** <https://discourse.jupyter.org/t/oauth-azure-logins-hang-after-token-is-returned/7641>\
**Category:** JupyterHub\
**Created:** [January 25, 2021, 11:10am UTC](https://discourse.jupyter.org/t/oauth-azure-logins-hang-after-token-is-returned/7641 "2021-01-25T11:10:54Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![jim-smith](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/jim-smith/32/3537_2.png) [@jim-smith](https://discourse.jupyter.org/u/jim-smith)\
**Post date:** [January 25, 2021, 11:10am UTC](https://discourse.jupyter.org/t/oauth-azure-logins-hang-after-token-is-returned/7641/1 "2021-01-25T11:10:54Z")

</div>

I have jupyterhub set up on an azure server and working own port 22000.  
I can get other authenticators to work but to make life easier for students I and am trying to get oauth-azure working.  
At the moment when I try to log in it sends me through to our main systems for authentication.  
Looking at their logs it seems the login attempts are successful.  
However the process then just hangs and eventually returns a browser error saying the server can’t be reached.

(I’ve changed the actual domain name to MYDOMAIN and the code, star and session\_state in the message)

Safari can’t open the page “[https://MYDOMAIN:22000/hub/oauth\_callback?code=AAAAA&state=BBBBBB&session\_state=CCCCCC”](https://MYDOMAIN:22000/hub/oauth_callback?code=AAAAA&state=BBBBBB&session_state=CCCCCC%E2%80%9D) because the server where this page is located isn’t responding.

Help needed please: How can I find out where the process is stalled?

# Notes:

Our systems are set up with the callback\_url set to my [https://MYDOMAIN:22000](https://MYDOMAIN:22000)  
(MYDOMAIN is set to the appropriate url with a redirect to the IP address as well).

I’ve registered my domain and installed the certificates, and checked with different authenticators that the https part works fine.

jupyter hub is installed in /opt/jupyterhub following these instructions:  
[https://jupyterhub.readthedocs.io/en/stable/installation-guide-hard.html](https://jupyterhub.readthedocs.io/en/stable/installation-guide-hard.html)  
and works with the native authenticator and the 'dummy authenticator.

it is configured to listen on port 22000 and with the azure config options hard coded using. these Ines in the jupyterhub\_config.py:  
c.JupyterHub.bind\_url = ‘https://:22000’

from oauthenticator.azuread import AzureAdOAuthenticator  
c.JupyterHub.authenticator\_class = AzureAdOAuthenticator

c.Application.log\_level = ‘DEBUG’

c.AzureAdOAuthenticator.tenant\_id = ‘XXXXX’ #os.environ.get(‘AAD\_TENANT\_ID’)

## I’ve hard coded this rather than exporting the environment variable outside this file

c.AzureAdOAuthenticator.oauth\_callback\_url = ‘[https://MYDOMAIN:22000/hub/oauth\_callback](https://MYDOMAIN:22000/hub/oauth_callback)’  
c.AzureAdOAuthenticator.client\_id = ‘YYYYYYY’ #’{AAD-APP-CLIENT\_ID}’  
c.AzureAdOAuthenticator.client\_secret = ‘ZZZZZZZ’ # ‘{AAD-APP-CLIENT-SECRET}’

I’ve tried setting the AAD\_TENANT variable in the script that registers the service and also running running from the command line, prefixed by sudo and explicitly setting those three environments variables but that makes no difference.

---

<div class="post-metadata">

**Author:** ![manics](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/manics/32/85_2.png) [@manics](https://discourse.jupyter.org/u/manics)\
**Post date:** [January 25, 2021, 1:41pm UTC](https://discourse.jupyter.org/t/oauth-azure-logins-hang-after-token-is-returned/7641/2 "2021-01-25T13:41:45Z")

</div>

Could you try turning on debug logging in JupyterHub, and show us the logs during and before the attempt to login?

---

<div class="post-metadata">

**Author:** ![jim-smith](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/jim-smith/32/3537_2.png) [@jim-smith](https://discourse.jupyter.org/u/jim-smith)\
**Post date:** [January 26, 2021, 11:18am UTC](https://discourse.jupyter.org/t/oauth-azure-logins-hang-after-token-is-returned/7641/3 "2021-01-26T11:18:02Z")

</div>

starting from the command line:  
sudo /opt/jupyterhub/bin/jupyterhub --debug -f /opt/jupyterhub/etc/jupyterhub/jupyterhub\_config.py

[D 2021-01-26 11:12:33.353 JupyterHub application:730] Looking for /opt/jupyterhub/etc/jupyterhub/jupyterhub\_config in /opt/jupyterhub

[D 2021-01-26 11:12:33.354 JupyterHub application:752] Loaded config file: /opt/jupyterhub/etc/jupyterhub/jupyterhub\_config.py

[I 2021-01-26 11:12:33.355 JupyterHub app:2349] Running JupyterHub version 1.3.0

[I 2021-01-26 11:12:33.355 JupyterHub app:2379] Using Authenticator: oauthenticator.azuread.AzureAdOAuthenticator-0.12.3

[I 2021-01-26 11:12:33.355 JupyterHub app:2379] Using Spawner: jupyterhub.spawner.LocalProcessSpawner-1.3.0

[I 2021-01-26 11:12:33.355 JupyterHub app:2379] Using Proxy: jupyterhub.proxy.ConfigurableHTTPProxy-1.3.0

[D 2021-01-26 11:12:33.356 JupyterHub app:2310] Could not load pycurl: No module named ‘pycurl’

pycurl is recommended if you have a large number of users.

[D 2021-01-26 11:12:33.357 JupyterHub app:1460] Generating new cookie\_secret

[I 2021-01-26 11:12:33.357 JupyterHub app:1465] Writing cookie\_secret to /opt/jupyterhub/jupyterhub\_cookie\_secret

[D 2021-01-26 11:12:33.357 JupyterHub app:1587] Connecting to db: sqlite:///jupyterhub.sqlite

[D 2021-01-26 11:12:33.367 JupyterHub orm:784] Stamping empty database with alembic revision 4dc2d5a8c53c

[I 2021-01-26 11:12:33.371 alembic.runtime.migration migration:155] Context impl SQLiteImpl.

[I 2021-01-26 11:12:33.371 alembic.runtime.migration migration:158] Will assume non-transactional DDL.

[I 2021-01-26 11:12:33.399 alembic.runtime.migration migration:517] Running stamp\_revision -\> 4dc2d5a8c53c

[D 2021-01-26 11:12:33.399 alembic.runtime.migration migration:727] new branch insert 4dc2d5a8c53c

[I 2021-01-26 11:12:33.560 JupyterHub proxy:460] Generating new CONFIGPROXY\_AUTH\_TOKEN

[I 2021-01-26 11:12:33.584 JupyterHub app:1725] Not using allowed\_users. Any authenticated user will be allowed.

[D 2021-01-26 11:12:33.611 JupyterHub app:1877] Purging expired APITokens

[D 2021-01-26 11:12:33.613 JupyterHub app:1877] Purging expired OAuthAccessTokens

[D 2021-01-26 11:12:33.614 JupyterHub app:1877] Purging expired OAuthCodes

[D 2021-01-26 11:12:33.623 JupyterHub app:2004] Initializing spawners

[D 2021-01-26 11:12:33.624 JupyterHub app:2137] Loaded users:

[I 2021-01-26 11:12:33.625 JupyterHub app:2416] Initialized 0 spawners in 0.002 seconds

[I 2021-01-26 11:12:33.627 JupyterHub proxy:666] Starting proxy @ https://:22000

[D 2021-01-26 11:12:33.627 JupyterHub proxy:667] Proxy cmd: [‘configurable-http-proxy’, ‘–ip’, ‘’, ‘–port’, ‘22000’, ‘–api-ip’, ‘127.0.0.1’, ‘–api-port’, ‘8001’, ‘–error-target’, ‘[http://127.0.0.1:8081/hub/error](http://127.0.0.1:8081/hub/error)’, ‘–ssl-key’, ‘/etc/letsencrypt/live/csctcloud.uwe.ac.uk/privkey.pem’, ‘–ssl-cert’, ‘/etc/letsencrypt/live/csctcloud.uwe.ac.uk/fullchain.pem’]

[D 2021-01-26 11:12:33.629 JupyterHub proxy:574] Writing proxy pid file: jupyterhub-proxy.pid

11:12:34.051 [ConfigProxy] info: Proxying https://\*:22000 to (no default)

11:12:34.053 [ConfigProxy] info: Proxy API at [http://127.0.0.1:8001/api/routes](http://127.0.0.1:8001/api/routes)

[D 2021-01-26 11:12:34.198 JupyterHub proxy:702] Proxy started and appears to be up

[D 2021-01-26 11:12:34.201 JupyterHub proxy:795] Proxy: Fetching GET [http://127.0.0.1:8001/api/routes](http://127.0.0.1:8001/api/routes)

11:12:34.207 [ConfigProxy] info: 200 GET /api/routes

[I 2021-01-26 11:12:34.208 JupyterHub app:2664] Hub API listening on [http://127.0.0.1:8081/hub/](http://127.0.0.1:8081/hub/)

[D 2021-01-26 11:12:34.208 JupyterHub proxy:314] Fetching routes to check

[D 2021-01-26 11:12:34.208 JupyterHub proxy:795] Proxy: Fetching GET [http://127.0.0.1:8001/api/routes](http://127.0.0.1:8001/api/routes)

11:12:34.210 [ConfigProxy] info: 200 GET /api/routes

[I 2021-01-26 11:12:34.210 JupyterHub proxy:319] Checking routes

[I 2021-01-26 11:12:34.210 JupyterHub proxy:399] Adding default route for Hub: / =\> [http://127.0.0.1:8081](http://127.0.0.1:8081)

[D 2021-01-26 11:12:34.210 JupyterHub proxy:795] Proxy: Fetching POST [http://127.0.0.1:8001/api/routes/](http://127.0.0.1:8001/api/routes/)

11:12:34.212 [ConfigProxy] info: Adding route / -\> [http://127.0.0.1:8081](http://127.0.0.1:8081)

11:12:34.212 [ConfigProxy] info: Route added / -\> [http://127.0.0.1:8081](http://127.0.0.1:8081)

11:12:34.213 [ConfigProxy] info: 201 POST /api/routes/

[I 2021-01-26 11:12:34.213 JupyterHub app:2739] JupyterHub is now running at https://:22000

[D 2021-01-26 11:12:34.213 JupyterHub app:2342] It took 0.865 seconds for the Hub to start

then trying to connect via a browser pointed str localhost:22000 (there’s a ssh tunnel from my local port 22000 t port 22000 on the server) generates this extra logging (I’ve removed the specific client and tenth ids and domain from the GET command and replaced them with “MYxxx”

[I 2021-01-26 11:14:27.128 JupyterHub log:181] 200 GET /hub/login?next=%2Fhub%2F (@::ffff:127.0.0.1) 23.03ms

[I 2021-01-26 11:14:28.439 JupyterHub log:181] 302 GET / -\> /hub/ (@::ffff:127.0.0.1) 0.78ms

[I 2021-01-26 11:14:28.524 JupyterHub log:181] 302 GET /hub/ -\> /hub/login?next=%2Fhub%2F (@::ffff:127.0.0.1) 0.64ms

[I 2021-01-26 11:14:28.602 JupyterHub log:181] 200 GET /hub/login?next=%2Fhub%2F (@::ffff:127.0.0.1) 1.11ms

[I 2021-01-26 11:14:35.033 JupyterHub oauth2:104] OAuth redirect: ‘[https://csctcloud.uwe.ac.uk:22000/hub/oauth\_callback](https://csctcloud.uwe.ac.uk:22000/hub/oauth_callback)’

[D 2021-01-26 11:14:35.034 JupyterHub base:521] Setting cookie oauthenticator-state: {‘httponly’: True, ‘secure’: True, ‘expires\_days’: 1}

[I 2021-01-26 11:14:35.034 JupyterHub log:181] 302 GET /hub/oauth\_login?next=%2Fhub%2F -\> [Sign in to your account](https://login.microsoftonline.com/MY_AAD_TENANT_ID/oauth2/authorize?response_type=code&redirect_uri=MYDOMAIN%3A22000%2Fhub%2Foauth_callback&client_id=MY-AAD-APP-CLIENT_ID&state=%5Bsecret%5D) (@::ffff:127.0.0.1) 1.41ms

---

<div class="post-metadata">

**Author:** ![manics](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/manics/32/85_2.png) [@manics](https://discourse.jupyter.org/u/manics)\
**Post date:** [January 27, 2021, 8:09pm UTC](https://discourse.jupyter.org/t/oauth-azure-logins-hang-after-token-is-returned/7641/4 "2021-01-27T20:09:08Z")

</div>

> [@jim-smith](#):
>
> then trying to connect via a browser pointed str localhost:22000 (there’s a ssh tunnel from my local port 22000 t port 22000 on the server)

Could that be the problem? The hub is trying to redirect you to

> [@](#):
>
> `[I 2021-01-26 11:14:35.033 JupyterHub oauth2:104] OAuth redirect: ‘https://csctcloud.uwe.ac.uk:22000/hub/oauth_callback’`

but since you’re connected through a tunnel your browser is unable to access that `host:port`.

---

<div class="post-metadata">

**Author:** ![jim-smith](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/jim-smith/32/3537_2.png) [@jim-smith](https://discourse.jupyter.org/u/jim-smith)\
**Post date:** [January 28, 2021, 8:52am UTC](https://discourse.jupyter.org/t/oauth-azure-logins-hang-after-token-is-returned/7641/5 "2021-01-28T08:52:57Z")

</div>

Hi,  
thanks for getting back to me.  
I think you are correct- or at least if we open that port directly to the internet, and connect to it, then we get a different bunch of problems around local certificate issuers.

Do you happen to know if there is a way of configuring what our ITS people would like:  
users create ssh tunnel to azure VM which then runs oauth talking to a different machine?

---

<div class="post-metadata">

**Author:** ![manics](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/manics/32/85_2.png) [@manics](https://discourse.jupyter.org/u/manics)\
**Post date:** [January 28, 2021, 11:49pm UTC](https://discourse.jupyter.org/t/oauth-azure-logins-hang-after-token-is-returned/7641/6 "2021-01-28T23:49:10Z")

</div>

If everyone is always connecting in the same way (port forwarding to `localhost:2222`) you might be able to configure the hub oauth callback url to `http://localhost:22000/hub/oauth_callback`. This would have to be done in the jupyterhub config and probably also in the Azure application settings.

Another alttenative is to use ssh to provide a SOCKS proxy for your browser, effectively giving you a basic VPN, see for example

> **[How To Route Web Traffic Securely Without a VPN Using a SOCKS Tunnel |...](https://www.digitalocean.com/community/tutorials/how-to-route-web-traffic-securely-without-a-vpn-using-a-socks-tunnel)**
>
> You can browse the web securely using a Droplet with SSH access as a SOCKS 5 proxy end point. In this tutorial we'll use a Ubuntu 20.04 Droplet as the proxy, and the Firefox web browser as the client application. By the end of this tutorial you...

---

<div class="post-metadata">

**Author:** ![jim-smith](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/jim-smith/32/3537_2.png) [@jim-smith](https://discourse.jupyter.org/u/jim-smith)\
**Post date:** [January 29, 2021, 10:01am UTC](https://discourse.jupyter.org/t/oauth-azure-logins-hang-after-token-is-returned/7641/7 "2021-01-29T10:01:37Z")

</div>

Thanks very much for the help and pointers.
