12 Replies Latest reply on Apr 24, 2006 6:30 PM by louisaj

    Connect to security service?

      How do you explicitly tell an application (.war) to use JBoss security in the jboss-web.xml file?

      If it can't be done there, can it be done in the jboss-app.xml or application.xml in an .ear file?

      The reason I ask is that my application (a war deployment) is using some libraries that conflict with ones in jboss (specifically some jakarta commons libraries for struts). To enable their use I've specified java2ClassLoadingCompliance="false" in the jboss-web.xml file. This works to allow the code depending on the newer libraries to work, but then my security and authentication stops working.

      I've turned up logging in log4j.xml to the max, and jboss gets very noisy, but when I login, nothing spits back to tell me what is wrong. It just returns a failed login.

      Version: Jboss 3.2.3
      JVM: j2sdk 1.4.2_05

      What follows is my security configuration. If I'm completely off my rocker, or simply using a version that's too old, or just need to read the documentation more somewhere, please let me know. As it stands I'm at a complete loss. I've seen other posts on the issue (referring to 4.x versions) and the solutions were to set java2ClassLoadingCompliance="true". Unfortunately that's going to require I write a lot more code to work around, and I'd prefer not to have to do that.

      Here are the relevant security entries from web.xml

      <security-constraint>
       <!--
       <display-name>Example Security</display-name>
       -->
       <web-resource-collection>
       <web-resource-name>Struts Blank</web-resource-name>
       <description></description>
       <url-pattern>*.do</url-pattern>
       </web-resource-collection>
       <auth-constraint>
       <role-name>Administrators</role-name>
       </auth-constraint>
       </security-constraint>
      
       <login-config>
       <auth-method>FORM</auth-method>
       <form-login-config>
       <form-login-page>/login.html</form-login-page>
       <form-error-page>/login.html?error_message=failed</form-error-page>
       </form-login-config>
       </login-config>
      
       <security-role>
       <role-name>Users</role-name>
       </security-role>
       <security-role>
       <role-name>Administrators</role-name>
       </security-role>


      Here's my complete jboss-web.xml:

      <jboss-web>
       <class-loading java2ClassLoadingCompliance="false" >
       <loader-repository>
       struts-blank.someurl.ca:loader=struts-blank.war
       <loader-repository-config>java2ParentDelegation=false</loader-repository-config>
       </loader-repository>
       </class-loading>
      
       <security-domain>java:/jaas/tagishNT</security-domain>
      </jboss-web>


      Here's the application-policy from the login-config.xml from the jboss-3.2.3//conf directory:

      <application-policy name = "tagishNT">
       <authentication>
       <login-module code = "ca.laj.TagishJBossLoginModule"
       flag = "required" />
       </authentication>
       </application-policy>



      I previously posted about this here, but may have taken the wrong approach in my query:
      http://www.jboss.com/index.html?module=bb&op=viewtopic&t=78503

      Topics that discuss this behaviour for other users:
      In Jboss 3.2.2
      http://www.jboss.com/index.html?module=bb&op=viewtopic&t=69557

      This individual has a personal security service, but shows the jndi naming being blocked (again java2 loading is false):
      http://www.jboss.com/index.html?module=bb&op=viewtopic&t=67850

      I've also read the following, and I do not have jboss jar's in my webapp (unless jakarta commons packages count):
      http://www.jboss.com/index.html?module=bb&op=viewtopic&t=74266

      Lastly I've read and tested against the following condition and am reasonably certain that I don't have org.jboss.* classes in my .war (I understand that I'm allowed to depend on them right? Just not include them?):
      http://www.jboss.org/index.html?module=bb&op=viewtopic&t=71536

      Scott Stark, if you read this, would you please give a brief explanation why org.jboss.* class will stop things if java2 loading is false?

      Is it possible that using java2ClassLoadingCompliance="false" would block jndi name lookups? (Thus preventing the jboss-web.xml configuration from being able to refer to a login configuration in the login-config.xml file?)

        • 1. Re: Connect to security service?
          j2ee_junkie

          louisaj,

          Thanks for posting more detail. I really think you need to read http://wiki.jboss.org/wiki/Wiki.jsp?page=JBossClassLoadingUseCases. This explains in great detail how your configurations change the classloading scheme. From what I can see, you probably should not have set java2ParentDelegation to false. I think this means that unless a class is present in your war, or the system classpath, your war's classloader will not find it.

          Hope this can help, cgriffith

          • 2. Re: Connect to security service?
            louisaj_work

            Ok, I've read through that. I think I now have at least a tenuous grip on ClassLoaders and Repositories. I've also read through http://wiki.jboss.org/wiki/Wiki.jsp?page=ClassLoadingConfiguration.

            Since java2ParentDelegation is disabled by default, I tried enabling it, as well as removing that line entirely. This had no apparent effect on the behaviour of the program and jaas security. I also tried setting java2ClassLoadingCompliance to true and providing a unique name for the class repository. This allowed the security mechanism to work, but the components that required the updated librariries started using the old libraries.

            Next step, delving into the jboss source code to see what exactly happens when a jaas:/security/service name is looked up to see why this silently fails with java2ClassLoadingCompliance=false

            • 3. Re: Connect to security service?
              j2ee_junkie

              louisaj,

              I was looking at the deployment you posted at laj.ca:8080. I am unfamiliar with using the embeded Tomcat 4.1. Where do you configure the Realm used for your engine/host/context?

              cgriffith

              • 4. Re: Connect to security service?
                louisaj_work

                A plain vanilla tomcat installation requires you to declare the realms and such. However, this is not necessary for an embedded tomcat installation in jboss. Instead you simply declare an <application-policy> in the
                server/< instance>/conf/login-config.xml file. You can see the application-policy I am using here:

                <application-policy name = "tagishNT">
                 <authentication>
                 <login-module code = "ca.laj.TagishJBossLoginModule"
                 flag = "required" />
                 </authentication>
                </application-policy>

                This policy acts in the same fashion as declaring a realm in tomcat. JBoss registers its security with tomcat through a valve (i think) in server/< instance>/deploy/jbossweb-tomcat41.sar/META-INF/jboss-service.xml
                <Valve className="org.jboss.web.tomcat.security.SecurityAssociationValve"/>

                This will make the application-policy take effect in tomcat in the usual way as a realm would.

                • 5. Re: Connect to security service?
                  louisaj_work

                  How Jboss actually gets the security system up is detailed under the JBoss SX wiki:
                  http://wiki.jboss.org/wiki/Wiki.jsp?page=JBossSX

                  • 6. Re: Connect to security service?
                    j2ee_junkie

                    louisaj_work,

                    Your assumptions are incorrect with regard to Tomcat security layer.

                    Tomcat has a server.xml file that configures the server. With Tomcat 5.5 embeded (and so I assume Tomcat 4.1), this server.xml file is in tomcat sar. I am interested in seeing what Realm you are using. In your example distribution, I see no designation of how your Tomcat server is configured.

                    The application policy does not 'act in the same fashion as declaring a realm'. The realm needs to be the org.jboss.web.tomcat.seucrity.JBossSecurityMgrRealm which delegates authentication/authoriztion to the security manager of your JBoss server for the application-policy you designate as your security-domain. Thus, what realm are you using?

                    maybe you should read [/url]http://wiki.jboss.org/wiki/Wiki.jsp?page=Tomcat, cgriffith

                    • 7. Re: Connect to security service?
                      louisaj_work

                      I'll read up on that. However, the assumptions I have made on how the security layer works are irrelevant. The point is that I have posted two examples. In one, the security authentication works with my custom login module. In the other one, security authentication does not work.

                      The only change I've made between the two is to set java2ClassLoadingCompliance to "false".

                      I have not touched the tomcat realm configuration. Also, it doesn't matter if I use my own custom login module, or one of the ones supplied by the core jboss instalation (like the users roles login module). If I configure my application to use any of them it works, until I set java2ClassLoadingCompliance to "false".

                      The configuration I have posted does work in JBoss 3.2.3. I am reasonably confident that I have not configured extra security realms in tomcat configuration files. I started with a vanilla Jboss 3.2.3 installation with tomcat 4 embedded, and made the changes detailed in the first post.
                      It works.
                      When I change java2ClassLoadingCompliance to "false" (in either the application's jboss-web.xml or in jbossweb-tomcat41.sar/META-INF/jboss-service.xml then and only then does security stop working.

                      • 8. Re: Connect to security service?
                        j2ee_junkie

                        louisaj,

                        I have looked into the configuration of Tomcat 4.1.x used in JBoss 3.2.3. It seems as though things are quite different for this version than Tomcat5.5 in JBoss 4.0.x. I am sorry if I lead you down the wrong track by my lack of knowledge (ie ignorance) on this version. It appears as though the servlet container is configured through the jbossweb-tomcat41.sar/META-INF/jboss-service.xml file. However, in this version the realm instance is not important. Like you said.

                        At this point my lack of knowledge on your particular configuration forces me to sit down, and shut-up. Sorry, I could not help more. cgriffith

                        • 9. Re: Connect to security service?

                          I've finally sat down and traced the code on this a little more. I've found the key difference as to why the secruity context is failing when java2ClassLoadingCompliance=false. However, I'm not able to tell yet why it's failing.
                          I'm about to check this all out on JBoss AS 4.0.3SP1. However our current environment is AS 3.2.3 and I don't have the power to change that.

                          Here's what I've got so far (in AS 3.2.3):

                          When a web app is first accessed, JBoss attempts to lookup it's security context from a new InitialContext(). This is done by
                          org.jboss.web.tomcat.security.JBossSecurityMgrRealm
                          during the first call to the
                          .invoke( Request, Response, ValveContext) method:

                          public void invoke(Request request, Response response, ValveContext context)
                           throws IOException, ServletException
                           {
                           try
                           {
                           try
                           {
                           Context securityCtx = getSecurityContext();
                           if( subjectAttributeName != null && securityCtx != null )


                          Then it calls out to .getSecurityContext():81 which returns null as the securityCtx:
                          private Context getSecurityContext()
                           {
                           Context securityCtx = null;
                           // Get the JBoss security manager from the ENC context
                           try
                           {
                           InitialContext iniCtx = new InitialContext(); // This works fine, but may not contain the security manager
                           securityCtx = (Context) iniCtx.lookup("java:comp/env/security");
                           }
                           catch(NamingException e)
                           {
                           // Apparently there is no security context?
                           //(louis@laj.ca) No there is one, but it fails to look it up (java2ClassLoading=false)
                           }
                           return securityCtx; // Return's null when java2ClassLoading=false
                           }


                          When it's left to the default: java2ClassLoadingCompliance="true" then it does find the security context.

                          I'm going to test this out in JBoss 4.0.3, and I'm digging deeper into the name lookups, but that's where I'm having trouble tracing the operation of the program. Given the posts I've mentioned previously about people needing to set java2ClassLoadingCompliance="true" (Since in 4.0.1 it's false by default) in order to enable jaas I don't expect it to suddenly work, but I'll post what I find out. More to follow as I get further in my investigation...

                          • 10. Re: Connect to security service?

                            P.S. When it's working (java2ClassLoadingCompliance=true), the securityCtx that is returned is called NamingContext, and I think it's a NamingManager.

                            • 11. Re: Connect to security service?

                              Good news is that I've tested in 4.0.3SP1 and it's working there. I did my tests just using the UsersRolesLoginModule, and initially against the 'other' security definition which worked.

                              Then I noted how tomcat5.5.sar (META-INF/jboss-service.xml) links to jaas/other by default. So I duplicated and renamed it in login-config.xml to try it as a 'different' login config, and it still worked.

                              login-config.xml:
                              <application-policy name = "sec-test">
                               <authentication>
                               <login-module code = "org.jboss.security.auth.spi.UsersRolesLoginModule"
                               flag = "required" />
                               </authentication>
                               </application-policy>
                              
                              jboss-web.xml:
                              <security-domain>java:/jaas/sec-test</security-domain>
                              


                              Paranoid as I am I decided that maybe it was just failing and going to 'other', I then changed the default security domain to jbossmq, to ensure that I wasn't magically failling back to 'other'
                              <attribute name="DefaultSecurityDomain">java:/jaas/jbossmq</attribute>


                              I know that UsersRolesLoginModule works. I still need to test with my custom login module, that will come tomorrow. If it works I'm going to pitch for a move to the new server, but I don't know if they'll go for it, and if they do, if it will be in my lifetime.

                              Given the still heavy use of 3.2.3 it would be nice to be able to resolve the original problem though.

                              • 12. Stop that! It is silly.

                                I've downloaded and tried it with JBoss 3.2.8 SP1 and now jaas works with java2ClassLoadingCompliance set to false. So both the past two threads I've been pushing on this have been in vain. JBoss has fixed the problem.

                                Given the still heavy use of 3.2.3 it would be nice to be able to resolve the original problem though.

                                Also, this is obviously an unreasonable request since a) it's been fixed in the 3.2.x stream, and b) they'd have to realease what? 3.2.3 SP1 ? Probably not happening.

                                I think I found the reference to what took care of this issue. In the release notes for JBoss 3.2.6RC2 there's a note about jaas:
                                https://sourceforge.net/docman/display_doc.php?docid=24862&group_id=22866
                                JBossWeb
                                Externalize the JAAS based authentication and authorization realm implementation to server.xml and specify the default certificatePrincipal attribute. The certificatePrincipal attribute gives the class name of the org.jboss.security.auth.certs.CertificatePrincipal impl used for mapping X509[] cert chains to a Princpal.

                                I could be wrong in my reading of this, but if the jaas realm is externalized, then it will be able to look up jndi names properly again, and thus will be able to access defined login-config's independantly of the web context that's it's working for.

                                In short: I feel silly. Very, very silly.