You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Matthew Kerle <ma...@sra.com.au> on 2007/08/15 08:38:37 UTC

tomcat memory realms & tomcat-users.xml

Hi all

I'm developing a web service with xFire 1.2.3 / tomcat 5.5.23 / Java 
1.6.0_01, and we need to authenticate access by client applications 
coming in over SOAP. We're looking at using the tomcat-users.xml file to 
store user/pwd/role data until the customers Single Sign-On service is 
ready (which will be when pigs fly, if it keeps going as it has).

The application will be deployed internally so we don't need any SSL or 
digest authentication, we're looking at simple HTTP BASIC or SOAP 
headers  for the client to pass through their auth details. The 
complication is that we want to allow default access as well as 
authenticated access, and authenticate against the tomcat-users file.

eg - un-authenticated clients can still access the web service url, but 
get a public role, and authenticated clients get a privileged role.

I'm thinking we might be able to do part of that with the following 
tomcat-users.xml config by having an empty user declaration:

<tomcat-users>c
  <role rolename="privileged"/>
  <user name=""  password="" roles="PUBLIC"  />
  <user name="priv_user1"  password="tomcat" roles="privileged"  />
</tomcat-users>

The question is how to authenticate against the tomcat-user database? 

I've read the tomcat docs on memory realm: 
http://tomcat.apache.org/tomcat-5.5-doc/realm-howto.html#MemoryRealm, 
and I want to expose the org.apache.catalina.UserDatabase class to the 
web service context via a <ResourceLink...>. I'd like to be able to 
authenticate users without having to add a <security-constraint> to my 
web.xml, so that unauthenticated clients can still connect.

Am I on the right track? Or is there a much easier way than what I'm 
trying to do...

thanks!

-- 
* Matthew Kerle
* * IT Consultant *
* Canberra, Australia*

Mobile: +61404 096 863
Email:     Matthew Kerle <ma...@gmail.com>
Web:      Matthew Kerle <http://threebrightlights.blogspot.com/> 
<http://threebrightlights.blogspot.com/>


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


Re: tomcat memory realms & tomcat-users.xml

Posted by Matthew Kerle <ma...@sra.com.au>.
Hi Charles, thanks for you help.

what if the memory-realm was configured in the context.xml for the 
application? then it should only be available to that particular 
app...?  I'm currently working on a mock to see if I can get this to 
work, if something as simple as defining the memoryrealm and the client 
adding http auth headers will be turned into a principal by tomcat 
available to my code, then it's all good. but things are never that 
simple...

Does anyone know what circumstances have to be true for tomcat to run 
the request against the memoryrealm and create a Principle? The access 
control will all be happening inside my code (well, in database access 
code more precisely), my dilemma is how to turn HTTP or SOAP headers 
into role names and where to store all that...

thanks for the security filter link, I'll check it out and see if it 
meets our needs.


* Matthew Kerle
* * IT Consultant *
* Canberra, Australia*

Mobile: +61404 096 863
Email:     Matthew Kerle <ma...@gmail.com>
Web:      Matthew Kerle <http://threebrightlights.blogspot.com/>


Caldarale, Charles R wrote:
>> From: Matthew Kerle [mailto:matthew.kerle@sra.com.au] 
>> Subject: tomcat memory realms & tomcat-users.xml
>>
>> I've read the tomcat docs on memory realm: 
>> http://tomcat.apache.org/tomcat-5.5-doc/realm-howto.html#MemoryRealm, 
>> and I want to expose the org.apache.catalina.UserDatabase 
>> class to the web service context via a <ResourceLink...>.
>>     
>
> You probably don't want to do that (even if it's possible, which I
> doubt), since all code in the webapps would then have access to the
> credentials.
>
>   
>> I'd like to be able to authenticate users without having 
>> to add a <security-constraint> to my web.xml, so that
>> unauthenticated clients can still connect.
>>     
>
> URL patterns in the <security-constraint> allow you to control which
> portions of the webapp are accessible to unauthenticated users.  If you
> want something with finer granularity, a filter is probably appropriate.
> Take a look at:
>     http://securityfilter.sourceforge.net/
> for a popular one.
>
>  - Chuck
>
>
> THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY
> MATERIAL and is thus for use only by the intended recipient. If you
> received this in error, please contact the sender and delete the e-mail
> and its attachments from all computers.
>
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@tomcat.apache.org
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>
>   


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


RE: tomcat memory realms & tomcat-users.xml

Posted by "Caldarale, Charles R" <Ch...@unisys.com>.
> From: Matthew Kerle [mailto:matthew.kerle@sra.com.au] 
> Subject: tomcat memory realms & tomcat-users.xml
> 
> I've read the tomcat docs on memory realm: 
> http://tomcat.apache.org/tomcat-5.5-doc/realm-howto.html#MemoryRealm, 
> and I want to expose the org.apache.catalina.UserDatabase 
> class to the web service context via a <ResourceLink...>.

You probably don't want to do that (even if it's possible, which I
doubt), since all code in the webapps would then have access to the
credentials.

> I'd like to be able to authenticate users without having 
> to add a <security-constraint> to my web.xml, so that
> unauthenticated clients can still connect.

URL patterns in the <security-constraint> allow you to control which
portions of the webapp are accessible to unauthenticated users.  If you
want something with finer granularity, a filter is probably appropriate.
Take a look at:
    http://securityfilter.sourceforge.net/
for a popular one.

 - Chuck


THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY
MATERIAL and is thus for use only by the intended recipient. If you
received this in error, please contact the sender and delete the e-mail
and its attachments from all computers.

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


Re: ClassCastException trying to cast MemoryUserDatabase to UserDatabase

Posted by Matthew Kerle <ma...@sra.com.au>.
Hi Chris

I naively tried relocating the catalina.jar to /common/lib, and got the 
below error. Peter has a good comment to this problem in his reply, so 
I'll continue the thread in response to his mail.

many thanks!

cmd /c C:\servers\apache-tomcat-5.5.23\bin\catalina.bat run
Using CATALINA_BASE:   C:\Documents and 
Settings\mkerle\.IntelliJIdea60\system\tomcat_Unnamed_cb722476
Using CATALINA_HOME:   C:\servers\apache-tomcat-5.5.23
Using CATALINA_TMPDIR: C:\servers\apache-tomcat-5.5.23\temp
Using JRE_HOME:        C:\Program Files\Java\jdk1.6.0
Connected to the target VM, address: '127.0.0.1:4958', transport: 'socket'
java.lang.NoClassDefFoundError: org/apache/tomcat/util/log/SystemLogHandler
    at java.lang.Class.getDeclaredConstructors0(Native Method)
    at java.lang.Class.privateGetDeclaredConstructors(Class.java:2389)
    at java.lang.Class.getConstructor0(Class.java:2699)
    at java.lang.Class.newInstance0(Class.java:326)
    at java.lang.Class.newInstance(Class.java:308)
    at org.apache.catalina.startup.Bootstrap.init(Bootstrap.java:225)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:410)
Disconnected from the target VM, address: '127.0.0.1:4958', transport: 
'socket'
Disconnected from server


Christopher Schultz wrote:
> Matt,
>   
> So, the class names are the same, but not the classes. This indicates
> that you have the same class loaded using two different ClassLoaders. Do
> you have a JAR file from the Tomcat distro sitting in your webapp's
> WEB-INF/lib directory?
>
> If so, you'll need to figure out how to deploy the JAR in one place but
> use it everywhere ($CATALINA_HOME/common/lib for TC 5.5 and, I think,
> just $CATALINA_HOME/lib for TC 6.0).
>
> - -chris
>
>   

-- 
Matthew Kerle
IT Consultant
Canberra, Australia

Mobile: +61404 096 863
Email : mattkerle@gmail.com
Web : http://threebrightlights.blogspot.com/


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


Re: ClassCastException trying to cast MemoryUserDatabase to UserDatabase

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Matt,

Matthew Kerle wrote:
> this is weird, check this out:
> 
> //code (tomcat 5.5.23)
> java.security.Principal p = request.getUserPrincipal();
> System.out.println(p.getClass().getName().equals(MemoryUser.class.getName()));
> // prints "true"
> System.out.println(p.getClass().equals(MemoryUser.class)); //prints "false"

So, the class names are the same, but not the classes. This indicates
that you have the same class loaded using two different ClassLoaders. Do
you have a JAR file from the Tomcat distro sitting in your webapp's
WEB-INF/lib directory?

If so, you'll need to figure out how to deploy the JAR in one place but
use it everywhere ($CATALINA_HOME/common/lib for TC 5.5 and, I think,
just $CATALINA_HOME/lib for TC 6.0).

- -chris

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGxFOX9CaO5/Lv0PARAsBQAJ9vXQKyDl2T6FXHz9Ijw241juk1OQCgvf4+
UzPy8kYFxyvPhBiY7DSh04k=
=EM9K
-----END PGP SIGNATURE-----

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


Re: ClassCastException trying to cast MemoryUserDatabase to UserDatabase

Posted by Matthew Kerle <ma...@sra.com.au>.
I agree, the Principal interface is verily hobbled and almost useless 
(Go Sun!). The catalina implementations are much more user-friendly, but 
unfortunately difficult to access.

I can't really justify making the tomcat install non-standard (also 
probably not possible as it's owned by the client, not me) just to get 
access to this class. I'll go with another hack, in that although I 
can't refer directly to MemoryUser, I can still call it's toString() 
method, which prints out the <user> tag in it's entirety, which I can 
then munge for role names.

I can't believe something this simple is so hard, far out.

thanks so much for your help Peter, I would've been totally stuck 
without it!

Peter Crowther wrote:
>> From: Matthew Kerle [mailto:matthew.kerle@sra.com.au] 
>> the MemoryUser class is in catalina.jar, which is in the server/lib 
>> folder. would I be right in saying that web application code 
>> is barred 
>> from loading any classes from the server/lib directory?
>>     
>
> (light bulb comes on)
>
> Ah yes, I remember this now from some ancient history on another
> project.  It's a real pain, principally because the Principal interface
> is IMO too limited.  We ended up with the horrible, horrible hack of
> pulling the class out of catalina.jar, putting it in its own jar, and
> deploying that in common/lib.  This, of course, means you no longer have
> a default Tomcat install... but we couldn't find another way round the
> problem.
>
> 		- Peter
>   

-- 
Matthew Kerle
IT Consultant
Canberra, Australia

Mobile: +61404 096 863
Email : mattkerle@gmail.com
Web : http://threebrightlights.blogspot.com/


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


Re: ClassCastException trying to cast MemoryUserDatabase to UserDatabase

Posted by Matthew Kerle <ma...@sra.com.au>.
http://tomcat.apache.org/tomcat-5.5-doc/class-loader-howto.html

this is why I can't reference any classes loaded from server/lib in my 
webapp, the server/lib classes are loaded by the web application 
classloader's "uncle", so to speak, the sibling of it's parent. so it 
makes sense that no web application has access to the server/lib jars. 
doh...!

Peter Crowther wrote:
>> From: Matthew Kerle [mailto:matthew.kerle@sra.com.au] 
>> the MemoryUser class is in catalina.jar, which is in the server/lib 
>> folder. would I be right in saying that web application code 
>> is barred 
>> from loading any classes from the server/lib directory?
>>     
>
> (light bulb comes on)
>
> Ah yes, I remember this now from some ancient history on another
> project.  It's a real pain, principally because the Principal interface
> is IMO too limited.  We ended up with the horrible, horrible hack of
> pulling the class out of catalina.jar, putting it in its own jar, and
> deploying that in common/lib.  This, of course, means you no longer have
> a default Tomcat install... but we couldn't find another way round the
> problem.
>
> 		- Peter

-- 
Matthew Kerle
IT Consultant
Canberra, Australia

Mobile: +61404 096 863
Email : mattkerle@gmail.com
Web : http://threebrightlights.blogspot.com/


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


Re: ClassCastException trying to cast MemoryUserDatabase to UserDatabase

Posted by Matthew Kerle <ma...@sra.com.au>.
just downloaded security filter and had a look, it looks very cool. If I 
had more robust requirements for my authentication (and more time!) I 
would probably use it.

At the moment though I've got a workable work-around in using the 
toString() method, so I'll just use that instead.

thanks Chris!

Christopher Schultz wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Matthew,
> Why not just use the built-in authentication and authorization mechanism
> instead of trying to use Tomcat's built-in classes to roll your own?
>
> A more flexible option is to use securityfilter
> (http://securityfilter.sourceforge.net) to handle everything.
> securityfilter allows you to use Tomcat realms by dropping catalina.jar
> into your webapp's library directory. Since securityfilter runs entirely
> in your webapp, there are no classloading problems (even though Tomcat's
> internal classes are used, they are loaded by the webapp's ClassLoader,
> and are insulated from Tomcat, so they're safe).
>
> - -chris
-- 
Matthew Kerle
IT Consultant
Canberra, Australia

Mobile: +61404 096 863
Email : mattkerle@gmail.com
Web : http://threebrightlights.blogspot.com/


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


Re: ClassCastException trying to cast MemoryUserDatabase to UserDatabase

Posted by Mario Ivankovits <ma...@ops.co.at>.
Hi!
> Mario, you are a hero. do women come and worship you in the street?
Haha! Oh boy ... you don't want to know ...

Glad it helped you! :-)

Ciao,
Mario


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


Re: ClassCastException trying to cast MemoryUserDatabase to UserDatabase

Posted by Matthew Kerle <ma...@sra.com.au>.
Mario, you are a hero. do women come and worship you in the street? they 
should! Using reflection to break into an object of a foreign class is 
just...genius! this is the sort of thing that Ruby programmers do all 
the time, but is very hard to do in Java...

my final code (in the context of a ServiceImpl class for an xFire 
webservice, exception-handling & error-checking elided)

        //get Role from security Principal, which we 'happen to know', is
        // an instance of catalina MemoryUser.
        HttpServletRequest request = XFireServletController.getRequest();
        Principal principal = request.getUserPrincipal();
        String rolename = null;
        if(principal != null){
            
if(principal.getClass().getName().equalsIgnoreCase("org.apache.catalina.users.MemoryUser")){
                Iterator it =(Iterator) 
principal.getClass().getMethod("getRoles").invoke(principal);
                Object role = it.next();
                String role1 = 
(String)role.getClass().getMethod("getRolename").invoke(role);
                int i = 0;
            }else{
                String xml = principal.toString();
                rolename = xml.split("\"")[3]; // [1]=username, 
[2]=pass, [3]=roles
            }
        }else{
            rolename = "public";
        }


Mario Ivankovits wrote:
> Hi!
>   
>> A more flexible option is to use securityfilter
>> (http://securityfilter.sourceforge.net) to handle everything.
>>   
>>     
> If you are already using spring have a look at ACEGI.
> It is not really easy to install, but allows you to e.g. have different
> login methods within the same webapp.
>
> Regarding the principal. Remember, you can always use reflection to
> break into an object (given you use no securitymanager or a liberal
> configured one).
>
> For example, I used for a while:
>
>         try
>         {
>             Method hasRoleMeth =
> principal.getClass().getMethod("hasRole", String.class);
>             return (Boolean) hasRoleMeth.invoke(principal, role);
>         }
>         catch (NoSuchMethodException e)
>         {
>             log.error(e.getLocalizedMessage(), e);
>         }
>         catch (IllegalAccessException e)
>         {
>             log.error(e.getLocalizedMessage(), e);
>         }
>         catch (InvocationTargetException e)
>         {
>             log.error(e.getLocalizedMessage(), e);
>         }
>
>
> Ciao,
> Mario
>
>   

-- 
Matthew Kerle
IT Consultant
Canberra, Australia

Mobile: +61404 096 863
Email : mattkerle@gmail.com
Web : http://threebrightlights.blogspot.com/


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


Re: ClassCastException trying to cast MemoryUserDatabase to UserDatabase

Posted by Mario Ivankovits <ma...@ops.co.at>.
Hi!
> A more flexible option is to use securityfilter
> (http://securityfilter.sourceforge.net) to handle everything.
>   
If you are already using spring have a look at ACEGI.
It is not really easy to install, but allows you to e.g. have different
login methods within the same webapp.

Regarding the principal. Remember, you can always use reflection to
break into an object (given you use no securitymanager or a liberal
configured one).

For example, I used for a while:

        try
        {
            Method hasRoleMeth =
principal.getClass().getMethod("hasRole", String.class);
            return (Boolean) hasRoleMeth.invoke(principal, role);
        }
        catch (NoSuchMethodException e)
        {
            log.error(e.getLocalizedMessage(), e);
        }
        catch (IllegalAccessException e)
        {
            log.error(e.getLocalizedMessage(), e);
        }
        catch (InvocationTargetException e)
        {
            log.error(e.getLocalizedMessage(), e);
        }


Ciao,
Mario


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


Re: ClassCastException trying to cast MemoryUserDatabase to UserDatabase

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Matthew,

Matthew Kerle wrote:
> no, see my previous reply, tomcat fails to bootstrap if catalina.jar is
> not in server/lib...

That's too bad.

Why not just use the built-in authentication and authorization mechanism
instead of trying to use Tomcat's built-in classes to roll your own?

A more flexible option is to use securityfilter
(http://securityfilter.sourceforge.net) to handle everything.
securityfilter allows you to use Tomcat realms by dropping catalina.jar
into your webapp's library directory. Since securityfilter runs entirely
in your webapp, there are no classloading problems (even though Tomcat's
internal classes are used, they are loaded by the webapp's ClassLoader,
and are insulated from Tomcat, so they're safe).

- -chris

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGxFgg9CaO5/Lv0PARAr+tAJ9qFSDak0g2RVaM4ZP0col6JQUASwCgt1g/
gze5O3bGX+AwWdfa5Y8meLI=
=d06z
-----END PGP SIGNATURE-----

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


Re: ClassCastException trying to cast MemoryUserDatabase to UserDatabase

Posted by Matthew Kerle <ma...@sra.com.au>.
no, see my previous reply, tomcat fails to bootstrap if catalina.jar is 
not in server/lib...

Christopher Schultz wrote:
>
> Peter,
> Shouldn't it be acceptable to simply move catalina.jar from server/lib
> to common/lib?
>
> Sure, you'll still have a non-standard install, but it's easier to
> script a setup like that than pulling specific classes out of the distro
> (which may change from version to version).

-- 
Matthew Kerle
IT Consultant
Canberra, Australia

Mobile: +61404 096 863
Email : mattkerle@gmail.com
Web : http://threebrightlights.blogspot.com/


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


RE: ClassCastException trying to cast MemoryUserDatabase to UserDatabase

Posted by Peter Crowther <Pe...@melandra.com>.
> From: Christopher Schultz [mailto:chris@christopherschultz.net] 
> Shouldn't it be acceptable to simply move catalina.jar from server/lib
> to common/lib?
> 
> Sure, you'll still have a non-standard install, but it's easier to
> script a setup like that than pulling specific classes out of 
> the distro (which may change from version to version).

We wanted to add as few classes as possible to common - but, yes, that'd
be a more maintainable solution.  By that time we were maintaining quite
a heavily customised Tomcat anyway, so one more pain point was minor.

		- Peter

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


Re: ClassCastException trying to cast MemoryUserDatabase to UserDatabase

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Peter,

Peter Crowther wrote:
> We ended up with the horrible, horrible hack of
> pulling the class out of catalina.jar, putting it in its own jar, and
> deploying that in common/lib.

Shouldn't it be acceptable to simply move catalina.jar from server/lib
to common/lib?

Sure, you'll still have a non-standard install, but it's easier to
script a setup like that than pulling specific classes out of the distro
(which may change from version to version).

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGxFT79CaO5/Lv0PARAnV4AKCFlrCGXZRW6kAsuAKVALotClJZVQCgt35C
cCXiuO3XNkXko3SshrF9tpg=
=wR3z
-----END PGP SIGNATURE-----

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


RE: ClassCastException trying to cast MemoryUserDatabase to UserDatabase

Posted by Peter Crowther <Pe...@melandra.com>.
> From: Matthew Kerle [mailto:matthew.kerle@sra.com.au] 
> the MemoryUser class is in catalina.jar, which is in the server/lib 
> folder. would I be right in saying that web application code 
> is barred 
> from loading any classes from the server/lib directory?

(light bulb comes on)

Ah yes, I remember this now from some ancient history on another
project.  It's a real pain, principally because the Principal interface
is IMO too limited.  We ended up with the horrible, horrible hack of
pulling the class out of catalina.jar, putting it in its own jar, and
deploying that in common/lib.  This, of course, means you no longer have
a default Tomcat install... but we couldn't find another way round the
problem.

		- Peter

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


Re: ClassCastException trying to cast MemoryUserDatabase to UserDatabase

Posted by Matthew Kerle <ma...@sra.com.au>.
you're exactly right again. I just checked my project settings, I had to 
add catalina.jar to the project libraries to get the class to compile, 
but I'd forgotten to prevent it from being deployed, so there was a copy 
of catalina.jar in my /WEB-INF/lib, doh!

So I configured it to not be deployed, and deleted the existing jar, so 
now I get a new problem, a NoClassDefFoundError on the MemoryUser class, 
which is referenced by my code. So now my class doesn't even load!! I 
have a feeling someone's gone to a fair bit of trouble to make sure I 
can't load this class!

the MemoryUser class is in catalina.jar, which is in the server/lib 
folder. would I be right in saying that web application code is barred 
from loading any classes from the server/lib directory?

any ideas Peter?

org.codehaus.xfire.XFireRuntimeException: Error invoking 
'myapp.service.webservice.ImageService.enumerateLOV(java.lang.String)'. 
Nested exception is java.lang.reflect.InvocationTargetException: null
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at 
org.codehaus.xfire.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:59)
    ... elided
    at 
org.codehaus.xfire.transport.http.XFireServlet.doPost(XFireServlet.java:116)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    at 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
    ... elided
    at 
org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1286)
    at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.NoClassDefFoundError: 
org/apache/catalina/users/MemoryUser
    at 
myapp.service.webservice.ImageServiceImpl.enumerateLOV(ImageServiceImpl.java:67)
    ... 31 more

Peter Crowther wrote:
> Right.  So request.getUserPrincipal() returns a class that's loaded by
> one of Tomcat's classloaders.  You need to make sure that when you
> reference MemoryUser, it's loaded by the same classloader.
>
> Thinking aloud here, so apologies to the more experienced folks in the
> community who will have better ideas... Is MemoryUser.class in any of
> the jars in your webapp?  I'm not entirely sure why there's a second
> copy of it, loaded by the webapp's classloader, in the system.  I'd
> expect the webapp's classloader to be unable to find the class as your
> webapp loads and punt the request for the class up the classloader
> chain, returning the standard classloader's class.  But I may be
> misunderstanding Tomcat's classloaders.
>
> 		- Peter

-- 
Matthew Kerle
IT Consultant
Canberra, Australia

Mobile: +61404 096 863
Email : mattkerle@gmail.com
Web : http://threebrightlights.blogspot.com/


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


RE: ClassCastException trying to cast MemoryUserDatabase to UserDatabase

Posted by Peter Crowther <Pe...@melandra.com>.
> From: Matthew Kerle [mailto:matthew.kerle@sra.com.au] 
> Class c1 = request.getUserPrincipal().getClass(); //get the 
> class of the 
> Principal that tomcat created , which is a MemoryUser instance
> Class c2 = MemoryUser.class; // get the class loaded by the 
> current loader
> System.out.println(c1.getClassLoader().getClass.getName()); //prints 
> "org.apache.catalina.loader.StandardClassLoader"
> System.out.println(c2.getClassLoader().getClass.getName()); //prints 
> "org.apache.catalina.loader.WebappClassLoader"
> 
> Great, so now I've got two different classloaders. Do you know if 
> there's any way I can cast the Principal to a Memoryuser 
> object and use 
> it? do I have to load the MemoryUser class in the current classloader?

Right.  So request.getUserPrincipal() returns a class that's loaded by
one of Tomcat's classloaders.  You need to make sure that when you
reference MemoryUser, it's loaded by the same classloader.

Thinking aloud here, so apologies to the more experienced folks in the
community who will have better ideas... Is MemoryUser.class in any of
the jars in your webapp?  I'm not entirely sure why there's a second
copy of it, loaded by the webapp's classloader, in the system.  I'd
expect the webapp's classloader to be unable to find the class as your
webapp loads and punt the request for the class up the classloader
chain, returning the standard classloader's class.  But I may be
misunderstanding Tomcat's classloaders.

		- Peter

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


Re: ClassCastException trying to cast MemoryUserDatabase to UserDatabase

Posted by Matthew Kerle <ma...@sra.com.au>.
Peter,
you're exactly right.

***code***
Class c1 = request.getUserPrincipal().getClass(); //get the class of the 
Principal that tomcat created , which is a MemoryUser instance
Class c2 = MemoryUser.class; // get the class loaded by the current loader
System.out.println(c1.getClassLoader().getClass.getName()); //prints 
"org.apache.catalina.loader.StandardClassLoader"
System.out.println(c2.getClassLoader().getClass.getName()); //prints 
"org.apache.catalina.loader.WebappClassLoader"

Great, so now I've got two different classloaders. Do you know if 
there's any way I can cast the Principal to a Memoryuser object and use 
it? do I have to load the MemoryUser class in the current classloader?

full kudos for figuring out the problem exactly, I never would have 
thought of that!

ps - This would be entertaining, if only I was the one who got to watch 
someone else wade through this!

Peter Crowther wrote:
>> From: Matthew Kerle [mailto:matthew.kerle@sra.com.au] 
>> So what this is saying is that the *names* of the classes are 
>> the same, 
>> but the actual classes are different. this is crazy...
>>     
>
> I suspect the two classes are being loaded by different classloaders - a
> common and entertaining* problem in Tomcat and other servlet containers.
> You can find out by asking each for its classloader and comparing.
>
> 		- Peter
>
> * Depending on whether you're watching someone else try to solve the
> problem, or having to wade through it yourself.  Best of luck!
>
>
>   

-- 
Matthew Kerle
IT Consultant
Canberra, Australia

Mobile: +61404 096 863
Email : mattkerle@gmail.com
Web : http://threebrightlights.blogspot.com/


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


RE: ClassCastException trying to cast MemoryUserDatabase to UserDatabase

Posted by Peter Crowther <Pe...@melandra.com>.
> From: Matthew Kerle [mailto:matthew.kerle@sra.com.au] 
> So what this is saying is that the *names* of the classes are 
> the same, 
> but the actual classes are different. this is crazy...

I suspect the two classes are being loaded by different classloaders - a
common and entertaining* problem in Tomcat and other servlet containers.
You can find out by asking each for its classloader and comparing.

		- Peter

* Depending on whether you're watching someone else try to solve the
problem, or having to wade through it yourself.  Best of luck!

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


Re: ClassCastException trying to cast MemoryUserDatabase to UserDatabase

Posted by Matthew Kerle <ma...@sra.com.au>.
this is weird, check this out:

//code (tomcat 5.5.23)
java.security.Principal p = request.getUserPrincipal();
System.out.println(p.getClass().getName().equals(MemoryUser.class.getName())); 
// prints "true"
System.out.println(p.getClass().equals(MemoryUser.class)); //prints "false"

So what this is saying is that the *names* of the classes are the same, 
but the actual classes are different. this is crazy...

Good news is that p.toString() prints out that users details in the form 
<user username="user1" password="pass" roles="public"/>, so I can hack 
the role names out of that. but that's a very dirty hack and I'm amazed 
that this is so hard...

Does anyone have any input on why this might be so, and/or a better 
solution to convert the request principal to something I can get 
rolenames out of?

thanks!

Matthew Kerle wrote:
> //code
> Object o = ic.lookup("java:comp/env/users");
> System.out.println(o.getClass().getName()); // prints : 
> "org.apache.catalina.users.MemoryUserDatabase"
>
> doing instanceof tests on the returned object for MemoryUserDatabase & 
> UserDatabase all fail, even though in debug that's clearly what it 
> identifies as.
>
> could this be a security manager thing? I notice that in the tomcat 
> manager deployment descriptor it has privileged="true" in the Context 
> tag. Are only privileged applications allowed access to the 
> UserDatabase? (this would make sense as you could enumerate all users 
> & passwords...)
>

-- 
Matthew Kerle
IT Consultant
Canberra, Australia

Mobile: +61404 096 863
Email : mattkerle@gmail.com
Web : http://threebrightlights.blogspot.com/


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


Re: ClassCastException trying to cast MemoryUserDatabase to UserDatabase

Posted by Matthew Kerle <ma...@sra.com.au>.
//code
Object o = ic.lookup("java:comp/env/users");
System.out.println(o.getClass().getName()); // prints : 
"org.apache.catalina.users.MemoryUserDatabase"

doing instanceof tests on the returned object for MemoryUserDatabase & 
UserDatabase all fail, even though in debug that's clearly what it 
identifies as.

could this be a security manager thing? I notice that in the tomcat 
manager deployment descriptor it has privileged="true" in the Context 
tag. Are only privileged applications allowed access to the 
UserDatabase? (this would make sense as you could enumerate all users & 
passwords...)

Gregor Schneider wrote:
> InitialContext.lookup() gives you a simple object:
>
> so change your code to
>
> Context ic = new InitialContext();
> Object o = ic.lookup("java:comp/env/users");
>
> set a breakpoint and see, what type of object you're getting back.
>
> hth
>
> gregor
>   

-- 
Matthew Kerle
IT Consultant
Canberra, Australia

Mobile: +61404 096 863
Email : mattkerle@gmail.com
Web : http://threebrightlights.blogspot.com/


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


Re: ClassCastException trying to cast MemoryUserDatabase to UserDatabase

Posted by Gregor Schneider <rc...@googlemail.com>.
InitialContext.lookup() gives you a simple object:

so change your code to

Context ic = new InitialContext();
Object o = ic.lookup("java:comp/env/users");

set a breakpoint and see, what type of object you're getting back.

hth

gregor
-- 
what's puzzlin' you, is the nature of my game
gpgp-fp: 79A84FA526807026795E4209D3B3FE028B3170B2
gpgp-key available @ http://pgpkeys.pca.dfn.de:11371

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


Re: ClassCastException trying to cast MemoryUserDatabase to UserDatabase

Posted by Matthew Kerle <ma...@sra.com.au>.
oops, also here is my resource definition from my web.xml:

  <!-- Define reference to the user database for looking up roles -->
  <resource-env-ref>
    <description>
      Link to the UserDatabase instance from which we request lists of
      defined role names.  Typically, this will be connected to the global
      user database with a ResourceLink element in server.xml or the context
      configuration file for the Manager web application.
    </description>
    <resource-env-ref-name>users</resource-env-ref-name>
    <resource-env-ref-type>
      org.apache.catalina.UserDatabase
    </resource-env-ref-type>
  </resource-env-ref>

Matthew Kerle wrote:
> (see below for message context)
>
> Ok, I've decided on using Http Basic authentication for my web 
> service, and successfully configured tomcat to authenticate against 
> the tomcat-users.xml file to the point where I can access a valid 
> principal. But now I've got another problem.. :-)
>
> I tried accessing the userDatabase which represents the memoryrealm, 
> and got the below exception. I don't understand this as according to 
> the API doc MemoryUserDatabase is an implementation of UserDatabase, 
> and this is confirmed by looking at the source code for 
> MemoryUserDatabase, which *does* implement that interface!
>
> I'm stumped, does anyone know why this might be happening? Or am I 
> doing something the wrong way...
>
>
> //code to get tomcat UserDatabase, copied from 
> ManagerServlet.roles(PrintWriter) from tomcat manager application.
> Context ic = new InitialContext();
> UserDatabase userdb = (UserDatabase )ic.lookup("java:comp/env/users"); 
> // <- this line causes ClassCastException
>
> SEVERE: Fault occurred!
> java.lang.ClassCastException: 
> org.apache.catalina.users.MemoryUserDatabase cannot be cast to 
> org.apache.catalina.UserDatabase
>    at 
> myapp.service.webservice.ImageServiceImpl.EnumerateLOV(ImageServiceImpl.java:88) 
>
>    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>    at 
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
>
>    at 
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
>
>    at java.lang.reflect.Method.invoke(Method.java:597)
>    // stack trace elided...
>    at 
> org.codehaus.xfire.transport.http.XFireServlet.doPost(XFireServlet.java:116) 
>
>    at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
>    at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
>    at 
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269) 
>
>    // stack trace elided...
>    at 
> org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1286)
>    at java.lang.Thread.run(Thread.java:619)
>
> //my context.xml
> <Context path="/myapp">
>    <!-- get access to the tomcat-users.xml database -->
>      <ResourceLink name="users" global="UserDatabase"   
> type="org.apache.catalina.UserDatabase"/>
> </Context>
>
>
> Matthew Kerle wrote:
>> Hi all
>>
>> I'm developing a web service with xFire 1.2.3 / tomcat 5.5.23 / Java 
>> 1.6.0_01, and we need to authenticate access by client applications 
>> coming in over SOAP. We're looking at using the tomcat-users.xml file 
>> to store user/pwd/role data until the customers Single Sign-On 
>> service is ready (which will be when pigs fly, if it keeps going as 
>> it has).
>>
>> The application will be deployed internally so we don't need any SSL 
>> or digest authentication, we're looking at simple HTTP BASIC or SOAP 
>> headers  for the client to pass through their auth details. The 
>> complication is that we want to allow default access as well as 
>> authenticated access, and authenticate against the tomcat-users file.
>>
>> eg - un-authenticated clients can still access the web service url, 
>> but get a public role, and authenticated clients get a privileged role.
>>
>> I'm thinking we might be able to do part of that with the following 
>> tomcat-users.xml config by having an empty user declaration:
>>
>> <tomcat-users>c
>>  <role rolename="privileged"/>
>>  <user name=""  password="" roles="PUBLIC"  />
>>  <user name="priv_user1"  password="tomcat" roles="privileged"  />
>> </tomcat-users>
>>
>> The question is how to authenticate against the tomcat-user database?
>> I've read the tomcat docs on memory realm: 
>> http://tomcat.apache.org/tomcat-5.5-doc/realm-howto.html#MemoryRealm, 
>> and I want to expose the org.apache.catalina.UserDatabase class to 
>> the web service context via a <ResourceLink...>. I'd like to be able 
>> to authenticate users without having to add a <security-constraint> 
>> to my web.xml, so that unauthenticated clients can still connect.
>>
>> Am I on the right track? Or is there a much easier way than what I'm 
>> trying to do...
>>
>> thanks!
>>
>

-- 
Matthew Kerle
IT Consultant
Canberra, Australia

Mobile: +61404 096 863
Email : mattkerle@gmail.com
Web : http://threebrightlights.blogspot.com/


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


ClassCastException trying to cast MemoryUserDatabase to UserDatabase

Posted by Matthew Kerle <ma...@sra.com.au>.
(see below for message context)

Ok, I've decided on using Http Basic authentication for my web service, 
and successfully configured tomcat to authenticate against the 
tomcat-users.xml file to the point where I can access a valid principal. 
But now I've got another problem.. :-)

I tried accessing the userDatabase which represents the memoryrealm, and 
got the below exception. I don't understand this as according to the API 
doc MemoryUserDatabase is an implementation of UserDatabase, and this is 
confirmed by looking at the source code for MemoryUserDatabase, which 
*does* implement that interface!

I'm stumped, does anyone know why this might be happening? Or am I doing 
something the wrong way...


//code to get tomcat UserDatabase, copied from 
ManagerServlet.roles(PrintWriter) from tomcat manager application.
Context ic = new InitialContext();
UserDatabase userdb = (UserDatabase )ic.lookup("java:comp/env/users"); 
// <- this line causes ClassCastException

SEVERE: Fault occurred!
java.lang.ClassCastException: 
org.apache.catalina.users.MemoryUserDatabase cannot be cast to 
org.apache.catalina.UserDatabase
    at 
myapp.service.webservice.ImageServiceImpl.EnumerateLOV(ImageServiceImpl.java:88)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    // stack trace elided...
    at 
org.codehaus.xfire.transport.http.XFireServlet.doPost(XFireServlet.java:116)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    at 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
    // stack trace elided...
    at 
org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1286)
    at java.lang.Thread.run(Thread.java:619)

//my context.xml
<Context path="/myapp">
    <!-- get access to the tomcat-users.xml database -->
      <ResourceLink name="users" global="UserDatabase"   
type="org.apache.catalina.UserDatabase"/>
</Context>


Matthew Kerle wrote:
> Hi all
>
> I'm developing a web service with xFire 1.2.3 / tomcat 5.5.23 / Java 
> 1.6.0_01, and we need to authenticate access by client applications 
> coming in over SOAP. We're looking at using the tomcat-users.xml file 
> to store user/pwd/role data until the customers Single Sign-On service 
> is ready (which will be when pigs fly, if it keeps going as it has).
>
> The application will be deployed internally so we don't need any SSL 
> or digest authentication, we're looking at simple HTTP BASIC or SOAP 
> headers  for the client to pass through their auth details. The 
> complication is that we want to allow default access as well as 
> authenticated access, and authenticate against the tomcat-users file.
>
> eg - un-authenticated clients can still access the web service url, 
> but get a public role, and authenticated clients get a privileged role.
>
> I'm thinking we might be able to do part of that with the following 
> tomcat-users.xml config by having an empty user declaration:
>
> <tomcat-users>c
>  <role rolename="privileged"/>
>  <user name=""  password="" roles="PUBLIC"  />
>  <user name="priv_user1"  password="tomcat" roles="privileged"  />
> </tomcat-users>
>
> The question is how to authenticate against the tomcat-user database?
> I've read the tomcat docs on memory realm: 
> http://tomcat.apache.org/tomcat-5.5-doc/realm-howto.html#MemoryRealm, 
> and I want to expose the org.apache.catalina.UserDatabase class to the 
> web service context via a <ResourceLink...>. I'd like to be able to 
> authenticate users without having to add a <security-constraint> to my 
> web.xml, so that unauthenticated clients can still connect.
>
> Am I on the right track? Or is there a much easier way than what I'm 
> trying to do...
>
> thanks!
>

-- 
Matthew Kerle
IT Consultant
Canberra, Australia

Mobile: +61404 096 863
Email : mattkerle@gmail.com
Web : http://threebrightlights.blogspot.com/


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