Uploaded image for project: 'Nuxeo Platform'
  1. Nuxeo Platform
  2. NXP-30507

Skip handleLogin when HTTP response has already been commited

    Details

      Description

      This scenario leads to an error:

      1. 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>
        
      2. 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}}'
        
      3. Wait for the token to expire
      4. 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}'
        
      5. 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);
      

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              tmartins Thierry Martins
              Participants:
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:

                PagerDuty

                Error rendering 'com.pagerduty.jira-server-plugin:PagerDuty'. Please contact your Jira administrators.