janiussyafiq commented on code in PR #13825:
URL: https://github.com/apache/apisix/pull/13825#discussion_r3781772792


##########
apisix/plugins/openid-connect.lua:
##########
@@ -1294,34 +1303,65 @@ function _M.rewrite(plugin_conf, ctx)
                                                           
build_session_opts(conf.session))
 
         if err then
-            if session then
-                session:close()
-            end
             if err == "unauthorized request" then
+                if session then
+                    session:close()
+                end
                 if conf.unauth_action == "pass" then
                     return nil
                 end
                 return 401
             end
 
-            -- Stale authorization callback: the session holds no authorization
-            -- state for the state in the callback, e.g. an already completed
-            -- callback was replayed, or the state was pruned after too many
-            -- concurrent flows. (Concurrent logins in several tabs are handled
-            -- by resty.openidc itself since 1.9.0, which keeps one
-            -- authorization state per in-flight flow.) The client is a browser
-            -- mid-navigation, so instead of a dead-end 500, send it back to 
the
-            -- original URL that resty.openidc returns alongside the error: a
-            -- fresh flow starts from there and completes without any user
-            -- interaction while the ID provider still holds an SSO session.
-            if err == STATE_MISMATCH_ERR and target_url
+            -- Recoverable authorization-callback failures: a stale state
+            -- (replayed or pruned callback), or the ID provider redirecting
+            -- back with error=temporarily_unavailable, e.g. Keycloak after
+            -- its login session expired. The client is a browser
+            -- mid-navigation, so restart the authentication flow by sending
+            -- it back to the original URL instead of dead-ending with a 500.
+            -- Other OAuth2 error codes (access_denied, login_required, ...)
+            -- reflect a deliberate outcome and are not retried.
+            local restart_reason
+            if err == STATE_MISMATCH_ERR then
+                restart_reason = "state mismatch (replayed or pruned callback)"
+            elseif core.string.has_prefix(err, UNHANDLED_REDIRECT_URI_ERR) then
+                local uri_args = ngx.req.get_uri_args()
+                if uri_args.error == "temporarily_unavailable" then

Review Comment:
   fixed



-- 
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]

Reply via email to