Re: problem using default Realm in new unit tests
On 10/01/12 13:21, Brian Burch wrote: Konstantin, Thank you for your prompt and helpful response... at least I know I haven't overlooked something simple. With your encouragement, I'm happy to keep fighting the alligators until I can get back to draining the swamp! I am working on this issue in my spare time while on holiday in Australia. I was testing a local fix yesterday which inserted the default MemoryRealm into the StandardEngine. I decided to go to bed and email my proposed change in the morning. While I was sleeping, Mark committed r1230777 (and r1230767), which is very similar to mine, but was more bold. I was nervous (through ignorance) about the consequences for the standalone and embedded cases. I have now reworked my new unit tests to work with Mark's change (they no longer need to explicitly trigger assignment of the default MemoryRealm), and they all run successfully. I will submit them soon. Sorry to keep this topic open, but I have some outstanding questions following Mark's change, so perhaps someone could spare the time to answer them for me? Tomcat.getEngine has not changed its overall behaviour: it creates the Engine when it doesn't already exist. However, it now also creates and assigns the default MemoryRealm to the new StandardEngine instance. I can see the StandardEngine constructor is also called in both the MBeanFactory and Embedded classes. MBeanFactory, at first glance, seems to set the Realm on request, but not define a default for the Engine. The Embedded constructors will either explicitly set a Realm, or leave it uninitialised. If this observation is correct, then there are real cases where the Engine can be created without a default realm, in which case StandardEngine will create a default JAASRealm as soon as the getRealm method is called. This JAASRealm MUST be properly configured in the jvm if an Exception is to be avoided. Is it still meaningful to let the StandardEngine establish a default JAASRealm in getRealm under these circumstances, or would it be more consistent to use a default MemoryRealm? Anyone who wants to use a JAASRealm would surely have to configure it, so isn't it is a bit lazy to rely on implicit assignment. Surely these users would (should) explicitly define the JAASRealm in Embedded or MBeanFactory? Perhaps the logic in StandardEngine.getRealm to catch these special cases and create a default JAASRealm is redundant? Thanks, Brian - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: problem using default Realm in new unit tests
Brian Burch br...@pingtoo.com wrote: On 10/01/12 13:21, Brian Burch wrote: Tomcat.getEngine has not changed its overall behaviour: it creates the Engine when it doesn't already exist. However, it now also creates and assigns the default MemoryRealm to the new StandardEngine instance. It isn't the MemoryRealm but a simplified version of it. I can see the StandardEngine constructor is also called in both the MBeanFactory and Embedded classes. MBeanFactory, at first glance, seems to set the Realm on request, but not define a default for the Engine. The Embedded constructors will either explicitly set a Realm, or leave it uninitialised. If this observation is correct, then there are real cases where the Engine can be created without a default realm, in which case StandardEngine will create a default JAASRealm as soon as the getRealm method is called. This JAASRealm MUST be properly configured in the jvm if an Exception is to be avoided. Is it still meaningful to let the StandardEngine establish a default JAASRealm in getRealm under these circumstances, or would it be more consistent to use a default MemoryRealm? Anyone who wants to use a JAASRealm would surely have to configure it, so isn't it is a bit lazy to rely on implicit assignment. Surely these users would (should) explicitly define the JAASRealm in Embedded or MBeanFactory? Perhaps the logic in StandardEngine.getRealm to catch these special cases and create a default JAASRealm is redundant? My preference is to create a new NullRealm (with a better name) that always fails authentication and is used in place of the JAAS realm as a default for the engine. Mark Thanks, Brian - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
Re: problem using default Realm in new unit tests
On 06/01/12 11:47, Konstantin Kolinko wrote: 2012/1/6 Brian Burchbr...@pingtoo.com: I am developing some new unit tests to validate SingleSignOn and Authenticator logic. I have used this existing test class as my template: org.apache.catalina.authenticator.TestDigestAuthenticator .. which extends org.apache.catalina.startup.TomcatBaseTest. I noticed that TestDigestAuthenticator sets up its own MapRealm and assigns it to its single Context. I thought this logic was unnecessary, and so my own initial test logic simply used the default RealmBase provided by the underlying Tomcat instance. I add my test user and role to that. It worked fine with my simple cases, however... To test SSO, I need to set up two Contexts under the same Realm. I see the following message in the output log: INFO: The start() method was called on component [Realm[Simple]] after start() had already been called. The second call will be ignored. I know it is an INFO message. I know the second start (and its associated stop) are ignored and therefore are harmless. However, I am reluctant to simply shrug and ignore it. My instincts tell me something isn't right. I have done quite a lot of investigating, but the underlying logic is very hard for me to follow. Here is what I am sure about: 1. The message is ONLY emitted in tests that create two Contexts and each have the same Realm assigned with setRealm. 2. The message is NOT emitted at the time the Contexts are created and defined (servlets, security constraints, etc). 3. The message IS emitted after the Tomcat.start method is called. 4. The message is emitted by one of the two threads which are started on behalf of my two contexts. The messages are issued by the start and stop methods in the abstract class org.apache.catalina.util.LifecycleBase. 5. org.apache.catalina.realm.RealmBase extends org.apache.catalina.util.LifecycleMBeanBase which extends LifecycleBase. My currently unanswered questions are: 1. Is this message normal? (I don't see it when I start multiple contexts under a real tomcat server, but perhaps the logging properties are different). 2. Why isn't the redundant startup of the Realm detected earlier and simply avoided (maybe the Threads are intended to race to be first with startup - but then I think the message should be debug level and not sound so scary). Please don't waste your time investigating this for me. I am only asking the question because I don't want too get side-tracked if one of you already knows the answers to my questions. I'd like to settle the matter quickly and get back to my original task! Thanks for listening, The message is expected. I would say that the configuration is wrong, or at least unusual. If you look at the default server.xml file you will note that the Realm element there belongs to Engine. That is why it is started once. I agree, and this is what the TomcatBaseTest expects. If you tickle tomcat with TomcatBaseTest.getTomcatInstance() and then with Tomcat.getDefaultRealm(), a new default RealBase (memory) instance is definitely created. When Contexts are created and their context.xml files are parsed, the Contexts always get distinct new Realm instances. Instead of assigning the same Realm instance to both Contexts you should assign it to an upper container (I have not looked at the API though). Or maybe you can have different Realm instances, but which connect to the same backing storage? When the StandardEngine (extending ContainerBase) thread starts, I would expect percolating getRealm calls (from Context to Host to Engine) to eventually arrive at the already-defined Tomcat default Realm. HOWEVER, StandardEngine overrides the ContainerBase.getRealm method and ensures that an unconfigured JAAS Realm is instantiated as the default for the Context, because it cannot locate its parent (the field is certainly null, not tomcat), so it decides to use this JAAS as the backstop. This looks to me as if some refactoring between tomcat 5 and 6 left the Tomcat default memory realm orphaned from the StandardEngine, which now operates independently and establishes a completely different default realm. Perhaps the right hand no longer knows what the left hand is doing Funny thing is that I googled this: http://tomcat.10.n6.nabble.com/default-realm-set-to-JAASRealm-in-StandardEngine-td2005479.html ... and your name (Konstantin) is all over it! Can you cast you mind back 4 months and try to give me a clue about the history of this change to the logic? My feeling is that we need to stop StandardEngine from unilaterally creating an unconfigured JAAS default Realm... and help the poor thing find its true parent, i.e. tomcat, which has a perfectly serviceable default memory realm just waiting to be used! (apologies for the mild sarcasm - I can see you are very busy on other issues), Brian - To unsubscribe, e-mail:
Re: problem using default Realm in new unit tests
2012/1/9 Brian Burch br...@pingtoo.com: On 06/01/12 11:47, Konstantin Kolinko wrote: 2012/1/6 Brian Burchbr...@pingtoo.com: I am developing some new unit tests to validate SingleSignOn and Authenticator logic. I have used this existing test class as my template: org.apache.catalina.authenticator.TestDigestAuthenticator .. which extends org.apache.catalina.startup.TomcatBaseTest. I noticed that TestDigestAuthenticator sets up its own MapRealm and assigns it to its single Context. I thought this logic was unnecessary, and so my own initial test logic simply used the default RealmBase provided by the underlying Tomcat instance. I add my test user and role to that. It worked fine with my simple cases, however... To test SSO, I need to set up two Contexts under the same Realm. I see the following message in the output log: INFO: The start() method was called on component [Realm[Simple]] after start() had already been called. The second call will be ignored. I know it is an INFO message. I know the second start (and its associated stop) are ignored and therefore are harmless. However, I am reluctant to simply shrug and ignore it. My instincts tell me something isn't right. I have done quite a lot of investigating, but the underlying logic is very hard for me to follow. Here is what I am sure about: 1. The message is ONLY emitted in tests that create two Contexts and each have the same Realm assigned with setRealm. 2. The message is NOT emitted at the time the Contexts are created and defined (servlets, security constraints, etc). 3. The message IS emitted after the Tomcat.start method is called. 4. The message is emitted by one of the two threads which are started on behalf of my two contexts. The messages are issued by the start and stop methods in the abstract class org.apache.catalina.util.LifecycleBase. 5. org.apache.catalina.realm.RealmBase extends org.apache.catalina.util.LifecycleMBeanBase which extends LifecycleBase. My currently unanswered questions are: 1. Is this message normal? (I don't see it when I start multiple contexts under a real tomcat server, but perhaps the logging properties are different). 2. Why isn't the redundant startup of the Realm detected earlier and simply avoided (maybe the Threads are intended to race to be first with startup - but then I think the message should be debug level and not sound so scary). Please don't waste your time investigating this for me. I am only asking the question because I don't want too get side-tracked if one of you already knows the answers to my questions. I'd like to settle the matter quickly and get back to my original task! Thanks for listening, The message is expected. I would say that the configuration is wrong, or at least unusual. If you look at the default server.xml file you will note that the Realm element there belongs to Engine. That is why it is started once. I agree, and this is what the TomcatBaseTest expects. If you tickle tomcat with TomcatBaseTest.getTomcatInstance() and then with Tomcat.getDefaultRealm(), a new default RealBase (memory) instance is definitely created. When Contexts are created and their context.xml files are parsed, the Contexts always get distinct new Realm instances. Instead of assigning the same Realm instance to both Contexts you should assign it to an upper container (I have not looked at the API though). Or maybe you can have different Realm instances, but which connect to the same backing storage? When the StandardEngine (extending ContainerBase) thread starts, I would expect percolating getRealm calls (from Context to Host to Engine) to eventually arrive at the already-defined Tomcat default Realm. HOWEVER, StandardEngine overrides the ContainerBase.getRealm method and ensures that an unconfigured JAAS Realm is instantiated as the default for the Context, because it cannot locate its parent (the field is certainly null, not tomcat), so it decides to use this JAAS as the backstop. This looks to me as if some refactoring between tomcat 5 and 6 left the Tomcat default memory realm orphaned from the StandardEngine, which now operates independently and establishes a completely different default realm. Perhaps the right hand no longer knows what the left hand is doing Funny thing is that I googled this: http://tomcat.10.n6.nabble.com/default-realm-set-to-JAASRealm-in-StandardEngine-td2005479.html ... and your name (Konstantin) is all over it! Can you cast you mind back 4 months and try to give me a clue about the history of this change to the logic? My feeling is that we need to stop StandardEngine from unilaterally creating an unconfigured JAAS default Realm... and help the poor thing find its true parent, i.e. tomcat, which has a perfectly serviceable default memory realm just waiting to be used! Tomcat is not part of container hierarchy. Tomcat class is just a wrapper/factory that
Re: problem using default Realm in new unit tests
Konstantin, Thank you for your prompt and helpful response... at least I know I haven't overlooked something simple. With your encouragement, I'm happy to keep fighting the alligators until I can get back to draining the swamp! On 10/01/12 02:56, Konstantin Kolinko wrote: 2012/1/9 Brian Burchbr...@pingtoo.com: On 06/01/12 11:47, Konstantin Kolinko wrote: 2012/1/6 Brian Burchbr...@pingtoo.com: I am developing some new unit tests to validate SingleSignOn and Authenticator logic. I have used this existing test class as my template: org.apache.catalina.authenticator.TestDigestAuthenticator .. which extends org.apache.catalina.startup.TomcatBaseTest. I noticed that TestDigestAuthenticator sets up its own MapRealm and assigns it to its single Context. I thought this logic was unnecessary, and so my own initial test logic simply used the default RealmBase provided by the underlying Tomcat instance. I add my test user and role to that. It worked fine with my simple cases, however... To test SSO, I need to set up two Contexts under the same Realm. I see the following message in the output log: INFO: The start() method was called on component [Realm[Simple]] after start() had already been called. The second call will be ignored. I know it is an INFO message. I know the second start (and its associated stop) are ignored and therefore are harmless. However, I am reluctant to simply shrug and ignore it. My instincts tell me something isn't right. I have done quite a lot of investigating, but the underlying logic is very hard for me to follow. Here is what I am sure about: 1. The message is ONLY emitted in tests that create two Contexts and each have the same Realm assigned with setRealm. 2. The message is NOT emitted at the time the Contexts are created and defined (servlets, security constraints, etc). 3. The message IS emitted after the Tomcat.start method is called. 4. The message is emitted by one of the two threads which are started on behalf of my two contexts. The messages are issued by the start and stop methods in the abstract class org.apache.catalina.util.LifecycleBase. 5. org.apache.catalina.realm.RealmBase extends org.apache.catalina.util.LifecycleMBeanBase which extends LifecycleBase. My currently unanswered questions are: 1. Is this message normal? (I don't see it when I start multiple contexts under a real tomcat server, but perhaps the logging properties are different). 2. Why isn't the redundant startup of the Realm detected earlier and simply avoided (maybe the Threads are intended to race to be first with startup - but then I think the message should be debug level and not sound so scary). Please don't waste your time investigating this for me. I am only asking the question because I don't want too get side-tracked if one of you already knows the answers to my questions. I'd like to settle the matter quickly and get back to my original task! Thanks for listening, The message is expected. I would say that the configuration is wrong, or at least unusual. If you look at the default server.xml file you will note that the Realmelement there belongs to Engine. That is why it is started once. I agree, and this is what the TomcatBaseTest expects. If you tickle tomcat with TomcatBaseTest.getTomcatInstance() and then with Tomcat.getDefaultRealm(), a new default RealBase (memory) instance is definitely created. When Contexts are created and their context.xml files are parsed, the Contexts always get distinct new Realm instances. Instead of assigning the same Realm instance to both Contexts you should assign it to an upper container (I have not looked at the API though). Or maybe you can have different Realm instances, but which connect to the same backing storage? When the StandardEngine (extending ContainerBase) thread starts, I would expect percolating getRealm calls (from Context to Host to Engine) to eventually arrive at the already-defined Tomcat default Realm. HOWEVER, StandardEngine overrides the ContainerBase.getRealm method and ensures that an unconfigured JAAS Realm is instantiated as the default for the Context, because it cannot locate its parent (the field is certainly null, not tomcat), so it decides to use this JAAS as the backstop. This looks to me as if some refactoring between tomcat 5 and 6 left the Tomcat default memory realm orphaned from the StandardEngine, which now operates independently and establishes a completely different default realm. Perhaps the right hand no longer knows what the left hand is doing Funny thing is that I googled this: http://tomcat.10.n6.nabble.com/default-realm-set-to-JAASRealm-in-StandardEngine-td2005479.html ... and your name (Konstantin) is all over it! Can you cast you mind back 4 months and try to give me a clue about the history of this change to the logic? My feeling is that we need to stop StandardEngine from unilaterally creating an unconfigured JAAS default Realm... and help the poor thing
Re: problem using default Realm in new unit tests
2012/1/6 Brian Burch br...@pingtoo.com: I am developing some new unit tests to validate SingleSignOn and Authenticator logic. I have used this existing test class as my template: org.apache.catalina.authenticator.TestDigestAuthenticator .. which extends org.apache.catalina.startup.TomcatBaseTest. I noticed that TestDigestAuthenticator sets up its own MapRealm and assigns it to its single Context. I thought this logic was unnecessary, and so my own initial test logic simply used the default RealmBase provided by the underlying Tomcat instance. I add my test user and role to that. It worked fine with my simple cases, however... To test SSO, I need to set up two Contexts under the same Realm. I see the following message in the output log: INFO: The start() method was called on component [Realm[Simple]] after start() had already been called. The second call will be ignored. I know it is an INFO message. I know the second start (and its associated stop) are ignored and therefore are harmless. However, I am reluctant to simply shrug and ignore it. My instincts tell me something isn't right. I have done quite a lot of investigating, but the underlying logic is very hard for me to follow. Here is what I am sure about: 1. The message is ONLY emitted in tests that create two Contexts and each have the same Realm assigned with setRealm. 2. The message is NOT emitted at the time the Contexts are created and defined (servlets, security constraints, etc). 3. The message IS emitted after the Tomcat.start method is called. 4. The message is emitted by one of the two threads which are started on behalf of my two contexts. The messages are issued by the start and stop methods in the abstract class org.apache.catalina.util.LifecycleBase. 5. org.apache.catalina.realm.RealmBase extends org.apache.catalina.util.LifecycleMBeanBase which extends LifecycleBase. My currently unanswered questions are: 1. Is this message normal? (I don't see it when I start multiple contexts under a real tomcat server, but perhaps the logging properties are different). 2. Why isn't the redundant startup of the Realm detected earlier and simply avoided (maybe the Threads are intended to race to be first with startup - but then I think the message should be debug level and not sound so scary). Please don't waste your time investigating this for me. I am only asking the question because I don't want too get side-tracked if one of you already knows the answers to my questions. I'd like to settle the matter quickly and get back to my original task! Thanks for listening, The message is expected. I would say that the configuration is wrong, or at least unusual. If you look at the default server.xml file you will note that the Realm element there belongs to Engine. That is why it is started once. When Contexts are created and their context.xml files are parsed, the Contexts always get distinct new Realm instances. Instead of assigning the same Realm instance to both Contexts you should assign it to an upper container (I have not looked at the API though). Or maybe you can have different Realm instances, but which connect to the same backing storage? Best regards, Konstantin Kolinko - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org