8 Replies Latest reply on Jul 2, 2010 1:48 PM by javaspack

    HttpServletRequest.authenticate error

    javaspack

      I am using JBoss 6.0M3

      I am trying to use the new servlet 3.0 spec function authenticate(HttpServletResponse) from an HttpServletRequest. Each time I invoke it from my servlet, I get the error "No authenticator available for programmatic login"

       

      I have tracked this error down to the Request class with the property ("coyoteRequest.noAuthenticator")

      (http://anonsvn.jboss.org/repos/jbossweb/trunk/java/org/apache/catalina/connector/Request.java)

       

       

       

          public boolean authenticate(HttpServletResponse response) throws IOException,

                  ServletException {

              if (context != null && context.getAuthenticator() != null) {

                  return context.getAuthenticator().authenticate(this, response);

              } else {

                  throw new ServletException(sm.getString("coyoteRequest.noAuthenticator"));

              }

          }

       

       

      I have a Valve set in my context.xml that I believe should be retrieved when context.getAuthenticator() is called, but it doesn't seem to work. Is there some mysterious way to set this? Since my Valve extends AuthenticatorBase which implements Authenticator, I know it is a valid Authenticator.

       

      Just for comparison, I downloaded the Tomcat 7.0 branch (because it is my understanding that that is where the new servlet 3.0 is implemented, maybe I'm wrong?) and the Request class has a different authenticate method

       

      public boolean authenticate(HttpServletResponse response)
          throws IOException, ServletException {
              if (response.isCommitted()) {
                  throw new IllegalStateException(
                          sm.getString("coyoteRequest.authenticate.ise"));
              }

       

              LoginConfig config = context.getLoginConfig();
             
              if (config == null) {
                  throw new ServletException(
                          sm.getString("coyoteRequest.noLoginConfig"));
              }
              return context.getAuthenticator().authenticate(this, response, config);
          }

       

       

      Since these are very different, is there a bug that has been fixed? Or am I just missing something?

        • 1. Re: HttpServletRequest.authenticate error
          jfclere

          Just for comparison, I downloaded the Tomcat 7.0 branch (because it is my understanding that that is where the new servlet 3.0 is implemented, maybe I'm wrong?) and the Request class has a different authenticate method

          JBossWeb has its own implementation of Servlet 3.0.

          BTW: I am afraid the Tomcat code will throw a NullPointerException in your case.

           

           

          Or am I just missing something?

          It seems you need to configure the authenticator and/or have a constraints in the webapp you are using.

          • 2. Re: HttpServletRequest.authenticate error
            javaspack
            It seems you need to configure the authenticator and/or have a  constraints in the webapp you are using

             

            In my context.xml file, I define a Valve

            <Context>

             

              <Valve className="com.mycompany.auth.MyValve" />

            </Context>

             

            Doesn't this become my configured authenticator for the context? MyValve extends AuthenticatorBase which implements Authenticator. It is a valid authenticator.

             

             

            I have also tried numerous changes in the web.xml with and without constraints. But it is my understanding that one of the reasons for this functionality is to remove the dependency of having constraints and just allowing a dynamic login.

            (http://blogs.sun.com/nithya/entry/new_security_features_in_glassfish1)

             

            Anyway, here is my current web.xml:

             

            <web-app xmlns="http://java.sun.com/xml/ns/javaee"

                      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                          http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
                      version="2.5">

             

              <servlet>
                 <servlet-name>AuthenticationServlet</servlet-name>
                 <servlet-class>mycompany.AuthenticationServlet</servlet-class>
               </servlet>

              <servlet-mapping>
                 <servlet-name>AuthenticationServlet</servlet-name>
                 <url-pattern>/hello</url-pattern>
               </servlet-mapping>

             

              <welcome-file-list>
                 <welcome-file>index.html</welcome-file>
               </welcome-file-list> 
             
              <security-constraint>
                 <display-name>Security Constraints with  Authorization</display-name>
               
                 <web-resource-collection>
                   <web-resource-name>AuthorizedPages</web-resource-name>
                   <url-pattern>/hello</url-pattern>
                   <http-method>GET</http-method>
                   <http-method>POST</http-method>
                 </web-resource-collection>
               
                <auth-constraint>
                   <role-name>*</role-name>
                </auth-constraint>
                
                <user-data-constraint>
                   <transport-guarantee>NONE</transport-guarantee>
                 </user-data-constraint>
              </security-constraint>

             

               <security-role>   
                <description>Authorized user  roles</description>
                <role-name>*</role-name>
               </security-role>

             

              <login-config>
                 <auth-method>BASIC</auth-method>
                 <realm-name>authentication</realm-name>
               </login-config>

             

            </web-app>

             

             

            Maybe JBoss has sample code that shows how this works? Or maybe there is a different way to configure an authenticator?

            • 3. Re: HttpServletRequest.authenticate error
              javaspack

              Ok. I have found a way to get it to work but it has become unnecessarily complex.

               

              In the Valve::start() method, if I add

                   this.context.setAuthenticator(this)

               

              then it works. The real problem is that the setAuthenticator method only exists in the new servlet 3.0 so it can't be assumed to be there, which means you have to create a way to handle this.

               

              I guess what I was expecting was something like this:

               

              <Context>

               

                <Valve className="com.mycompany.auth.MyValve" setAuthenticator="true"/>

              </Context>

               

              Then it is easy to configure and the Valve can easily throw any values it doesn't recognize (for code that predates the setAuthenticator stuff)

               

              Is this the expected way of handling this? Is there a better way?

              • 4. Re: HttpServletRequest.authenticate error
                jaikiran

                Sean Whyte wrote:

                 

                Or maybe there is a different way to configure an authenticator?

                Does this help http://community.jboss.org/message/532453 (I don't know if that thread applies to programatic authentication).

                • 5. Re: HttpServletRequest.authenticate error
                  javaspack

                  Unfortunately, not quite the same. A context can now have a default Authenticator associated with it, which is what I am trying to accomplish. The new 'setAuthenticator()' method appears to be specific to the JBossWeb implementation as no such method exists in the Tomcat code (even Tomcat7)

                   

                  My suggestion would be for JBoss to provide a more elegant way of configuring this, much like the login-config.xml is used as a better way to  configure where Tomcat requires a jaas.conf file. I think it would be nice to provide this in the context.xml file like I suggested earlier.

                   

                  Do any of the JBossWeb developers ever see suggestions from here?

                  • 6. Re: HttpServletRequest.authenticate error
                    jfclere

                    hm if you use a programatic logic in valves I think it makes more sense to program all instead mixing configuration file and program, no?

                    • 7. Re: HttpServletRequest.authenticate error
                      jfclere

                      See JBossWeb SVN: r1499 -    trunk/java/org/apache/catalina/startup... I think that  is what you need, you will have in M4

                      • 8. Re: HttpServletRequest.authenticate error
                        javaspack

                        Yes, I think that is it. The ContextConfig class has a method authenticatorConfig() which will configure a Valve that implements Authenticator as the default authenticator.

                         

                        I will look forward to trying the M4 release.