You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by calder <ca...@gmail.com> on 2016/11/01 18:12:25 UTC

(TC7+) Why was the Realm argument removed for GenericPrincipal?

We have an application that runs on Tomcat6. For Tomcat7+, two of our
.java files require modification.   The modifications are mostly
concerned with the invocation of the
org.apache.catalina.realm.GenericPrincipal constructor - see the
MyappRealm class just below - this is the TC6 version. For the TC7+
version, we must remove the "this" (our Realm) argument.

Please see the MyappSpnegoFormAuth class just below - specifically the
invoke() method.
With Tomcat6, the super.invoke() method consumes ~2 milliseconds.
With Tomcat7+, the super.invoke() method consumes ~28 milliseconds.
super.invoke() is a call to org.apache.catalina.authenticator.AuthenticatorBase

We believe, somehow, that the "missing dependency" (admittedly, we
don't know what the catalina GenericPrincipal class does with the
passed-in Realm - ie, our Realm class) is causing the extended
millisecond times.

So, can anyone explain why the Realm arg was removed for the TC7+
GenericPrincipal class?
And just as important, is there a way to match the functionality?
Maybe we missed where our Realm class is passed to catalina code?


(if anyone is curious why we are concerned about the extra 26
milliseconds, it's because this code is used during "report
generation" and is called many times - example, with TC6, the report
runs in 25 seconds, with TC7+, it takes 80 seconds!).

import java.security.Principal;
import org.apache.catalina.realm.GenericPrincipal;
import org.apache.catalina.realm.RealmBase;

public class MyappRealm extends RealmBase {

  @Override
  protected Principal getPrincipal(String username) {
   // in Tomcat6, all GenericPrincipal ctors required a Realm (1st) argument
   // - Tomcat7+ no Realm arg
    return new GenericPrincipal( this, username, getPassword(username), roles);
  }

  public Principal authenticate(String alias, String uname, String creds,...) {
    // setup code
   return new GenericPrincipal( this, "myapp " + uname + "blah", creds, roles);
  }

  @Override
  public Principal authenticate(String uname, String creds) {
   // setup code
   return new GenericPrincipal( this, "myapp " +uname +"blah", creds, roles);
  }
}

import org.apache.catalina.Realm;
import org.apache.catalina.authenticator.FormAuthenticator;
import org.apache.catalina.realm.GenericPrincipal;

public class MyappSpnegoFormAuth extends FormAuthenticator {
  @Override
  public void invoke(Request request, Response response)
 throws IOException, ServletException {
 // setup code
    if( (session = request.getSessionInternal(false)) != null) {
      if( (prince = session.getPrincipal()) != null )
        request.setUserPrincipal(prince); // prince is a Principal
    }

    super.invoke(request, response);
  }

  public boolean realmAuth(HttpServletRequest request,
   String uname, String creds) {
    Realm realm = context.getRealm();
    Principal prince = realm.authenticate(uname, creds);
    if (prince != null) {
      this.register(req, res, prince, "FORM", uname, creds);
      return true;
    }
    return false;
  }

  @Override
  public boolean authenticate(Request request,
   Response response, LoginConfig cfg)  throws IOException {
    // setup code
     // various decisions and calls to super.authenticate() -
    // if all are false, this last super call is made
    return super.authenticate(request, response, cfg);
  }
}

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: (TC7+) Why was the Realm argument removed for GenericPrincipal?

Posted by Mark Thomas <ma...@apache.org>.
On 01/11/2016 18:12, calder wrote:
> We have an application that runs on Tomcat6. For Tomcat7+, two of our
> .java files require modification.   The modifications are mostly
> concerned with the invocation of the
> org.apache.catalina.realm.GenericPrincipal constructor - see the
> MyappRealm class just below - this is the TC6 version. For the TC7+
> version, we must remove the "this" (our Realm) argument.
> 
> Please see the MyappSpnegoFormAuth class just below - specifically the
> invoke() method.
> With Tomcat6, the super.invoke() method consumes ~2 milliseconds.
> With Tomcat7+, the super.invoke() method consumes ~28 milliseconds.
> super.invoke() is a call to org.apache.catalina.authenticator.AuthenticatorBase
> 
> We believe, somehow, that the "missing dependency" (admittedly, we
> don't know what the catalina GenericPrincipal class does with the
> passed-in Realm - ie, our Realm class) is causing the extended
> millisecond times.

That looks very much like jumping to a conclusion with insufficient
evidence to me.

If you want to know where the time is spent, you need to use a profiler.
I use YourKit because they give kindly Apache committers a free copy to
use for work on Apache projects.

> So, can anyone explain why the Realm arg was removed for the TC7+
> GenericPrincipal class?

The great thing about open source is that not only do you have access to
the source, you have access to the history as well.

In this case you want to start here:
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/realm/GenericPrincipal.java?view=log

A quick scan down that list leads you to this entry:
http://svn.apache.org/viewvc?view=revision&revision=797162

Which in turns points you to this bug report:
https://bz.apache.org/bugzilla/show_bug.cgi?id=40881

Read down to comment 11:
https://bz.apache.org/bugzilla/show_bug.cgi?id=40881#c11

And you find out the the Realm was essentially unused apart from when
logging a debug message.

All of which tells you that your theory about the Realm being related to
the performance change is unlikely to be correct.

Looking at a diff between 6.0.x and 7.0.x for AuthenticatorBase I can
see several changes that might be responsible for performance difference
but, again, a profiler is the tool to use to figure out what is actually
going on.

> And just as important, is there a way to match the functionality?
> Maybe we missed where our Realm class is passed to catalina code?

You are asking the wrong question here. Figure out where the time is
being spent then you can ask the right question which is how to reduce
that time.

Mark


> (if anyone is curious why we are concerned about the extra 26
> milliseconds, it's because this code is used during "report
> generation" and is called many times - example, with TC6, the report
> runs in 25 seconds, with TC7+, it takes 80 seconds!).
> 
> import java.security.Principal;
> import org.apache.catalina.realm.GenericPrincipal;
> import org.apache.catalina.realm.RealmBase;
> 
> public class MyappRealm extends RealmBase {
> 
>   @Override
>   protected Principal getPrincipal(String username) {
>    // in Tomcat6, all GenericPrincipal ctors required a Realm (1st) argument
>    // - Tomcat7+ no Realm arg
>     return new GenericPrincipal( this, username, getPassword(username), roles);
>   }
> 
>   public Principal authenticate(String alias, String uname, String creds,...) {
>     // setup code
>    return new GenericPrincipal( this, "myapp " + uname + "blah", creds, roles);
>   }
> 
>   @Override
>   public Principal authenticate(String uname, String creds) {
>    // setup code
>    return new GenericPrincipal( this, "myapp " +uname +"blah", creds, roles);
>   }
> }
> 
> import org.apache.catalina.Realm;
> import org.apache.catalina.authenticator.FormAuthenticator;
> import org.apache.catalina.realm.GenericPrincipal;
> 
> public class MyappSpnegoFormAuth extends FormAuthenticator {
>   @Override
>   public void invoke(Request request, Response response)
>  throws IOException, ServletException {
>  // setup code
>     if( (session = request.getSessionInternal(false)) != null) {
>       if( (prince = session.getPrincipal()) != null )
>         request.setUserPrincipal(prince); // prince is a Principal
>     }
> 
>     super.invoke(request, response);
>   }
> 
>   public boolean realmAuth(HttpServletRequest request,
>    String uname, String creds) {
>     Realm realm = context.getRealm();
>     Principal prince = realm.authenticate(uname, creds);
>     if (prince != null) {
>       this.register(req, res, prince, "FORM", uname, creds);
>       return true;
>     }
>     return false;
>   }
> 
>   @Override
>   public boolean authenticate(Request request,
>    Response response, LoginConfig cfg)  throws IOException {
>     // setup code
>      // various decisions and calls to super.authenticate() -
>     // if all are false, this last super call is made
>     return super.authenticate(request, response, cfg);
>   }
> }
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org