When running with the JAASRealm, the container sets the JAAS application name to be the container's name: --- 8< --- JAASRealm.java --- 8< --- public void setContainer(Container container) { super.setContainer(container); String name=container.getName(); if( appName==null ) { appName=name; log.info("Setting JAAS app name " + appName); } } --- 8< --- JAASRealm.java --- 8< --- However, the container's name always starts with a /, which isn't an allowable name in the JAAS specification: --- 8< --- stdout --- 8< --- ... INFO: Setting JAAS app name /MyApp ... --- 8< --- stdout --- 8< --- --- 8< --- jaas.conf --- 8< --- /MyApp { com.example.MyJAASLoginModule required; }; --- 8< --- jaas.conf --- 8< --- The Sun Security barfs at the '/' on leading MyApp, so it can't be speficied. The default name 'Tomcat' doesn't work either, because the JAAS name has already been set, and this cannot be set in the config file. Instead, you have to use 'other' which is applicable to all apps in the application. The fix would be to check whether there are any unprintable characters in the application name, and if so, fix them. Of course, what constitutes an unprintable character is up to Sun's Configuration parser, which probably isn't that good. A quick fix would be: --- 8< --- JAASRealm.java.fix --- 8< --- public void setContainer(Container container) { super.setContainer(container); String name=container.getName(); if( appName==null ) { if (name.startsWith("/")) name.substring(1); appName=name; log.info("Setting JAAS app name " + appName); } } --- 8< --- JAASRealm.java.fix --- 8< --- but in reality, you'd need to check for all other non-printable characters and replace/delete them as appropriate, because a name may have other / characters (e.g. /MyApp/Other).
Of course, I meant 'name=name.substring(1)'.
Can you point to the class or code in "Sun Security" that "barfs" at the leading slash please? Also if you could attach your suggested patch in .diff format, that'd be great. Thanks ;)
I'm not sure I can find the code for the barf, because I don't have the Sun source code :-) I think the problem is in com.sun.security.auth.login.ConfigFile which is the class reading the jaas.config file (actually, the name isn't relevant -- it's the file pointed to by the URL in -Djava.security.auth.login.config or by default in ${user.home}/.java.login.config) The JavaDoc isn't up to much: ConfigFile is http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/spec/com/sun/security/auth/login/ConfigFile.html which says it parses the file with the syntax described in: http://java.sun.com/j2se/1.4.2/docs/api/javax/security/auth/login/Configuration.html and all it says in there is "Each entry in the Configuration is indexed via an application name. ApplicationName { ModuleClass Flag ModuleOptions; ModuleClass Flag ModuleOptions; ModuleClass Flag ModuleOptions; }; " So Tomcat is setting the name OK programmatically, but the ConfigFile parser only seems to allow [a-zA-Z]+ as the ApplicationName, so fails at the initial / Thus, if you try and use a config file: /MyAppRoot { com.example.LoginModule required; }; then the ConfigFile parser doesn't successfully read it. It seems that the ConfigFile uses lazy loading, so it doesn't parse the first login request when using JAAS. Sorry, can't paste in .diff format; I don't have the Tomcat source code on a machine with a '.diff' command -- I just eyeballed the problem to find out why the name was being set with a leading '/'.
OK, done for both 5.0.29 and 5.5.3. My initial implementation is simply to remove leading slash if one is present. I made the relevant method protected so extenders of JAASRealm can easily modify this behavior.