-
Type: Question
-
Status: Resolved
-
Priority: Minor
-
Resolution: Fixed
-
Affects Version/s: 10.10
-
Component/s: Authentication
This scenario leads to an error:
- Use this authentication chain
<extension target="org.nuxeo.ecm.platform.ui.web.auth.service.PluggableAuthenticationService" point="specificChains"> <specificAuthenticationChain name="RestAPI"> <urlPatterns> <url>(.*)/api/v.*</url> </urlPatterns> <replacementChain> <plugin>AUTOMATION_BASIC_AUTH</plugin> <plugin>KEYCLOAK_AUTH</plugin> </replacementChain> </specificAuthenticationChain> </extension>
- Get a Keycloak token
curl --location --request POST 'https://{{url_keycloak}}/auth/realms/{{REALM}}/protocol/openid-connect/token' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'client_id={{client_id}}' \ --data-urlencode 'grant_type=password' \ --data-urlencode 'scope=openid' \ --data-urlencode 'username={{user}}' \ --data-urlencode 'password={{password}}'
- Wait for the token to expire
- Use the expired token to run a REST call
curl --location --request GET '{{nuxeo_url}}/nuxeo/api/v1/path/default-domain/workspaces/upload/test.mp4' \ --header 'Authorization: Bearer {{Jeton_KeyCloak}'
- The request returns a HTTP 500 error with this server error
ERROR [http-nio-0.0.0.0-8080-exec-3] [DefaultNuxeoExceptionHandler] java.lang.IllegalStateException: Cannot call sendError() after the response has been committed java.lang.IllegalStateException: Cannot call sendError() after the response has been committed at org.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:472) ~[catalina-9.0.45.jar:9.0.45] at javax.servlet.http.HttpServletResponseWrapper.sendError(HttpServletResponseWrapper.java:129) ~[servlet-api-9.0.45.jar:4.0.FR] at org.nuxeo.ecm.platform.ui.web.auth.plugins.BasicAuthenticator.handleLoginPrompt(BasicAuthenticator.java:76) ~[nuxeo-platform-web-common-10.10-HF44.jar:?] at org.nuxeo.ecm.platform.ui.web.auth.NuxeoAuthenticationFilter.handleLogin(NuxeoAuthenticationFilter.java:1120) ~[nuxeo-platform-web-common-10.10-HF44.jar:?] at org.nuxeo.ecm.platform.ui.web.auth.NuxeoAuthenticationFilter.handleLoginPrompt(NuxeoAuthenticationFilter.java:1078) ~[nuxeo-platform-web-common-10.10-HF44.jar:?] at org.nuxeo.ecm.platform.ui.web.auth.NuxeoAuthenticationFilter.doFilterInternal(NuxeoAuthenticationFilter.java:563) ~[nuxeo-platform-web-common-10.10-HF44.jar:?] at org.nuxeo.ecm.platform.ui.web.auth.NuxeoAuthenticationFilter.doFilter(NuxeoAuthenticationFilter.java:431) ~[nuxeo-platform-web-common-10.10-HF44.jar:?] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[catalina-9.0.45.jar:9.0.45]
The root cause is that the Keycloak module, which handles the authentication with the expired token, will return AuthOutcome.FAILED result and at the same time it will send the error in the HTTP response, and commits the response.
Back to NuxeoAuthenticationFilter, it iterates over all available authentication plugin to find an appropriate one to prompt a login and BasicAuth will also return an error in the HTTP response which provokes the exception.
Expected behavior is to return a HTTP 401 with no errror in the logs.
Suggested fix:
diff --git a/nuxeo-services/nuxeo-platform-web-common/src/main/java/org/nuxeo/ecm/platform/ui/web/auth/NuxeoAuthenticationFilter.java b/nuxeo-services/nuxeo-platform-web-common/src/main/java/org/nuxeo/ecm/platform/ui/web/auth/NuxeoAuthenticationFilter.java index 77198ecf3ba..0c53cf606da 100644 --- a/nuxeo-services/nuxeo-platform-web-common/src/main/java/org/nuxeo/ecm/platform/ui/web/auth/NuxeoAuthenticationFilter.java +++ b/nuxeo-services/nuxeo-platform-web-common/src/main/java/org/nuxeo/ecm/platform/ui/web/auth/NuxeoAuthenticationFilter.java @@ -1080,8 +1080,11 @@ public class NuxeoAuthenticationFilter implements Filter { } private boolean handleLogin(HttpServletRequest httpRequest, HttpServletResponse httpResponse) { - String baseURL = service.getBaseURL(httpRequest); + if (httpResponse.isCommitted()) { + return true; + } + String baseURL = service.getBaseURL(httpRequest); // go through plugins to get UserIdentity for (String pluginName : service.getAuthChain(httpRequest)) { NuxeoAuthenticationPlugin plugin = service.getPlugin(pluginName);
- causes
-
NXP-32389 Fix HTTP 500 when running an unauthenticated request against REST API with Keycloak auth
- Resolved
- links to