4 Replies Latest reply on Aug 14, 2006 8:15 AM by ppareit

    Webapp Auth/Auth with Custom LoginModule Principals

    gkushida

      I'm trying to port an existing web application from Tomcat (5.5.16) to JBoss (4.0.3rc1). This app uses an existing JAAS LoginModule, which uses custom User and Role principals. I am currently trying to get JBoss to propagate these custom Principal implementations to my webapp. The sticking point, I think, is that I don't know where to define the custom userClass and roleClass returned by my custom LoginModule.

      In Tomcat, I had to upgrade to 5.5.16 to get this to work, so it's entirely possible that this will not work in the current JBoss version. My Tomcat server.xml has a (sanitized) Realm definition like this:

       <Realm className="org.apache.catalina.realm.JAASRealm"
       debug="0"
       appName="FooLogin"
       userClassNames="com.foo.jaas.FooUser"
       roleClassNames="com.foo.jaas.FooRole"
       resourceName="FooRealm"
       useContextClassLoader="true"/>
      


      As well as a jaas.config file:
      FooLogin {
       com.foo.jaas.FooLoginModule required;
      };
      


      I set up a similar configuration in JBoss: conf/foo-login-config.xml (loaded by deploy/foo-login-config-service.xml)
       <application-policy name = "FooRealm">
       <authentication>
       <login-module code = "com.foo.jaas.FooLoginModule" flag="required"/>
       </authentication>
       </application-policy>
      


      But I am not sure how to indicate that JAAS should use my FooUser and FooRole classes. The closest thing I could find is here:
      http://www.jboss.com/index.html?module=bb&op=viewtopic&t=45724&postdays=0&postorder=asc&start=10

      Which sets a "principalClass" module-option for UsersRolesLoginModule (among other things):
       <module-option name = "principalClass">org.jboss.test.security.ejb.CustomPrincipalImpl</module-option>
      


      I've seen similar configurations in other posts, but they all use LoginModules that extend some JBoss login module (generally the database one). However, this won't work for me for several reasons:
      - My LoginModule doesn't extend JBoss classes
      - My custom User and Role classes are not the same class, although they are both Principals

      Am I trying to do something that is just not possible?

      When doing this in Tomcat, I had to upgrade to 5.5.16 to get the custom userClassNames and roleClassNames attributes in the Realm definition to actually work. It's possible that I'm running into the same thing with the bundled tomcat (5.5.9 I believe). But I'm not sure, because that particular bug was fixed in the org.apache.catalina.realm.JAASRealm implementation, which I don't think is in play here.

      Any help would be appreciated, thanks?


        • 1. Re: Webapp Auth/Auth with Custom LoginModule Principals
          starksm64

          See:
          http://wiki.jboss.org/wiki/Wiki.jsp?page=UsingCustomPrincpalsWith

          We have no notion of a custom role as its an internal detail. What is you use for a custom role class?

          • 2. Re: Webapp Auth/Auth with Custom LoginModule Principals
            gkushida

            Thanks for the quick response!

            Actually, I don't specifically need a custom Role class, that was just how the existing Login Module works.

            The LoginModule is not JBoss-specific, so it does not extend UsernamePasswordLoginModule or use SimpleGroup/SimplePrincipal.

            In the initialize() method, I set the provided Subject as a member variable.

            In the login() method, after a successful login, I create a custom User Principal (and Role Principal(s), but let's not worry about that for now). Those get assigned to other member vars.

            In the commit() method, I add the user and roles to the Subject stored earlier:

             mSubject.getPrincipals().add(mUserPrincipal);
             mSubject.getPrincipals().addAll(mPrincipals);
            


            On the Wiki page, this is somewhat different; the caller principal gets added to a "CallerPrincipal" group which is then added to the Subject. Also, there is the 'principalClass' defined as a module-option for the CustomPrincipalLoginModule.

            I can see how to do the former - if necessary i could create my own Group impl (since the login module doesn't have access to SimpleGroup).

            But I don't know how to deal with the custom principalClass module-option. How would i use the custom principal in a custom Login Module with no JBoss dependencies?


            • 3. Re: Webapp Auth/Auth with Custom LoginModule Principals
              ppareit

              I have the same problem:

              I use the following realm code:

              if (!subject.getPrincipals().contains(userPrincipal))
               subject.getPrincipals().add(userPrincipal);
              subject.getPrincipals().addAll(rolePrincipals);
              


              Where userPrinipal an instance of UserPrincipal (Framework class), and RolePrincipals is ArrayList (Framework class).

              In my application I use the following code:


              locale = (Locale) principal.getClass().getMethod("getLocale",(Class[]) null).invoke(principal, (Object[]) null);
              
              dateFormat = (String) principal.getClass().getMethod("getDateFormat", (Class[]) null).invoke(principal,(Object[]) null);
              


              On a Tomcat 5.5 server everything works fine.

              On Jboss 4.0.4 GA: I get the following exception:

              java.lang.NoSuchMethodException: org.jboss.security.SimplePrincipal.getLocale()
               at java.lang.Class.getMethod(Class.java:1581)
               at com.easypaygroup.framework.control.userprofile.UserProfile.<init>(UserProfile.java:70)
               at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
               at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
               at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
               at java.lang.reflect.Constructor.newInstance(Constructor.java:494)
               at java.lang.Class.newInstance0(Class.java:350)
               at java.lang.Class.newInstance(Class.java:303)
               at org.apache.myfaces.shared_impl.util.ClassUtils.newInstance(ClassUtils.java:274)
               at org.apache.myfaces.shared_impl.util.ClassUtils.newInstance(ClassUtils.java:265)
               at org.apache.myfaces.config.ManagedBeanBuilder.buildManagedBean(ManagedBeanBuilder.java:50)
               at org.apache.myfaces.el.VariableResolverImpl.resolveVariable(VariableResolverImpl.java:311)
               at org.apache.myfaces.config.LastVariableResolverInChain.resolveVariable(LastVariableResolverInChain.java:42)
               at org.apache.myfaces.el.ValueBindingImpl$ELVariableResolver.resolveVariable(ValueBindingImpl.java:574)
               at org.apache.commons.el.NamedValue.evaluate(NamedValue.java:124)
               at org.apache.commons.el.ComplexValue.evaluate(ComplexValue.java:140)
               at org.apache.myfaces.el.ValueBindingImpl.getValue(ValueBindingImpl.java:383)
               at org.apache.myfaces.taglib.core.ViewTag.setProperties(ViewTag.java:199)
               at javax.faces.webapp.UIComponentTag.findComponent(UIComponentTag.java:536)
               at javax.faces.webapp.UIComponentTag.doStartTag(UIComponentTag.java:312)
               at org.apache.myfaces.taglib.core.ViewTag.doStartTag(ViewTag.java:70)
               at org.apache.jsp.com.easypaygroup.easytest.webapp.menu.menu_jsp._jspService(menu_jsp.java:64)
               at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)
               at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
               at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
              
              ............
              
              java.lang.IllegalArgumentException: Locale or String class expected. Expression: #{UserProfile.locale}. Return value nul
              l
               at org.apache.myfaces.taglib.core.ViewTag.setProperties(ViewTag.java:218)
               at javax.faces.webapp.UIComponentTag.findComponent(UIComponentTag.java:536)
               at javax.faces.webapp.UIComponentTag.doStartTag(UIComponentTag.java:312)
               at org.apache.myfaces.taglib.core.ViewTag.doStartTag(ViewTag.java:70)
               at org.apache.jsp.com.easypaygroup.easytest.webapp.menu.menu_jsp._jspService(menu_jsp.java:64)
               at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)
               at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
               at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
               at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
               at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:672)
               at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:463)
               at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:398)
               at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:301)
               at org.apache.myfaces.context.servlet.ServletExternalContextImpl.dispatch(ServletExternalContextImpl.java:416)
               at org.apache.myfaces.application.jsp.JspViewHandlerImpl.renderView(JspViewHandlerImpl.java:234)
               at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:367)
               at javax.faces.webapp.FacesServlet.service(FacesServlet.java:138)
               at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
               at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
               at com.easypaygroup.framework.hibernate.CloseSessionFilter.doFilter(CloseSessionFilter.java:28)
               at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
               at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
               at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:144)
               at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
               at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
               at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
               at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
               at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
               at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
               at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
               at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:175)
               at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:524)
               at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74)
               at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
               at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
               at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
               at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
               at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
               at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java
              :664)
               at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
               at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
               at java.lang.Thread.run(Thread.java:595)
              


              • 4. Re: Webapp Auth/Auth with Custom LoginModule Principals
                ppareit

                Problem found!

                I have added my realm config also in the jboss-4.0.4.GA-simple\server\default\deploy\jbossweb-tomcat55.sar server.xml config.

                and that was enough

                Cya,
                Pieter