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]