Spring Security
  1. Spring Security
  2. SEC-1700

IOException in JaasAuthenticationProvider when loginConfig is a classpath resource in JBoss 5.1.0.GA

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 3.0.5
    • Fix Version/s: 3.1.0.RC2, 3.0.6
    • Component/s: Core
    • Labels:
      None

      Description

      Here is a snippet of my security config file showing my declaration of the JaasAuthenticationProvider:

      <b:bean id="jaasAuthenticationProvider" class="org.springframework.security.authentication.jaas.JaasAuthenticationProvider">
      <b:property name="loginConfig" value="classpath:auth.conf" />
      ...
      </b:bean>

      Here is the exception thrown when starting up the application:

      org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jaasAuthenticationProvider' defined in class path resource [applicationContext-security.xml]: Invocation of init method failed; nested exception is java.io.IOException: File resolution not supported for nested resource: ZipEntryHandler@30251001[path=application.ear/application-main-4.5.0.jar/auth.conf context=file:/C:/tools/jboss-5.1.0.GA/server/default/deploy/ real=file:/C:/tools/jboss-5.1.0.GA/server/default/deploy/application.ear/application-main-4.5.0.jar/auth.conf]
      at org.springframework.beans.factory.access.SingletonBeanFactoryLocator.useBeanFactory(SingletonBeanFactoryLocator.java:389)

      Digging through the Spring code, I found that the exception is being thrown from the getFile() method of VfsUtils, which is called from VfsResource.getFile(). Apparently under JBoss, the classpath resource is resolved to a VfsResource. The first line of the method JaasAuthenticationProvider.convertLoginConfigToUrl() calls loginConfig.getFile().getAboslutePath(). Looking at the code in VfsUtils, it appears that the version of the JBoss VFS used with JBoss 5 doesn't support the getFile() method, and throws the IOException noted above.

      Even if it weren't for this problem, the code in JaasAuthenticationProvider.convertLoginConfigToUrl() appears to assume that the loginConfig is a file in the file system. Any other type of resource looks as though it would not work.

      To test this theory, I wrote a subclass of JaasAuthenticationProvider, and replaced the convertLoginConfigToUrl method with the following code:

      private String convertLoginConfigToUrl() throws IOException

      { return getLoginConfig().getURL().toString(); }

      This solved my problem.

        Activity

        Hide
        Luke Taylor added a comment -

        If you check the file history, you'll see that it used to actually be implemented that way. However that causes other problems - see SEC-1239, which explains why it was changed to the current version.

        Given that there seem to also be problems with the behaviour of the underlying Sun classes, it doesn't seem possible to satisfy everyone's setup. Therefore, I'd recommend that you override the configureJaas() method to work with your particular environment.

        Show
        Luke Taylor added a comment - If you check the file history, you'll see that it used to actually be implemented that way. However that causes other problems - see SEC-1239 , which explains why it was changed to the current version. Given that there seem to also be problems with the behaviour of the underlying Sun classes, it doesn't seem possible to satisfy everyone's setup. Therefore, I'd recommend that you override the configureJaas() method to work with your particular environment.
        Hide
        Luke Taylor added a comment - - edited

        I guess as an alternative, we could always try to catch the IOException and failover to the original getURL() approach, but in the meantime, overriding configureJaas() is your best bet.

        Show
        Luke Taylor added a comment - - edited I guess as an alternative, we could always try to catch the IOException and failover to the original getURL() approach, but in the meantime, overriding configureJaas() is your best bet.
        Hide
        Morley Howell added a comment -

        Yes, catching the exception and failing over could make sense.

        What about solving SEC-1239 by decoding the URL returned by loginConfig.getURL().toString()? This would replace the %20 character with a space.

        Show
        Morley Howell added a comment - Yes, catching the exception and failing over could make sense. What about solving SEC-1239 by decoding the URL returned by loginConfig.getURL().toString()? This would replace the %20 character with a space.
        Hide
        Morley Howell added a comment -

        I.e:

        private String convertLoginConfigToUrl() throws IOException

        { return URLDecoder.decode(getLoginConfig().getURL().toString, "UTF-8"); }
        Show
        Morley Howell added a comment - I.e: private String convertLoginConfigToUrl() throws IOException { return URLDecoder.decode(getLoginConfig().getURL().toString, "UTF-8"); }
        Hide
        Rob Winch added a comment -

        I realize you are using Spring Security 3.0.x, but as a note in Spring Security 3.1 you can use the DefaultJaasAuthenticationProvider which allows the configuration to be injected into it independent of a configuration file [1]

        [1] http://static.springsource.org/spring-security/site/docs/3.1.x/reference/jaas.html#jaas-defaultjaasauthenticationprovider

        Show
        Rob Winch added a comment - I realize you are using Spring Security 3.0.x, but as a note in Spring Security 3.1 you can use the DefaultJaasAuthenticationProvider which allows the configuration to be injected into it independent of a configuration file [1] [1] http://static.springsource.org/spring-security/site/docs/3.1.x/reference/jaas.html#jaas-defaultjaasauthenticationprovider
        Hide
        Luke Taylor added a comment -

        The decoding option caused failures in existing tests. I've implemented the approach whereby the exception is caught and resource.getURL() used in that case.

        Show
        Luke Taylor added a comment - The decoding option caused failures in existing tests. I've implemented the approach whereby the exception is caught and resource.getURL() used in that case.

          People

          • Assignee:
            Luke Taylor
            Reporter:
            Morley Howell
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: