4 Replies Latest reply on Oct 31, 2003 6:29 AM by shorero

    Web App Authentication?

    shorero

      I want to set up a web app to use BASIC authentication. I've got the web app set up to trigger a particular set of LoginModule implementations, but the userid and password don't seem to be visible.

      One of the LoginModule objects is a dummy module that always succeeds but as a side-effect prints out the current authentication environment: all the stuff from the Subject, the current shared space, the principal and credential from the SecurityAssociation, and the results returned from Name and Password callbacks. I see this stuff being logged, which means that my login-module stack is being triggered at the proper place in the processing. However, I don't see the userid, much less the password, in any of the logged info coming out of my special LoginModule. In particular, the name callback and the password callback are always returning null.

      What am I doing wrong here?

        • 1. Re: Web App Authentication?
          jkuhn

          Can you show us the code that creates your LoginContext?
          And also the login-config.xml from your jboss/conf directory.

          • 2. Re: Web App Authentication?
            shorero

            I'm not entirely sure what you're asking. I'm not creating a LoginContext at any point in this process - I assume that the login context is being built someplace in the BASIC authentication processing. Specifically, looking at thread dumps from my login module, it appears that catalina's BasicAuthentication class is passing userid/password info down through JBossSecurityMgrRealm -- eventually an instance of JaasSecurityManager gets the isValid() request and builds the callback handler. None of this is my code.

            Here's the relevant part of login-config.xml:
            ==============
            <application-policy name = "TemplarDomain">

            <login-module code = "com.templar.jboss.ext.LoginInfoDumper"
            flag = "optional">
            <module-option name="policy-name">TemplarDomain</module-option>
            <module-option name="dump-stack">true</module-option>
            </login-module>
            <login-module code = "org.jboss.security.auth.spi.UsersRolesLoginModule"
            flag = "required" >
            <module-option name="password-stacking">true</module-option>
            </login-module>
            <login-module code = "com.templar.jboss.ext.ClientHostLoginModule"
            flag = "optional">
            <module-option name="allow-range">192.168.0.0/255.255.255.0</module-option>
            <module-option name="caller-principal">LANuser</module-option>
            <module-option name="roles">LANuser local-user</module-option>
            </login-module>
            <login-module code = "com.templar.jboss.ext.LoginInfoDumper"
            flag = "optional">
            <module-option name="policy-name">TemplarDomain</module-option>
            </login-module>

            </application-policy>
            ====================
            I know that this is getting execerised 'cause the debug logging in LoginInfoDumper is showing up in the server's log. I can post the entire class if you want to see it, but the key dumpInfo() method is the following:
            ==========================
            private void dumpInfo() {
            DEBUG("Subject:");
            Set x = subject.getPrincipals();
            int count = 0;
            for (Iterator i = x.iterator(); i.hasNext();) {
            Object y = i.next();
            ++count;
            DEBUG(" Principal #" + count + " (" + y.getClass() + "): " + y);
            }
            x = subject.getPrivateCredentials();
            count = 0;
            for (Iterator i = x.iterator(); i.hasNext();) {
            Object y = i.next();
            ++count;
            DEBUG(
            " Private Credential #"
            + count
            + " ("
            + y.getClass()
            + "): "
            + y);
            }
            x = subject.getPublicCredentials();
            count = 0;
            for (Iterator i = x.iterator(); i.hasNext();) {
            Object y = i.next();
            ++count;
            DEBUG(
            " Public Credential #"
            + count
            + " ("
            + y.getClass()
            + "): "
            + y);
            }
            DEBUG("Info: callback handler " + callbackHandler);
            DEBUG("Info: sharedState " + sharedState);
            if (callbackHandler != null) {
            Callback[] callbacks = new Callback[1];
            ObjectCallback callback =
            new ObjectCallback(
            TemplarAssociationHandler.CLIENT_HOST_REQUEST);
            callbacks[0] = callback;
            try {
            callbackHandler.handle(callbacks);
            DEBUG("Info: client host: " + callback.getCredential());
            } catch (Throwable e) {
            e.printStackTrace();
            // oh well...
            }
            }
            DEBUG("SA: principal "+SecurityAssociation.getPrincipal());
            DEBUG("SA: credential "+SecurityAssociation.getCredential());
            }
            ====================
            When I attempt to access the protected web page, I see entries in the log like the following (edited a bit to save space but including the stack trace from the initial LoginInfoDumper entry:
            ======================
            INFO [LoginInfoDumper] Initialize TemplarDomain: options={policy-name=TemplarDomain, dump-stack=true}
            INFO [LoginInfoDumper] Subject:
            INFO [LoginInfoDumper] Info: callback handler javax.security.auth.login.LoginContext$SecureCallbackHandler@1628b8d
            INFO [LoginInfoDumper] Info: sharedState {}
            INFO [LoginInfoDumper] Info: client host: null
            INFO [LoginInfoDumper] SA: principal null
            INFO [LoginInfoDumper] SA: credential null
            ERROR [STDERR] java.lang.Exception: Stack trace
            ERROR [STDERR] at java.lang.Thread.dumpStack(Thread.java:1064)
            ERROR [STDERR] at com.templar.jboss.ext.LoginInfoDumper.initialize(LoginInfoDumper.java:164)
            ERROR [STDERR] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            ERROR [STDERR] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
            ERROR [STDERR] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
            ERROR [STDERR] at java.lang.reflect.Method.invoke(Method.java:324)
            ERROR [STDERR] at javax.security.auth.login.LoginContext.invoke(LoginContext.java:662)
            ERROR [STDERR] at javax.security.auth.login.LoginContext.access$000(LoginContext.java:129)
            ERROR [STDERR] at javax.security.auth.login.LoginContext$4.run(LoginContext.java:610)
            ERROR [STDERR] at java.security.AccessController.doPrivileged(Native Method)
            ERROR [STDERR] at javax.security.auth.login.LoginContext.invokeModule(LoginContext.java:607)
            ERROR [STDERR] at javax.security.auth.login.LoginContext.login(LoginContext.java:534)
            ERROR [STDERR] at org.jboss.security.plugins.JaasSecurityManager.defaultLogin(JaasSecurityManager.java:487)
            ERROR [STDERR] at org.jboss.security.plugins.JaasSecurityManager.authenticate(JaasSecurityManager.java:442)
            ERROR [STDERR] at org.jboss.security.plugins.JaasSecurityManager.isValid(JaasSecurityManager.java:244)
            ERROR [STDERR] at org.jboss.security.plugins.JaasSecurityManager.isValid(JaasSecurityManager.java:219)
            ERROR [STDERR] at org.jboss.web.tomcat.security.JBossSecurityMgrRealm.authenticate(JBossSecurityMgrRealm.java:281)
            ERROR [STDERR] at org.apache.catalina.authenticator.BasicAuthenticator.authenticate(BasicAuthenticator.java:161)
            ERROR [STDERR] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:528)
            ERROR [STDERR] at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
            ERROR [STDERR] at org.apache.catalina.valves.CertificatesValve.invoke(CertificatesValve.java:246)
            ERROR [STDERR] at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
            ERROR [STDERR] at org.jboss.web.tomcat.tc4.statistics.ContainerStatsValve.invoke(ContainerStatsValve.java:76)
            ERROR [STDERR] at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
            ERROR [STDERR] at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
            ERROR [STDERR] at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
            ERROR [STDERR] at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2416)
            ERROR [STDERR] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180)
            ERROR [STDERR] at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
            ERROR [STDERR] at org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:171)
            ERROR [STDERR] at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
            ERROR [STDERR] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:172)
            ERROR [STDERR] at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
            ERROR [STDERR] at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:65)
            ERROR [STDERR] at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
            ERROR [STDERR] at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:577)
            ERROR [STDERR] at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
            ERROR [STDERR] at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
            ERROR [STDERR] at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
            ERROR [STDERR] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:174)
            ERROR [STDERR] at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
            ERROR [STDERR] at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
            ERROR [STDERR] at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
            ERROR [STDERR] at org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:223)
            ERROR [STDERR] at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:601)
            ERROR [STDERR] at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:392)
            ERROR [STDERR] at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:565)
            ERROR [STDERR] at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:619)
            ERROR [STDERR] at java.lang.Thread.run(Thread.java:534)
            INFO [LoginInfoDumper] Login
            INFO [LoginInfoDumper] Subject:
            INFO [LoginInfoDumper] Info: callback handler javax.security.auth.login.LoginContext$SecureCallbackHandler@1628b8d
            INFO [LoginInfoDumper] Info: sharedState {}
            INFO [LoginInfoDumper] Info: client host: null
            INFO [LoginInfoDumper] SA: principal null
            INFO [LoginInfoDumper] SA: credential null
            INFO [LoginInfoDumper] User name: null
            INFO [LoginInfoDumper] Credential:null
            INFO [LoginInfoDumper] Initialize TemplarDomain: options={policy-name=TemplarDomain}
            INFO [LoginInfoDumper] Subject:
            INFO [LoginInfoDumper] Info: callback handler javax.security.auth.login.LoginContext$SecureCallbackHandler@1628b8d
            INFO [LoginInfoDumper] Info: sharedState {}
            INFO [LoginInfoDumper] Info: client host: null
            INFO [LoginInfoDumper] SA: principal null
            INFO [LoginInfoDumper] SA: credential null
            INFO [LoginInfoDumper] Login
            INFO [LoginInfoDumper] Subject:
            INFO [LoginInfoDumper] Info: callback handler javax.security.auth.login.LoginContext$SecureCallbackHandler@1628b8d
            INFO [LoginInfoDumper] Info: sharedState {}
            INFO [LoginInfoDumper] Info: client host: null
            INFO [LoginInfoDumper] SA: principal null
            INFO [LoginInfoDumper] SA: credential null
            INFO [LoginInfoDumper] User name: null
            INFO [LoginInfoDumper] Credential:null
            INFO [LoginInfoDumper] Abort TemplarDomain
            INFO [LoginInfoDumper] Abort TemplarDomain
            =========================
            As expected, we're seeing two invocations of LoginInfoDumper, one at the top of the stack and one at the bottom. In both cases the user name and credential returned from the callback are null.

            • 3. Re: Web App Authentication?
              shorero

              I have another piece of information. I've now got some debug output in a replacement for JaasSecurityMgrRealm, which is the first class that gets the authentication request from the catalina BasicAuthentication class. At that point I'm seeing the userid and password as entered in the web browser's uid/pwd dialog. So at that point the uid/pwd is intact.

              So, at someplace between the security mgr realm and the login module the principal and credential are being eaten. Actually, I see two calls through the security mgr realm. The first has a null uid and null pwd and undoubtedly represents the browser's first attempt to access the page. The second one contains the uid/pwd entered on the browser's login dialog. Is it possible that this null entry is confusing JaasSecurityManager? I can't see how, but I don't have sufficient debug in the code to be sure.

              • 4. Re: Web App Authentication?
                shorero

                I am embarassed to say that I have found the enemy and it is me. I had other JBoss extensions that were not properly integrated with the basic code; my extensions were eating the basic auth userid and password.

                I apologize to anyone who wasted time trying to help me.