RE: Using Environment variables instead of Java -D properties for context.xml substitution
Can you use catalina.properties? From the docs [1] " All system properties are available including those set using the -D syntax, those automatically made available by the JVM and those configured in the $CATALINA_BASE/conf/catalina.properties file." [1] https://tomcat.apache.org/tomcat-7.0-doc/config/index.html -Original Message- From: Algirdas Veitas [mailto:apvei...@gmail.com] Sent: Monday, January 22, 2018 4:02 PM To: users@tomcat.apache.org Subject: Using Environment variables instead of Java -D properties for context.xml substitution Hi, We have a context.xml under $TOMCAT_HOME/conf that looks like this: if we do something like this in setenv.sh, the substitution works great export DB_USERNAME=xyz export DB_PASSWORD=vvv export JAVA_OPTS="$JAVA_OPTS -DDB_USERNAME=$DB_USERNAME" export JAVA_OPTS="$JAVA_OPTS -DDB_PASSWORD=$DB_PASSWORD" However, if on a linux box, if someone did a "ps -ef | grep java", they would be able to see the actual values of these parameters. theuser 127734 1 0 Jan19 ?00:04:39 /opt/java/bin/java -Djava.util.logging.config.file=/opt/mis/apps/jaspersoft/tomcat/apache-tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -DDB_USERNAME=xyz -DDB_PASSWORD=vvv Which our operations team does not want Is there any syntax that Tomcat can recognize to substitute true environment variables (i.e. export DB_USERNAME=xyz) as opposed to Java properties injected into the JVM by -D (i.e. export DB_USERNAME=$DB_USERNAME) ? Haven't been able to find any documentation on it, but thought would ask. Thanks in advance, Al
Questions about JSSEUtil#getKeyManagers
Hi all, I'm on Java 8 and Tomcat 8.5.26 (built from tag) moving from 7.0.41. I have a little problem with how JSSEUtil#getKeyManagers creates key managers. This essentially causes Tomcat to sometimes serves an incorrect server certificate chain during ServerHello. -Djavax.net.debug=all gave me a clue as it printed out multiple "matching alias", so I believe it's because the key manager (and key store) returned from that method doesn't contain only one key. From what I see, when switching to in-memory key store getKeyManagers creates a new key store of the configured type, calls setKeyEntry and expects the new key store to have only this one key in it. Note that we have our own implementation of the key store, but please bear with me. I'm also aware of this following bit of documentation and I suspect that the second sentence is very much related to my problem here. I'm also sure the certificateKeyAlias is set correctly and SSLHostConfigCertificate has all the expected values when I checked in debug mode. > The alias used for the server key and certificate in the keystore. If not specified, the first key read from the keystore will be used. The order in which keys are read from the keystore is implementation dependent. We didn't have this problem in 7.0.41 because it's doing something less complex and eventually just creates a JSSEKeyManager with the expected key alias with the key store as a delegate – see https://github.com/apache/tomcat70/blob/TOMCAT_7_0_41/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java#L563 But in 8.5, https://github.com/apache/tomcat85/blob/TOMCAT_8_5_26/java/org/apache/tomcat/util/net/jsse/JSSEUtil.java#L267 the identity comparison "ksUsed == ks" looks kind of weird to me as KeyStore.getInstance (at least in Oracle Java 8) always returns a new instance of KeyStore, so the checks will never be true (or will it?). Ideally, I'd want to find a way to get into that if block so the end state is like in 7.0.41. As I mentioned, we have our own key store implementation and it always loads all keys it's supposed to know about so reassigning "ksUsed = KeyStore.getInstance..." doesn't make a difference for us – it actually makes it worse as without it "ksUsed == ks" would have been true. We technically can just modify or introduce a new key store implementation to cater for Tomcat implementation – locally patching Tomcat to remove the identity check would work for us as well. Before doing that, am I missing something obvious? is reimplementing our key store the way to go here? Cheers, Nitkalya
Using Environment variables instead of Java -D properties for context.xml substitution
Hi, We have a context.xml under $TOMCAT_HOME/conf that looks like this: if we do something like this in setenv.sh, the substitution works great export DB_USERNAME=xyz export DB_PASSWORD=vvv export JAVA_OPTS="$JAVA_OPTS -DDB_USERNAME=$DB_USERNAME" export JAVA_OPTS="$JAVA_OPTS -DDB_PASSWORD=$DB_PASSWORD" However, if on a linux box, if someone did a "ps -ef | grep java", they would be able to see the actual values of these parameters. theuser 127734 1 0 Jan19 ?00:04:39 /opt/java/bin/java -Djava.util.logging.config.file=/opt/mis/apps/jaspersoft/tomcat/apache-tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -DDB_USERNAME=xyz -DDB_PASSWORD=vvv Which our operations team does not want Is there any syntax that Tomcat can recognize to substitute true environment variables (i.e. export DB_USERNAME=xyz) as opposed to Java properties injected into the JVM by -D (i.e. export DB_USERNAME=$DB_USERNAME) ? Haven't been able to find any documentation on it, but thought would ask. Thanks in advance, Al
Re: Can't Get SSL to Work in 8.5
On Mon, Jan 22, 2018 at 2:23 PM, Kenneth Taylorwrote: > We are trying to get SSL to work in 8.5 and have been unsuccessful. We > followed all the instructions in the Tomcat documentation and what help is > available on the net but have been unable to get TC to startup with an SSL > Connector configured. > > Here is our Connector configuration: > > scheme="http" redirectPort="8443" secure="false"/> > > SSLEnabled="true" > clientAuth="false" > maxThreads="20" > port="8443" > protocol="org.apache.coyote.http11.Http11NioProtocol" > sslImplementation="org.apache.tomcat.util.net.jsse.JSSEImplemntation" > scheme="https" > secure="true" > sslProtocol="TLS"> Remove `clientAuth="false"` and `sslProtocol="TLS"` from the Connector element and place them inside the SSLHostConfig element below. These two attributes are now SSLHostConfig attributes (even though they are allowed in the Connector because tomcat translates them to a default SSLHostConfig object initialized with those values). It's also noteworthy that you're using the default values for clientAuth and sslProtocol, so they aren't necessary. > hostName="localhost" You need an SSLHostConfig that's named _default_ for this to work (which is the default name) so remove hostName="localhost" too and this should work :) I'm going to file a BZ and see if others are interested in catching this NPE and doing something more useful with it. I'm also going to file an enhancement to remove the requirement to have a _default_ SSLHostConfig, if possible. > protocols="TLSv1.2" > sessionCacheSize="15" > sessionTimeout="960"> >certificateKeyAlias="localhost" > certificateKeystoreFile="conf/localhost-rsa.jks" > certificateKeystorePassword="=NR5^vtuW_/?" > certificateVerification="optionalNoCA" > type="RSA"/> > > > > Here is the error we get: > > Jan 19, 2018 2:24:07 PM org.apache.catalina.core.StandardService initInternal > SEVERE: Failed to initialize connector [Connector[HTTP/1.1-8443]] > org.apache.catalina.LifecycleException: Failed to initialize component > [Connector[HTTP/1.1-8443]] > at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:112) > at > org.apache.catalina.core.StandardService.initInternal(StandardService.java:549) > at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107) > at > org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:875) > at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107) > at org.apache.catalina.startup.Catalina.load(Catalina.java:607) > at org.apache.catalina.startup.Catalina.load(Catalina.java:630) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) > at > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.lang.reflect.Method.invoke(Method.java:498) > at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:311) > at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:494) > Caused by: org.apache.catalina.LifecycleException: Protocol handler > initialization failed > at org.apache.catalina.connector.Connector.initInternal(Connector.java:999) > at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107) > ... 12 more > Caused by: java.lang.IllegalArgumentException: java.lang.NullPointerException > at > org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:114) > at > org.apache.tomcat.util.net.AbstractJsseEndpoint.initialiseSsl(AbstractJsseEndpoint.java:85) > at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:225) > at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:970) > at > org.apache.tomcat.util.net.AbstractJsseEndpoint.init(AbstractJsseEndpoint.java:244) > at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:613) > at > org.apache.coyote.http11.AbstractHttp11Protocol.init(AbstractHttp11Protocol.java:66) > at org.apache.catalina.connector.Connector.initInternal(Connector.java:997) > ... 13 more > Caused by: java.lang.NullPointerException > at java.io.FileInputStream.(FileInputStream.java:130) > at java.io.FileInputStream.(FileInputStream.java:93) > at java.io.FileReader.(FileReader.java:58) > at org.apache.tomcat.util.net.jsse.PEMFile.(PEMFile.java:74) > at org.apache.tomcat.util.net.jsse.JSSEUtil.getKeyManagers(JSSEUtil.java:193) > at > org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:112) > ... 20 more > > We tried all kinds of variations of the configuration. We've run out of > things to try. > We are using a JKS keystore created in Java code using the Bouncy Castle API. > The config files are all in the correct location. > The keystore has a private key and certificate
Re: StoreConfig default registry misspelling
Am 22.01.2018 um 08:53 schrieb Rémy Maucherat: On Mon, Jan 22, 2018 at 8:35 AM, d3coderwrote: I can't enable StoreConfigLifecycleListener with default settings because of misspelling in class name in default server-registry.xml XML line 138 - storeFactoryClass="org.apache.catalina.storeconfig. OpenSSLConfSF" storeFactoryClass should be org.apache.catalina. storeconfig.SSLHostConfigSF or SSLHostConfigSF class should be renamed to OpenSSLConfSF. You can probably file a BZ, the class seems to be missing from r1805550. As a workaround since you're not using OpenSSLConf you should replace that store factory with the generic org.apache.catalina.storeconfig.StoreFactoryBase. Sorry for the inconcenience and thanks for letting us/me know. I forgot to commit that class and did it just now in r1821932 for TC 9 and r1821935 for TC 8.5. They will be part of 9.0.5 resp. 8.5.28 in about a month. The class is small though and should be compatible with a wide range of TC 8.5 and 9 versions. If you can compile Tomcat yourself, you can add this class to the storeconfig folder: /** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.catalina.storeconfig; import java.io.PrintWriter; import org.apache.tomcat.util.net.openssl.OpenSSLConf; import org.apache.tomcat.util.net.openssl.OpenSSLConfCmd; /** * Store OpenSSLConf */ public class OpenSSLConfSF extends StoreFactoryBase { /** * Store nested OpenSSLConfCmd elements. * {@inheritDoc} */ @Override public void storeChildren(PrintWriter aWriter, int indent, Object aOpenSSLConf, StoreDescription parentDesc) throws Exception { if (aOpenSSLConf instanceof OpenSSLConf) { OpenSSLConf openSslConf = (OpenSSLConf) aOpenSSLConf; // Store nested elements OpenSSLConfCmd[] openSSLConfCmds = openSslConf.getCommands().toArray(new OpenSSLConfCmd[0]); storeElementArray(aWriter, indent + 2, openSSLConfCmds); } } } Regards, Rainer - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Can't Get SSL to Work in 8.5
We are trying to get SSL to work in 8.5 and have been unsuccessful. We followed all the instructions in the Tomcat documentation and what help is available on the net but have been unable to get TC to startup with an SSL Connector configured. Here is our Connector configuration: Here is the error we get: Jan 19, 2018 2:24:07 PM org.apache.catalina.core.StandardService initInternal SEVERE: Failed to initialize connector [Connector[HTTP/1.1-8443]] org.apache.catalina.LifecycleException: Failed to initialize component [Connector[HTTP/1.1-8443]] at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:112) at org.apache.catalina.core.StandardService.initInternal(StandardService.java:549) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107) at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:875) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107) at org.apache.catalina.startup.Catalina.load(Catalina.java:607) at org.apache.catalina.startup.Catalina.load(Catalina.java:630) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:311) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:494) Caused by: org.apache.catalina.LifecycleException: Protocol handler initialization failed at org.apache.catalina.connector.Connector.initInternal(Connector.java:999) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107) ... 12 more Caused by: java.lang.IllegalArgumentException: java.lang.NullPointerException at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:114) at org.apache.tomcat.util.net.AbstractJsseEndpoint.initialiseSsl(AbstractJsseEndpoint.java:85) at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:225) at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:970) at org.apache.tomcat.util.net.AbstractJsseEndpoint.init(AbstractJsseEndpoint.java:244) at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:613) at org.apache.coyote.http11.AbstractHttp11Protocol.init(AbstractHttp11Protocol.java:66) at org.apache.catalina.connector.Connector.initInternal(Connector.java:997) ... 13 more Caused by: java.lang.NullPointerException at java.io.FileInputStream.(FileInputStream.java:130) at java.io.FileInputStream.(FileInputStream.java:93) at java.io.FileReader.(FileReader.java:58) at org.apache.tomcat.util.net.jsse.PEMFile.(PEMFile.java:74) at org.apache.tomcat.util.net.jsse.JSSEUtil.getKeyManagers(JSSEUtil.java:193) at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:112) ... 20 more We tried all kinds of variations of the configuration. We've run out of things to try. We are using a JKS keystore created in Java code using the Bouncy Castle API. The config files are all in the correct location. The keystore has a private key and certificate (self-signed using BC). Aliases & passwords are correct. Everything about the keystore looks correct. We tried "tomcat" as the alias (matching the entry in the keystore). We also tried the real hostname for hostName and matched the keysore alias to it. Our keys ares RSA 2048. We tried adding all the typical extensions to the CERT. The error above indicates that TC is looking for PEM files. Why? We weren't using PEM files. So, we tried switching to using PEM files but that throws another weird error from the SecretKeyGenerator about an invalid KeyGen algorithm. We are specifiying SHA256withRSA for KeyGen but TC is trying to use pbeWithSHAAnd2-KeyTripleDES-CBC. This looks like a bug. Also, we have configured many security settings. For example, all of the security related Filters are confgured in web.xml. TC version: 8.5.15 OS: Windows 8.1 Thanks for any help you can provide. Ken Disclaimer: This email from DMBGroup LLC, DMB Consulting Services LLC, or the personnel associated with either entity (collectively "DMB") and attachments, contain CONFIDENTIAL, PRIVILEGED AND PROPRIETARY information for exclusive use of the addressee individual(s) or entity. Unauthorized viewing, copying, disclosure, distribution or use of this e-mail or attachments may be subject to legal restriction or sanction. If received in error, notify sender immediately by return e-mail and delete original message and attachments. Nothing contained in this e-mail or attachments shall satisfy the requirements for a writing unless specifically stated. Nothing contained herein shall constitute a contract or electronic signature under the Electronic Signatures in Global and National Commerce Act, any version of the Uniform Electronic Transactions
Re: AJP Connector not throwing EOFException
Hi Chris, > Forget about EOFException, that was my mistake in the first email > > (and subject). I'm interested in improved handling of aborted > > connections (at least most of them). That's my end goal. > > > > read=-1 solely does not provide sufficient information to be able > > to distinguish between malformed request bodies and actual aborted > > connections. > > How is Tomcat supposed to determine the difference? > > > That's why the ServletInputStream#readLine API says: Returns: an > > integer specifying the actual number of bytes read, or -1 if the > > end of the stream is reached Throws: IOException - if an input or > > output exception has occurred > > End-of-stream is not an exceptional condition. > > > I understand that detecting aborted connections is not always > > possible because of the missed handshakes but given that apache2 > > and tomcat are most likely in the same local network and assuming > > the protocol closes sockets properly, as long as apache2 detects it > > tomcat should also. > > You are talking about AJP, which does not close connections between > the reverse proxy (httpd) and Tomcat. So... what event are you looking > for that Tomcat can use to signal an error? > You're spot on for the source of confusion. I thought AJP does close the connection between the reverse proxy and tomcat based on the apache log below (especially line 3 and 6). [Wed Jan 17 14:42:41 2018] [23791:140542260176640] [info] ajp_service::jk_ajp_common.c (2773): (directory_service) sending request to tomcat failed (unrecoverable), because of client read error (attempt=1) [Wed Jan 17 14:42:41 2018] [23791:140542260176640] [debug] ajp_reset_endpoint::jk_ajp_common.c (851): (directory_service) resetting endpoint with socket 23 (socket shutdown) [Wed Jan 17 14:42:41 2018] [23791:140542260176640] [debug] ajp_abort_endpoint::jk_ajp_common.c (821): (directory_service) aborting endpoint with socket 23 [Wed Jan 17 14:42:41 2018] [23791:140542260176640] [debug] jk_shutdown_socket::jk_connect.c (932): About to shutdown socket 23 [ 127.0.0.1:42538 -> 127.0.0.1:15443] [Wed Jan 17 14:42:41 2018] [23791:140542260176640] [debug] jk_is_input_event::jk_connect.c (1383): timeout during poll on socket 23 [ 127.0.0.1:42538 -> 127.0.0.1:15443] (timeout=100) [Wed Jan 17 14:42:41 2018] [23791:140542260176640] [debug] jk_shutdown_socket::jk_connect.c (1016): Shutdown socket 23 [127.0.0.1:42538 -> 127.0.0.1:15443] and read 0 lingering bytes in 0 sec. [Wed Jan 17 14:42:41 2018] [23791:140542260176640] [debug] ajp_done::jk_ajp_common.c (3282): recycling connection pool for worker directory_service and socket -1 [Wed Jan 17 14:42:41 2018] [23791:140542260176640] [debug] jk_handler::mod_jk.c (2921): Consumed 0 bytes of remaining request data for worker=directory_service [Wed Jan 17 14:42:41 2018] [23791:140542260176640] [info] jk_handler::mod_jk.c (2984): Aborting connection for worker=directory_service And also based on the ajp workers documentation which has specific recovery_options 4 that closes the connection to tomcat if an error when writing back the answer to the client is detected. Yes, this is for write not read. So, the next question is whether there is a way to have connections between apache and tomcat closed when aborted. > > I therefore think my expectation for an IOException when trying to > > read is justified. > > > > Do you still think otherwise? > > I do. It's not really up to Tomcat to verify that the client sent all > of the data it intended to send. > > George
Re: roles stripped when using login() in tomcat 8.5 but not 8.0
Hi Mark, everyone- I've constructed a sample app of ~5 files. The code is bundled in the jar file in the WEB-INF/lib directory. Here's a public url for the application (test.war; 8K): https://drive.google.com/file/d/1mZRXrm90F4WN3mizqoqrWYmQ1HHfrSS4/view?usp=sharing To reproduce the problem in tomcat 8.5.24 (for me): 1) make a user available with the role "testrole" (I just user tomcat-users) 2) startup tomcat, copy the war file into webapps 3) go to the application homepage, index.jsp should auto load 4) enter username and password and login; it should change to the username you're authenticated with 5) hit the auth test link and it should give you a success message 6) hit the same link again and it should give you a 403 If you want to see how things are changing, I created an unprotected page called /authinfo (no jsp) that shows the logged in user and role. Here's what it shows as you proceed through the test: * no user or role * user and role * user, but no role If you do this same process in tomcat 8 (8.0.43, for me) it works fine, particularly, the you can hit the link as many times as you want and the roles never go away until you logout. And generally, the login/test/logout works perfectly, where in 8.5 even if you logout it doesn't always log you back in the next time either. Sometimes its takes several attempts. Hopefully this is enough to give me some guidance. Some more info, if it helps: * macOS 10.13 * jdk1.8.0_131 Please let me know if you have any questions. Thanks again for the help! Robert (Note: I ripped this code from a larger codebase, so please don't hold me to the strictest coding standards :) ) On Fri, Jan 19, 2018 at 12:37 AM, Robert J. Carrwrote: > > OK, thanks Mark, I'll try to come up with a test plan, but I'm seriously pressed for time as this has eaten two full days. Thanks again for the help! > > On Fri, Jan 19, 2018 at 12:14 AM, Mark Thomas wrote: >> >> On 18/01/18 22:03, Robert J. Carr wrote: >> > (Bear with me as there are a lot of details; I'll try to be as clear as >> > possible) >> > >> > I've been setting up a simple application in tomcat 8.0 where some >> > resources are protected but others aren't. I want to login using AJAX >> > instead of FORM or BASIC so I don't have any login-config specified in my >> > deployment descriptor (nor any security-roles defined). >> > >> > For testing, I have a custom form that sends login info asynchronously to >> > an unprotected login service which calls login(). On the same page as the >> > login form, I have a test button that makes an asynchronous request to a >> > protected resource (using a @ServletSecurity annotation). As expected, >> > before calling login (and thus login()) I get a 403, but after doing the >> > login() I get a 200 and can see the response text. This all works fine in >> > tomcat 8.0. >> > >> > However, when I try the application in tomcat 8.5, with the same server and >> > application config, something different happens. I do the login and call >> > the protected resource and get the 200 as before, but now every subsequent >> > call to the protected resource returns a 403. I thought maybe there was >> > something peculiar about this specific protected resource, but not the >> > case, any protected resource works the first time, but not subsequent times. >> > >> > To confirm what is going on, I created an unprotected resource that >> > provides auth info, and I can see after I login() it reports my username >> > and my affiliated roles (using isUserInRole() for known role names). And I >> > can refresh this info any number of times and it doesn't change. But as >> > soon as I access a protected resource, twice, the unprotected auth info >> > still shows my username, but now my roles are stripped. >> > >> > Thinking there is something wrong with login(), I change to using BASIC and >> > run similar tests, never using the login() call, and everything works fine; >> > notably, I can access a protected resource more than once. >> > >> > Strangely, what I also unexpectedly noticed is now that I have BASIC >> > specified, when I do use login() things are working fine now even if I >> > never get a BASIC prompt. So, I can access a protected resource more than >> > once. >> > >> > I know this sounds like a weird state issue, but I've restarted web >> > servers, browsers, deployed, undeployed, and redeployed apps dozens and >> > dozens of time. And I even confirmed the 200 and subsequent 403 calls were >> > exactly the same; notably, both had the same session cookie information. >> > >> > So, if this isn't a tomcat bug, which of course I'm very hesitant to imply, >> > then maybe there is something that changed in the configuration that was >> > optional before but maybe isn't now? Maybe I have to specify BASIC or FORM >> > even if I never plan to use it? Any other suggestions? >> >> Create the simplest possible test case that