Infinite redirect loop with openID, NGINX and Azure Kubernetes config

Hey all. First off, thanks much for all your development work on Shinyproxy. We are hoping to use it to deliver educational analytics to school districts that could not otherwise afford commercial analytic solutions.

Configuration:
We are using Azure Active Directory as our OIDC provider and have specified our callback URL with the specified directory (https://(our-url)/login/oauth2/code/shinyproxy). We are using an NGINX ingress to handle https.

All goes well with AAD sign-in and Azure appears to be returning a valid token, however, shinyproxy fails to redirect the application.

The configuration worked well until we made a minor adjustment to our application.yml. The build with our minor change resulted in this infinite redirect loop so we returned the application.yml to it’s original state. However, the infinite direct loop persists even when we build the container with no cache.

We are somewhat baffled. Any thoughts on how to get shinyproxy up and running again, would be much appreciated.

I’ve pasted a sanitized version of our application.yml and 2 excerpts of what appear to be the most relevant sections of the debug error log.

application.yml:

  proxy:
  port: 8080
  container-backend: kubernetes
  authentication: openid 
  openid:  
    roles-claim: https://shinyproxy.io/shinyproxy_roles
    auth-url: https://login.microsoftonline.com/<$tenantId>/oauth2/authorize
    token-url: https://login.microsoftonline.com/<$tenantId>/oauth2/token
    jwks-url: https://login.microsoftonline.com/common/discovery/keys
    client-id: $myClientId 
    client-secret: “$myClientSecret”
  kubernetes:
    internal-networking: true
    url: http://localhost:8001
    namespace: default  
    image-pull-policy: Always 
    image-pull-secret: $myImageSecret 
  specs:
  - id: 01_hello
    display-name: Hello Application
    description: Application which demonstrates the basics of a Shiny app
    container-cmd: ["R", "-e", "shinyproxy::run_01_hello()"]
    container-image: openanalytics/shinyproxy-demo
  - id: 06_tabsets
    description: Shinyproxy demo app
    container-cmd: ["R", "-e", "shinyproxy::run_06_tabsets()"]
    container-image: openanalytics/shinyproxy-demo
logging:
  file:
    shinyproxy.log
  level: 
    root: DEBUG
server: 
  useForwardHeaders: true 

ErrorLog excerpt #1:/login/oauth2/code/shinyproxy seems to have the token from Azure

2020-06-30 15:57:50.252 DEBUG 1 --- [  XNIO-2 task-5] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login/oauth2/code/shinyproxy'; against '/css/**'
2020-06-30 15:57:50.252 DEBUG 1 --- [  XNIO-2 task-5] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login/oauth2/code/shinyproxy'; against '/img/**'
2020-06-30 15:57:50.252 DEBUG 1 --- [  XNIO-2 task-5] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login/oauth2/code/shinyproxy'; against '/js/**'
2020-06-30 15:57:50.252 DEBUG 1 --- [  XNIO-2 task-5] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login/oauth2/code/shinyproxy'; against '/assets/**'
2020-06-30 15:57:50.252 DEBUG 1 --- [  XNIO-2 task-5] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login/oauth2/code/shinyproxy'; against '/webjars/**'
2020-06-30 15:57:50.252 DEBUG 1 --- [  XNIO-2 task-5] o.s.security.web.FilterChainProxy        : /login/oauth2/code/shinyproxy?code=AQABAAIAAAAGV_bv21oQQ4ROqh0_1-tAgZ4Fg8-P3f02skNssOLaIEcLbLx1GFePBcJs0G6QDlPg1oWnePv7WeG5snOrf8b8ZXDIbqo8S8f2pShSKqblriQr1P-c3xZnnWNJMBONVStXL7mJisW0JGiXoIrB3EwH4BGpErvk-0PVdiEZ8ltoWzViD01Oiaw1rE8h0lyVGTy8PsX-Ztd1VMhZXJnMQJhbV3YfQ6n5mRGbRPMjS3eQ5SwBui-f78QH-q1nopyeaSElk0hO2UhyFe5zyUC_7yV7Ya23BcASK7oQh7r7qPj3eXdVmOvm9s2RJOKubj9KxTeA8tmyO6Vy4ofWbvO0wthiZAsuB0jt6lI7gjPipNXPdrTt4tFawexywcWffwuOd4UTuQdPgtqZwvs6BDkYjuLaLPxEvFBqQ10v5pLdI_fAWysig8muNeJUIWtL8W38LPmMiji7Ct9oQpIdnEJxQrp4ElmmixWFTY5QZfawK9L9f9rnbZRPSWozl8W1gOjatF_cFFCVwZm9AKjA_ckaEuMssZ8Dwi-tGrB8nqEwn2X2Yl3B2XEmkjjtNbPACW02mx6JdHHGB3u-LtwPjou0mHoTOajMO3NhILOfaBcm2dIy-Bh7OKxG5xrptLI1OHRYuk5cdnn9RchIgQC3I2X6tanssg6re3SURgjYvWWJKCAX3BlddZ-pKX8MculdJos_l8IAjqN2jCF89IiE5KokyOOUjRlGuqNIwqgBVaGgVd3dfaRr5NhWKMrEN4ltK4lKNaC7PtvwuLzpR07MTNGReOmnsAeIuzuKqMTURzbqlW9ye7PAH0W0gwBfAJDn0jhjnCg483ghCrsuBaQooH6mGbPz_xKOGaj8hwPH6dnCxQovE6am-nq3joTZaqaQcy6Bkr_UCBnaEvdlAYOClxsDbpQ_fvX6YF-gWtFHExa4IOtWcDqGw7mbB555RfoDButX22-erQMxeX0ehS3DOT6m5sDxFXYxUgtlmfM_vHp85OWblXtIkDOHi1qa7k44T0IeVhpLNEI8d4iOM-wBoLSBGq1da2orS3nDcNv_oHZwhqrBjfBN3nuoiboZfEMTVccXASvep_-qRCMw_9FKbjrqbBTjE8tlvXUQi2Vcx38O-7dwmnAxH0BrhouFrc8HqqU4nAQ7v7aLzHRe_IIhZ2PT4mkclLuF74TEdBHofIZHfz9U0yAA&state=3vtXCQ_lTjGn7g4Tntw7VLJ0Gj7fuxPcLYujmeTJD3o%3d&session_state=66dcad44-ba3b-443e-8003-646cb679a770 at position 1 of 14 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2020-06-30 15:57:50.252 DEBUG 1 --- [  XNIO-2 task-5] o.s.security.web.FilterChainProxy        : /login/oauth2/code/shinyproxy?code=AQABAAIAAAAGV_bv21oQQ4ROqh0_1-tAgZ4Fg8-P3f02skNssOLaIEcLbLx1GFePBcJs0G6QDlPg1oWnePv7WeG5snOrf8b8ZXDIbqo8S8f2pShSKqblriQr1P-c3xZnnWNJMBONVStXL7mJisW0JGiXoIrB3EwH4BGpErvk-0PVdiEZ8ltoWzViD01Oiaw1rE8h0lyVGTy8PsX-Ztd1VMhZXJnMQJhbV3YfQ6n5mRGbRPMjS3eQ5SwBui-f78QH-q1nopyeaSElk0hO2UhyFe5zyUC_7yV7Ya23BcASK7oQh7r7qPj3eXdVmOvm9s2RJOKubj9KxTeA8tmyO6Vy4ofWbvO0wthiZAsuB0jt6lI7gjPipNXPdrTt4tFawexywcWffwuOd4UTuQdPgtqZwvs6BDkYjuLaLPxEvFBqQ10v5pLdI_fAWysig8muNeJUIWtL8W38LPmMiji7Ct9oQpIdnEJxQrp4ElmmixWFTY5QZfawK9L9f9rnbZRPSWozl8W1gOjatF_cFFCVwZm9AKjA_ckaEuMssZ8Dwi-tGrB8nqEwn2X2Yl3B2XEmkjjtNbPACW02mx6JdHHGB3u-LtwPjou0mHoTOajMO3NhILOfaBcm2dIy-Bh7OKxG5xrptLI1OHRYuk5cdnn9RchIgQC3I2X6tanssg6re3SURgjYvWWJKCAX3BlddZ-pKX8MculdJos_l8IAjqN2jCF89IiE5KokyOOUjRlGuqNIwqgBVaGgVd3dfaRr5NhWKMrEN4ltK4lKNaC7PtvwuLzpR07MTNGReOmnsAeIuzuKqMTURzbqlW9ye7PAH0W0gwBfAJDn0jhjnCg483ghCrsuBaQooH6mGbPz_xKOGaj8hwPH6dnCxQovE6am-nq3joTZaqaQcy6Bkr_UCBnaEvdlAYOClxsDbpQ_fvX6YF-gWtFHExa4IOtWcDqGw7mbB555RfoDButX22-erQMxeX0ehS3DOT6m5sDxFXYxUgtlmfM_vHp85OWblXtIkDOHi1qa7k44T0IeVhpLNEI8d4iOM-wBoLSBGq1da2orS3nDcNv_oHZwhqrBjfBN3nuoiboZfEMTVccXASvep_-qRCMw_9FKbjrqbBTjE8tlvXUQi2Vcx38O-7dwmnAxH0BrhouFrc8HqqU4nAQ7v7aLzHRe_IIhZ2PT4mkclLuF74TEdBHofIZHfz9U0yAA&state=3vtXCQ_lTjGn7g4Tntw7VLJ0Gj7fuxPcLYujmeTJD3o%3d&session_state=66dcad44-ba3b-443e-8003-646cb679a770 at position 2 of 14 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2020-06-30 15:57:50.252 DEBUG 1 --- [  XNIO-2 task-5] w.c.HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT

ErrorLog excerpt #2: This looks like the end of the infinite redirect loop and the beginning of the stack overflow error.

2020-06-30 15:59:26.684 DEBUG 1 --- [  XNIO-2 task-8] s.n.www.protocol.http.HttpURLConnection  : sun.net.www.MessageHeader@7404dd818 pairs: {POST /8e860447-b167-4cc2-852f-4fb3d905a50d/oauth2/token HTTP/1.1: null}{Accept: application/json}{Authorization: Basic NTAyZTU1NTEtNTg1MS00OTBiLTliMzMtM2ExNGY5MTc4NzMyOiVFMiU4MCU5QzIxTXVqJTdFYTBCLUFpTy5ObzJJQXc1WWgxeFdrODBwR3BQJTdFJUUyJTgwJTlE}{Content-Type: application/x-www-form-urlencoded; charset=UTF-8}{User-Agent: Java/1.8.0_242}{Host: login.microsoftonline.com}{Connection: keep-alive}{Content-Length: 1331}
2020-06-30 15:59:26.750 DEBUG 1 --- [ XNIO-2 task-12] s.n.www.protocol.http.HttpURLConnection  : sun.net.www.MessageHeader@111a556915 pairs: {null: HTTP/1.1 401 Unauthorized}{Cache-Control: no-store, no-cache}{Pragma: no-cache}{Content-Type: application/json; charset=utf-8}{Expires: -1}{Strict-Transport-Security: max-age=31536000; includeSubDomains}{X-Content-Type-Options: nosniff}{P3P: CP="DSP CUR OTPi IND OTRi ONL FIN"}{x-ms-request-id: b141309b-96bf-424d-88f8-52272c592000}{x-ms-ests-server: 2.1.10761.12 - CHI ProdSlices}{Set-Cookie: fpc=AmOBfpvF2shFsJeurrCDKFaqfmKGAQAAAF1YjdYOAAAA; expires=Thu, 30-Jul-2020 15:59:26 GMT; path=/; secure; HttpOnly; SameSite=None}{Set-Cookie: x-ms-gateway-slice=prod; path=/; secure; samesite=none; httponly}{Set-Cookie: stsservicecookie=ests; path=/; secure; samesite=none; httponly}{Date: Tue, 30 Jun 2020 15:59:26 GMT}{Content-Length: 471}
2020-06-30 15:59:26.751 DEBUG 1 --- [ XNIO-2 task-12] o.s.s.authentication.ProviderManager     : Authentication attempt using org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationProvider
2020-06-30 15:59:26.751 DEBUG 1 --- [ XNIO-2 task-12] o.s.s.authentication.ProviderManager     : Authentication attempt using org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeAuthenticationProvider
2020-06-30 15:59:26.751 DEBUG 1 --- [ XNIO-2 task-12] s.n.www.protocol.http.HttpURLConnection  : sun.net.www.MessageHeader@565cd5bf8 pairs: {POST /8e860447-b167-4cc2-852f-4fb3d905a50d/oauth2/token HTTP/1.1: null}{Accept: application/json}{Authorization: Basic NTAyZTU1NTEtNTg1MS00OTBiLTliMzMtM2ExNGY5MTc4NzMyOiVFMiU4MCU5QzIxTXVqJTdFYTBCLUFpTy5ObzJJQXc1WWgxeFdrODBwR3BQJTdFJUUyJTgwJTlE}{Content-Type: application/x-www-form-urlencoded; charset=UTF-8}{User-Agent: Java/1.8.0_242}{Host: login.microsoftonline.com}{Connection: keep-alive}{Content-Length: 1331}
2020-06-30 15:59:26.827 DEBUG 1 --- [  XNIO-2 task-8] s.n.www.protocol.http.HttpURLConnection  : sun.net.www.MessageHeader@5dff2a4b15 pairs: {null: HTTP/1.1 401 Unauthorized}{Cache-Control: no-cache, no-store}{Pragma: no-cache}{Content-Type: application/json; charset=utf-8}{Expires: -1}{Strict-Transport-Security: max-age=31536000; includeSubDomains}{X-Content-Type-Options: nosniff}{x-ms-request-id: 966df6f3-b7f7-48bc-a65a-05211bb31d00}{x-ms-ests-server: 2.1.10761.12 - CHI ProdSlices}{P3P: CP="DSP CUR OTPi IND OTRi ONL FIN"}{Set-Cookie: fpc=Ao_UsomqgwBBtdesMgM82rmqfmKGAQAAAF5YjdYOAAAA; expires=Thu, 30-Jul-2020 15:59:26 GMT; path=/; secure; HttpOnly; SameSite=None}{Set-Cookie: x-ms-gateway-slice=prod; path=/; SameSite=None; secure; HttpOnly}{Set-Cookie: stsservicecookie=ests; path=/; SameSite=None; secure; HttpOnly}{Date: Tue, 30 Jun 2020 15:59:25 GMT}{Content-Length: 471}
2020-06-30 15:59:26.828 DEBUG 1 --- [  XNIO-2 task-8] o.s.s.authentication.ProviderManager     : Authentication attempt using org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationProvider
2020-06-30 15:59:26.828 DEBUG 1 --- [  XNIO-2 task-8] o.s.s.authentication.ProviderManager     : Authentication attempt using org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeAuthenticationProvider
2020-06-30 15:59:26.881 DEBUG 1 --- [  XNIO-2 task-8] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2020-06-30 15:59:26.881 DEBUG 1 --- [  XNIO-2 task-8] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2020-06-30 15:59:26.881 DEBUG 1 --- [  XNIO-2 task-8] o.s.b.w.s.f.OrderedRequestContextFilter  : Cleared thread-bound request context: HttpServletRequestImpl [ GET /login/oauth2/code/shinyproxy ]
2020-06-30 15:59:26.891 ERROR 1 --- [  XNIO-2 task-8] io.undertow.request                      : UT005023: Exception handling request to /login/oauth2/code/shinyproxy

java.lang.StackOverflowError: null
	at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_242]
	at sun.net.www.protocol.http.HttpURLConnection.<init>(HttpURLConnection.java:876) ~[na:1.8.0_242]
	at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.<init>(AbstractDelegateHttpsURLConnection.java:55) ~[na:1.8.0_242]
	at sun.net.www.protocol.https.DelegateHttpsURLConnection.<init>(DelegateHttpsURLConnection.java:64) ~[na:1.8.0_242]
	at sun.net.www.protocol.https.HttpsURLConnectionImpl.<init>(HttpsURLConnectionImpl.java:100) ~[na:1.8.0_242]
	at sun.net.www.protocol.https.Handler.openConnection(Handler.java:62) ~[na:1.8.0_242]
	at sun.net.www.protocol.https.Handler.openConnection(Handler.java:57) ~[na:1.8.0_242]
	at java.net.URL.openConnection(URL.java:1002) ~[na:1.8.0_242]
	at com.nimbusds.oauth2.sdk.http.HTTPRequest.toHttpURLConnection(HTTPRequest.java:772) ~[oauth2-oidc-sdk-5.54.jar!/:5.54]
	at com.nimbusds.oauth2.sdk.http.HTTPRequest.send(HTTPRequest.java:866) ~[oauth2-oidc-sdk-5.54.jar!/:5.54]
	at org.springframework.security.oauth2.client.endpoint.NimbusAuthorizationCodeTokenResponseClient.getTokenResponse(NimbusAuthorizationCodeTokenResponseClient.java:101) ~[spring-security-oauth2-client-5.0.3.RELEASE.jar!/:5.0.3.RELEASE]
	at org.springframework.security.oauth2.client.endpoint.NimbusAuthorizationCodeTokenResponseClient.getTokenResponse(NimbusAuthorizationCodeTokenResponseClient.java:67) ~[spring-security-oauth2-client-5.0.3.RELEASE.jar!/:5.0.3.RELEASE]
	at org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeAuthenticationProvider.authenticate(OidcAuthorizationCodeAuthenticationProvider.java:140) ~[spring-security-oauth2-client-5.0.3.RELEASE.jar!/:5.0.3.RELEASE]
	at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174) ~[spring-security-core-5.0.3.RELEASE.jar!/:5.0.3.RELEASE]
	at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:502) ~[spring-security-config-5.0.3.RELEASE.jar!/:5.0.3.RELEASE]
	at sun.reflect.GeneratedMethodAccessor25.invoke(Unknown Source) ~[na:na]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_242]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_242]
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:338) ~[spring-aop-5.0.4.RELEASE.jar!/:5.0.4.RELEASE]
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:206) ~[spring-aop-5.0.4.RELEASE.jar!/:5.0.4.RELEASE]
	at com.sun.proxy.$Proxy75.authenticate(Unknown Source) ~[na:na]
	at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:199) ~[spring-security-core-5.0.3.RELEASE.jar!/:5.0.3.RELEASE]
	at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:502) ~[spring-security-config-5.0.3.RELEASE.jar!/:5.0.3.RELEASE]