Re: [I] help request: OIDC Login Loop & Refresh Token Failures with openid-connect Plugin for SPA + API Gateway Pattern [apisix]
shreemaan-abhishek closed issue #12495: help request: OIDC Login Loop & Refresh Token Failures with openid-connect Plugin for SPA + API Gateway Pattern URL: https://github.com/apache/apisix/issues/12495 -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
Re: [I] help request: OIDC Login Loop & Refresh Token Failures with openid-connect Plugin for SPA + API Gateway Pattern [apisix]
github-actions[bot] commented on issue #12495: URL: https://github.com/apache/apisix/issues/12495#issuecomment-3674385818 This issue has been closed due to lack of activity. If you think that is incorrect, or the issue requires additional review, you can revive the issue at any time. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
Re: [I] help request: OIDC Login Loop & Refresh Token Failures with openid-connect Plugin for SPA + API Gateway Pattern [apisix]
github-actions[bot] closed issue #12495: help request: OIDC Login Loop & Refresh Token Failures with openid-connect Plugin for SPA + API Gateway Pattern URL: https://github.com/apache/apisix/issues/12495 -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
Re: [I] help request: OIDC Login Loop & Refresh Token Failures with openid-connect Plugin for SPA + API Gateway Pattern [apisix]
github-actions[bot] commented on issue #12495: URL: https://github.com/apache/apisix/issues/12495#issuecomment-3654851503 Due to lack of the reporter's response this issue has been labeled with "no response". It will be close in 3 days if no further activity occurs. If this issue is still relevant, please simply write any comment. Even if closed, you can still revive the issue at any time or discuss it on the [email protected] list. Thank you for your contributions. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
Re: [I] help request: OIDC Login Loop & Refresh Token Failures with openid-connect Plugin for SPA + API Gateway Pattern [apisix]
ronnybremer commented on issue #12495: URL: https://github.com/apache/apisix/issues/12495#issuecomment-3410090266 I have been configuring the exact same scenario a few months ago. Both `/*` and `/api/*` routes share the same openid-connect configuration with one small difference. On the API route I set ``` unauth_action = deny ``` hoping that this might prevent redirects from an API call to the login page if the token has expired in the meantime and letting APISIX request a new auth token from the IDP. However, this doesn't work as I never see a refresh token call in the IDPs backend (also not from the frontend route). @RegMTS would you mind sharing your openid route config? Mine looks like this: ``` routes: - name: PORTAL methods: ["GET", "POST"] uris: [ "/portal", "/portal/*", "/favicon.ico" ] plugins: openid-connect: client_id: *redacted* client_secret: *redacted* use_nonce: true use_pkce: true use_jwks: true timeout: 10 session.cookie.lifetime: 1800 set_access_token_header: true access_token_in_authorization_header: true discovery: https://idp.example.com:444/idp/.well-known/openid-configuration redirect_uri: https://idp.example.com:9443/aiportal/.apisix/redirect logout_path: /portal/.apisix/logout post_logout_redirect_uri: https://idp.example.com:444/idp/logout bearer_only: false realm: APP session: secret: *redacted* unauth_action: auth redirect: http_to_https: true opentelemetry: sampler: name: always_on upstream: scheme: https nodes: "app-backend.exmaple.com:443": 1 type: chash hash_on: cookie key: PHPSESSID - name: API methods: ["GET", "POST", "PUT", "PATCH", "DELETE"] uris: [ "/webservice/OData4Service.svc/*", "/webservice/rest/*" ] plugins: openid-connect: client_id: *redacted* client_secret: *redacted* use_jwks: true timeout: 10 session.cookie.lifetime: 1800 set_access_token_header: true access_token_in_authorization_header: true discovery: https://idp.example.com:444/idp/.well-known/openid-configuration bearer_only: false realm: APP session: secret: *redacted* unauth_action: deny redirect: http_to_https: true opentelemetry: sampler: name: always_on upstream: scheme: https nodes: "api-backend1.example.com:8443": 1 "api-backend2.example.com:8443": 2 type: roundrobin timeout: connect: 60 send: 180 read: 180 ``` The session is shared (with the same secret) and true, it sends a pretty large cookie back to the client. I would also like to avoid that, if possible. Since APISIX needs to be clustered, the `shdict` approach does not work for me, so I gotta wait for Redis. So, just like your original post, the first approach of yours works best, so far. The cookie is a bit long, but now we know why, and the automatic token refresh doesn't seem to occur. Hopefully its just a difference between your and my config. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
Re: [I] help request: OIDC Login Loop & Refresh Token Failures with openid-connect Plugin for SPA + API Gateway Pattern [apisix]
bzp2010 commented on issue #12495: URL: https://github.com/apache/apisix/issues/12495#issuecomment-3229166797 @RegMTS > I've looked through the documentation, but I couldn't find a specific example that illustrates how to configure two routes to share a session via shdict. To proceed with testing, I would need your help. This feature is supported by the underlying library `lua-resty-session`. While it's already out of the box for the library itself. Unfortunately, APISIX currently doesn't directly expose any capability to dynamically configure it. Although I believe it's on our to-do list (as some other users have also mentioned this need), we currently lack sufficient manpower to complete this work, whether from API7.ai engineers or other volunteers in the community. This doesn't mean we can't configure it at all—there are indeed some workarounds available. 1. Directly manipulate the underlying library by setting variables. ref: https://github.com/bungle/lua-resty-session/blob/v3.10/lib/resty/session.lua#L353 ref: https://github.com/bungle/lua-resty-session/blob/v3.10/lib/resty/session/storage/shm.lua#L23 ``` nginx_config: http_server_configuration_snippet: | set $session_storage 'shm'; set $session_shm_store 'sessions'; # shdict name ``` 2. Set the name of the shdict used for the session. ``` nginx_config: http: custom_lua_shared_dict: sessions: 100m # 100MBytes ``` Combine the above configurations. 3. Set the same `session.secret` value across multiple routes. I think this should work, but I haven't tested it myself yet. So you can give it a try. If any issues arise, you can report them here. (Alternatively, if you prefer, you can also contribute this feature to support setting session-related configuration items directly within the plugin configuration. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
Re: [I] help request: OIDC Login Loop & Refresh Token Failures with openid-connect Plugin for SPA + API Gateway Pattern [apisix]
RegMTS commented on issue #12495: URL: https://github.com/apache/apisix/issues/12495#issuecomment-3228330090 Hi @bzp2010 and @moonming, thank you so much for the detailed and in-depth explanation. It perfectly clarifies the trade-offs of each approach. I really appreciate the time you dedicated to this analysis. I now have a much better understanding of the reasoning behind the Redis suggestion, especially for scalability and to overcome the limitations of cookie-based sessions (size, no revocation) and `shdict` (cluster propagation). Our primary architectural goal remains to centralize the security logic in the gateway, completely abstracting it from the Single-Page Application, as if it were an application we cannot modify. For this reason, the `bearer_only: true` mode (which shifts the OIDC logic to the frontend) is not our first choice, although I understand its benefits in other contexts. In light of this, and considering that our deployment does not require an APISIX cluster for the time being, the **`shdict`**-based solution seems like the ideal compromise for our use case. It keeps the session server-side, solving the issues related to cookie size, and it is a native feature. I've looked through the documentation, but I couldn't find a specific example that illustrates how to configure two routes to share a session via `shdict`. To proceed with testing, I would need your help. Would you be able to provide a configuration example for the two routes (`/*` and `/api/*`) that shows how to correctly enable and set up session management via `shdict` in the `openid-connect` plugin, in order to solve the context-sharing problem? Thanks again for your time and for your support. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
Re: [I] help request: OIDC Login Loop & Refresh Token Failures with openid-connect Plugin for SPA + API Gateway Pattern [apisix]
bzp2010 commented on issue #12495: URL: https://github.com/apache/apisix/issues/12495#issuecomment-3223143029 @RegMTS @moonming recommends using Redis for session sharing, but the reason is not complete: If you use the same `session.secret` on multiple routes, session sharing will be possible, but you must explicitly configure it; otherwise, APISIX will generate and populate it. By default, you are using cookie-based sessions, where session data is encrypted with the secret and sent to the client as a cookie. Since the client does not know the secret, it cannot decrypt or modify it, making it secure. In this case, the data is not stored or persisted by any central component. Although APISIX can delete cookies from the browser, you cannot revoke a session because malicious actors can recover the session by recording and manually reconfiguring the cookie. Despite this, it is still secure, just a minor drawback of this stateless scheme. It is similar to the situation we encounter when using JWT. Additionally, since the cookie is sent with every HTTP request header, it may become quite large, potentially wasting your server bandwidth and triggering request header limits on your reverse proxy chain. For example, as far as I know, Nginx has such a default limit, which may result in a 400 “too large request header or cookie” error. A viable alternative is to use APISIX shdict to store session data and only send the session ID cookie to the client. This keeps the data on the server, and the client can never access it, so even if your secret is compromised, it remains secure. However, shdict cannot be efficiently propagated across multiple APISIX instances, which poses an obstacle to deploying an APISIX cluster. Therefore, Redis is listed as a compromise solution. It ensures that session data is retained solely on the server while reducing request headers, and it also enables seamless data sharing across multiple APISIX instances. This is the issue you encountered when setting `bearer_only` to false. --- Another completely different approach is to set `bearer_only` to true. In this case, APISIX will no longer use sessions or redirect clients to the IDP. Instead, it will **ONLY** verify the access token in the client API call. If the verification passes, the request will be forwarded to the upstream server. Otherwise, a 401 status will be returned to the client. Your "client" fully controls the authentication process. Let's take a web app as an example. Your web app is deployed on a CDN, and traffic to the web page does not pass through APISIX. When a user first opens the page, your page explicitly knows that no user credentials (access token) are stored in the browser, so you need to display a prompt informing the user that they need to log in. After the user clicks the button to redirect to the IDP and completes the entire authentication process (e.g., via the OIDC implicit flow), your web app will obtain the access token. Subsequently, the web app needs to request the API to retrieve the user's data. At this point, the request will pass through APISIX, which only needs to attach the access token. APISIX can then verify the credential, extract the user's identity, and pass it on to the upstream service. When the credentials in the browser expire, if the user accesses the application again, the browser will attach an invalid access token to access APISIX, and you will receive a 401 response. At this point, simply prompt the user to log in again, and they will be able to access the application once more. Additionally, since web apps can also obtain a refresh token, they can refresh the access token while the refresh token is still valid, even if the access token has expired. Users are unaware of token expiration and refresh, so they do not experience any interruptions. In this mode, APISIX will no longer be responsible for any tasks related to login and session/token issuance. Your application will handle these tasks independently, starting from obtaining and storing the access token. Since it is only verification, there is no need for server-side persistence, and Redis is not required. This helps create a seamless user experience. When a user clicks “Log In” on your page, they will be redirected to the IDP to complete the login process, after which the application can be used. When `bearer_only` is set to false, it is primarily used to add authentication to existing applications that you cannot modify. When users access the application, if there is no session data in the cookie, APISIX will redirect them directly to the IDP for login. Users will see a brief white screen before being redirected directly to the login page, rather than seeing your brand information followed by a brief, reasonable interaction before being properly redirected to
Re: [I] help request: OIDC Login Loop & Refresh Token Failures with openid-connect Plugin for SPA + API Gateway Pattern [apisix]
RegMTS commented on issue #12495: URL: https://github.com/apache/apisix/issues/12495#issuecomment-3222970450 Hi @moonming, thank you so much for the quick and transparent response. It's very helpful to have confirmation that this is a current limitation of the plugin's architecture and not a misconfiguration on my end. To answer your questions directly: 1. **On external session storage:** While using an external store like Redis would certainly solve the immediate problem, I see it more as a solution for scalability and high availability. From my perspective, an ideal solution would allow APISIX to manage and share this context natively between routes, without the architectural dependency on an external component for a baseline setup. This would keep the deployment simpler for many common use cases. 2. **On other approaches:** Actually, `bearer_only: false` is not a strict requirement for the backend route. An alternative pattern where only the frontend route (`/*`) handles the full OIDC flow is very interesting. The absolute key to this pattern, and the core of our requirement, is the **seamless refresh token scenario**. When the user's session on the frontend expires, the `openid-connect` plugin should transparently refresh the token. This newly refreshed session/token must then be made available to the backend route. This ensures that the user can continue to consume the backend APIs without any interruption or need to re-authenticate. Is there a recommended way within APISIX to achieve this "token forwarding" or context propagation? For example, could the `openid-connect` plugin on the frontend route automatically propagate the refreshed token to subsequent calls targeting the backend route, which could then be protected by a simpler mechanism like `jwt-auth`? Crucially, this JWT must contain the same **identity claims** found in the OIDC session cookie, as our backend services rely on this information to operate correctly. The critical link is ensuring the backend route benefits from the refresh cycle managed by the frontend route. I am very keen to contribute to this discussion as I believe this is a cornerstone use case for leveraging APISIX as a complete security gateway for web applications. Thanks again for your engagement on this. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
Re: [I] help request: OIDC Login Loop & Refresh Token Failures with openid-connect Plugin for SPA + API Gateway Pattern [apisix]
moonming commented on issue #12495: URL: https://github.com/apache/apisix/issues/12495#issuecomment-3200057876 Hi, @RegMTS thanks for the detailed report and clear description of your use case. Currently, Apache APISIX’s openid-connect plugin does not share session / refresh token context across multiple routes. This is why you are observing either refresh token failures or login loops when trying to protect both SPA and API routes with separate plugin instances. One possible direction to address this limitation would be to allow the plugin to use an external session store (e.g., Redis), so that different routes (or even different APISIX nodes) could share the same OIDC session context. In theory, this could solve the mismatch you are experiencing during token refresh. At the moment, this feature is not implemented. We’d be very interested to hear your feedback: - Would external session storage fit your architecture? - Do you see other approaches that could help in your scenario? Contributions and design discussions around this feature are very welcome. Thanks again for raising this important use case! -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
Re: [I] help request: OIDC Login Loop & Refresh Token Failures with openid-connect Plugin for SPA + API Gateway Pattern [apisix]
SkyeYoung commented on issue #12495: URL: https://github.com/apache/apisix/issues/12495#issuecomment-3173686554 We have started checking and will be feedback here when there is a conclusion. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
