2 Replies Latest reply on Jun 16, 2014 11:29 AM by Juergen H

    wildfly8 jaas authentication issues: IdentityManager.verify(Account), CallerPrincipal

    Juergen H Newbie

      So I'm trying to migrate a webapp from jboss-4.2.3.GA to wildlfy-8.1.CR1, and I got issues with Authentication

       

      1) org.wildfly.extension.undertow.security.JAASIdentityManagerImpl is used. Why does its verify(Account) reauthenticate?

      verify will happen on every request, so my defined login modules are executed - ldap bind included - on every request?

       

      2) verify(Account) reauthenticate DOES NOT take CallerPrincipal username mapping into consideration. reauthenticate will always fail for me

      I basically map the login username used for ldap bind and remap it to an application used username, which also is stored in Account.username

      reauthenticate on every request via verify(Account) using the remapped username for ldap bind will always fail

       

      My plan of attack is to replace org.wildfly.extension.undertow.security.JAASIdentityManagerImpl with a overridden custom version where verify(Account) will return account.

       

      3) next to no logging in undertow and such? I had to debug into wildfly code to find this issue.

       

      4) Account does store credentials? seems quite unsecure to me, especially if you do not use the inmemory session store, or persist sessions

       

      5) org.jboss.security.auth.spi.AbstractServerLoginModule.commit() will auto-create a CallerPrincipal group and add the identity as a member

      So basically the very first login module will add a CallerPrincipal group even if it does not define this role group on its own.

      Any follow-up login module that does define a specific CallerPrincipal will have its role group added to the auto-created group.

      BUT caller principal mapping later on will only take the very first principal in the role group which will be the auto-created identity

       

      My workaround is to basically override commit() and remove any existing (auto-created) CallerPrincipal role group to replace it with a specified one.

       

      EDIT (reply function yielded a blank error)

       

      I just found that JAASIdentityManagerImpl is created hardcoded in

      private org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService.handleIdentityManager(DeploymentInfo):

      deploymentInfo.setIdentityManager(new JAASIdentityManagerImpl(sdc));

       

      So no easy way to replace this crappy verify(Account) behaviour

       

      Have to think about a new workaround...

        • 1. Re: wildfly8 jaas authentication issues: IdentityManager.verify(Account), CallerPrincipal
          jaikiran pai Master

          Juergen H wrote:

           

          So I'm trying to migrate a webapp from jboss-4.2.3.GA to wildlfy-8.1.CR1, and I got issues with Authentication

          ....

          I just found that JAASIdentityManagerImpl is created hardcoded in

          private org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService.handleIdentityManager(DeploymentInfo):

          deploymentInfo.setIdentityManager(new JAASIdentityManagerImpl(sdc));

           

          So no easy way to replace this crappy verify(Account) behaviour

           

          Have to think about a new workaround...

          I haven't fully read or understood the question/problem. But have you given 8.1.0.Final a try? It has been released more than a week back.

          1 of 1 people found this helpful
          • 2. Re: Re: wildfly8 jaas authentication issues: IdentityManager.verify(Account), CallerPrincipal
            Juergen H Newbie

            Thanks for your info about 8.1.0.Final release. I upgraded.

             

            My problem still exists though. I'll try to make it more clear:

             

            I use a JAAS login configuration in my webapp, declared in standalone.xml. Wildfly plugs a JAASIdentityManagerImpl into my application.

             

            Now my issues:

             

            1.

            public Account verify(Account account) in JAASIdentityManagerImpl

            will reauthenticate the account (invoking the defined login modules, including a ldap bind in my case)

            now verify will be called for every request.

            This in itself is a huge performance issue I think.


            btw. org.jboss.as.domain.http.server.security.RealmIdentityManager simple does

            public Account verify(Account account) { return account; }


            2.

            to enable verify / reauthenticate, org.wildfly.extension.undertow.security.AccountImpl stores the credentials in cleartext during its lifetime.

            This seems like a security security issue to me, especially if the Account is persisted as part of the sesssion, if sessions are not only stored in-memory


            3.

            JBoss Authentication allows to define a "CallerPrincipal" role group. If it exists, the first member of this group will replace the original username as the subjects identity

            So "John" logging in with password "mypass" with a Role Group "CallerPrincipal" containing Principal "Mary" will result in the authenticated Account principal "Mary" with credentials "mypass"

            I use this CallerPrincipal mapping to map from ldap username "John" to application username "Mary". That "Mary" was "John" is I think lost in the session stored Account.

             

            Now here is where JAASIdentityManagerImpl.verify() not only becomes a performance issue, but is buggy: It does not take CallerPrincipal mapping into account.

            Basically - in my example - on the very next request after login of "John", CachedAuthenticatedSessionMechanism calles JAASIdentityManagerImpl.verify() with Account "Mary" / "mypass"

            verify invokes jaas login modules with "Mary" / "mypass" and login fails ("Mary" is not known, "John" was) and the authenticated session is invalidated.

             

            4.

            injection of org.wildfly.extension.undertow.security.JAASIdentityManagerImpl is hardcoded, I can't easily replace it a custom IdentityManager that does not reauthenticate on verify.

            private void org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService.handleIdentityManager(final DeploymentInfo deploymentInfo) {

                 deploymentInfo.setIdentityManager(new JAASIdentityManagerImpl(sdc));

            }


            But after a bit of thinking, I made a workaround for this issues. I created a ServletExtension as documented in http://undertow.io/documentation/servlet/using-non-blocking-handlers-with-servlet.html

            It takes the JAAS-IDM from deploymentInfo and wraps a delegate around that simply returns account in case of verify:


            package wildfly.workaround;
            
            import io.undertow.security.idm.Account;
            import io.undertow.security.idm.Credential;
            import io.undertow.security.idm.IdentityManager;
            import io.undertow.servlet.api.DeploymentInfo;
            
            import javax.servlet.ServletContext;
            
            public class NonVerifyingIdentityManagerExtension implements io.undertow.servlet.ServletExtension {
              public static class NonVerifyingIdentityManagerDelegate implements IdentityManager {
                protected IdentityManager delegate;
            
                public NonVerifyingIdentityManagerDelegate(IdentityManager delegate) {
                  super();
                  this.delegate = delegate;
                }
            
                public Account verify(Account account) {
                  return account;
                }
            
                public Account verify(String id, Credential credential) {
                  return delegate.verify(id, credential);
                }
            
                public Account verify(Credential credential) {
                  return delegate.verify(credential);
                }
               
              }
            
              public NonVerifyingIdentityManagerExtension() {
              }
            
              public void handleDeployment(DeploymentInfo deploymentInfo, ServletContext servletContext) {
                IdentityManager idm = deploymentInfo.getIdentityManager();
                idm = createNonIdentityManagerDelegate(idm);
                deploymentInfo.setIdentityManager(idm);
              }
            
              public IdentityManager createNonIdentityManagerDelegate(IdentityManager delegate) {
                return new NonVerifyingIdentityManagerDelegate(delegate);
              }
            }