Uploaded image for project: 'Elytron Web'
  1. Elytron Web
  2. ELYWEB-221

Programmatically calling request.authenticate(..) does not add challenge to response

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • Major
    • None
    • 1.9.3.Final
    • Undertow Servlet
    • None

    Description

      Hi, we are about to run our web app on JBoss EAP 7.4.10 and JDK17, which use Elytron subsystem. We found that programmatically calling request.authenticate(...) no longer create basic challenges on response. This is supported in Java Servelet spec 4.0(13.3, https://javaee.github.io/servlet-spec/downloads/servlet-4.0/servlet-4_0_FINAL.pdf , https://docs.oracle.com/cd/E19226-01/820-7627/gjiie/index.html  ), and in JBoss EAP 7.3.3+JDK11 it was working, which does not use Elytron subsystem. "login-config" has been added to web.xml.

      By debugging, we saw that:

      In https://github.com/undertow-io/undertow/blob/2.2.23.Final/servlet/src/main/java/io/undertow/servlet/spec/HttpServletRequestImpl.java#L472

      ```

              sc.setAuthenticationRequired();
              // TODO: this will set the status code and headers without going through any potential
              // wrappers, is this a problem?
              if (sc.authenticate()) {
                  if (sc.isAuthenticated())

      {                 return true;             }

      else

      {                 throw UndertowServletMessages.MESSAGES.authenticationFailed();             }

      ...

      ```

      "authentication required" is set, and "authenticate" is called, but "sc.isAuthenticated()" returned false and the exception is thrown.

       

      "HttpAuthenticator" performed the authentication under the hood. When authenticate not succeed or "Authorization" header missing, it will check if authentication is required to decide if auth challenge should be set to the response: https://github.com/wildfly-security/wildfly-elytron/blob/2.x/http/base/src/main/java/org/wildfly/security/http/HttpAuthenticator.java#L348

       

      The HttpAuthenticator is lazy generated by the security context and the "required" value is set in the builder:

      https://github.com/wildfly-security/elytron-web/blob/4.x/undertow/src/main/java/org/wildfly/elytron/web/undertow/server/SecurityContextImpl.java#L79

       

      The issue comes from the HttpAuthenticator generation. When any request comes, "SecurityContext.authenticate(..)" will first be called by `ServletAuthenticationCallHandler`: https://github.com/undertow-io/undertow/blob/2.2.23.Final/servlet/src/main/java/io/undertow/servlet/handlers/security/ServletAuthenticationCallHandler.java#L55 which will build a HttpAuthenticator for the security context with default security constraint. In the case when no security constraint / authentication constraint is set to the request, "required=false" is set to HttpAuthenticator so that authentication is ignored.

      However, when subsequent codes calling "sc.setAuthenticationRequired" and "sc.authenticate()" and try to authenticate using HttpAuthenticator with require=true, the same HttpAuthenticator is reused and "authenticationRequired" parameter takes no effect.

      The expected behavior should be that even there's no preset security-contraint on a request path, "request.authenticate(...)" should add challenge to response.

      Attachments

        Activity

          People

            Unassigned Unassigned
            junytse Juny Tse (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated: