You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by "Thomas Hoffmann (Speed4Trade GmbH)" <Th...@speed4trade.com.INVALID> on 2021/11/22 07:38:51 UTC

Authentication with Browser stopped working / missing exception handling in getRemainingLifetime

Hello,
we are using apache-tomcat-9.0.54 with LDAP authentication under Windows 2012R2.
One of the user complained that access with Firefox stopped working.

Looking into the logs I could find the following message:
                java.lang.IllegalStateException: This credential is no longer valid
                               at java.security.jgss/sun.security.jgss.GSSCredentialImpl.getRemainingLifetime(GSSCredentialImpl.java:208)
                               at org.apache.catalina.connector.Request.getUserPrincipal(Request.java:2659)
                               at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:508)
                               at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
                               at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
                               at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
                               at org.apache.catalina.authenticator.SingleSignOn.invoke(SingleSignOn.java:312)
                               at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
                               at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
                               at org.apache.coyote.http2.StreamProcessor.service(StreamProcessor.java:413)
                               at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
                               at org.apache.coyote.http2.StreamProcessor.process(StreamProcessor.java:74)
                               at org.apache.coyote.http2.StreamRunnable.run(StreamRunnable.java:35)

Looking into the sources of Request.java I can see that the exception is not catched and handled:

    public Principal getUserPrincipal() {
        if (userPrincipal instanceof TomcatPrincipal) {
            GSSCredential gssCredential =
                    ((TomcatPrincipal) userPrincipal).getGssCredential();
            if (gssCredential != null) {
                int left = -1;
                try {
                    left = gssCredential.getRemainingLifetime();
                } catch (GSSException e) {
                    log.warn(sm.getString("coyoteRequest.gssLifetimeFail",
                            userPrincipal.getName()), e);
                }
               if (left == 0) {
....

Would it be better to also catch IllegalStateException and instead of checking left == 0 to change it to left <= 0 ?

The only possible way to resolve the issue was to delete the browser cache including the credentials.

Greetings,
Thomas


AW: Authentication with Browser stopped working / missing exception handling in getRemainingLifetime

Posted by "Thomas Hoffmann (Speed4Trade GmbH)" <Th...@speed4trade.com.INVALID>.
Hello Mark,

thank you very much for your lightning speed fix and answer 😊

Have a nice day,
Thomas

-----Ursprüngliche Nachricht-----
Von: Mark Thomas <ma...@apache.org> 
Gesendet: Montag, 22. November 2021 18:44
An: users@tomcat.apache.org
Betreff: Re: Authentication with Browser stopped working / missing exception handling in getRemainingLifetime

On 22/11/2021 07:38, Thomas Hoffmann (Speed4Trade GmbH) wrote:
> Hello,
> we are using apache-tomcat-9.0.54 with LDAP authentication under Windows 2012R2.
> One of the user complained that access with Firefox stopped working.

<snip/>

> Would it be better to also catch IllegalStateException and instead of checking left == 0 to change it to left <= 0 ?

Both fair points. Thanks for bringing them to the community's attention. 
I've fixed both issues for the next set of releases.

Mark

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


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


Re: Authentication with Browser stopped working / missing exception handling in getRemainingLifetime

Posted by Mark Thomas <ma...@apache.org>.
On 22/11/2021 07:38, Thomas Hoffmann (Speed4Trade GmbH) wrote:
> Hello,
> we are using apache-tomcat-9.0.54 with LDAP authentication under Windows 2012R2.
> One of the user complained that access with Firefox stopped working.

<snip/>

> Would it be better to also catch IllegalStateException and instead of checking left == 0 to change it to left <= 0 ?

Both fair points. Thanks for bringing them to the community's attention. 
I've fixed both issues for the next set of releases.

Mark

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


AW: Authentication with Browser stopped working / missing exception handling in getRemainingLifetime

Posted by "Thomas Hoffmann (Speed4Trade GmbH)" <Th...@speed4trade.com.INVALID>.
Hello,

though it might be a bug in the implementation, the current proposed remediation within Tomcat
is still a good choice for the time being in my point of view and won't have any bad side effects in future.
It makes Tomcat more robust, more robust than the JGSS API requires.

Greetings,
Thomas

-----Ursprüngliche Nachricht-----
Von: Michael B Allen <io...@gmail.com> 
Gesendet: Dienstag, 23. November 2021 21:42
An: Tomcat Users List <us...@tomcat.apache.org>
Betreff: Re: Authentication with Browser stopped working / missing exception handling in getRemainingLifetime

On Tue, Nov 23, 2021 at 2:59 PM Thomas Hoffmann (Speed4Trade GmbH) <Th...@speed4trade.com.invalid> wrote:
>
> Short Addendum:
>
> The "destroyed" flag gets set, when the dispose-method of the GSSCredentialImpl was invoked.
> Currently, I have no clue when and how it happens, but I have seen this problem every few months.
> So it is only occurring sometimes. Maybe if the Kerberos ticket 
> expires and the http session is still alive (?)
>
> Nevertheless, the application should be able to recover from this situation and handles it like "not authenticated".

So as suspected it may actually be an invalid credential that maybe Tomcat had a hand in. If Tomcat disposed the credential and then subsequently tried to use it for any reason, that would be "invalid".
So that might warrant investigation before submitting a bug report.

But I would still argue that a JGSS implementation should not throw exceptions that are not defined by the API and currently only GSSException is defined.

Correction: This is not a bug in the JGSS API, it is (almost
certainly) a bug in the *Oracle / Sun implementation* of JGSS.

Mike

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


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


Re: Authentication with Browser stopped working / missing exception handling in getRemainingLifetime

Posted by Mark Thomas <ma...@apache.org>.
On 24/11/2021 08:06, Mark Thomas wrote:
> On 23/11/2021 20:42, Michael B Allen wrote:
>> On Tue, Nov 23, 2021 at 2:59 PM Thomas Hoffmann (Speed4Trade GmbH)
>> <Th...@speed4trade.com.invalid> wrote:
>>>
>>> Short Addendum:
>>>
>>> The "destroyed" flag gets set, when the dispose-method of the 
>>> GSSCredentialImpl was invoked.
>>> Currently, I have no clue when and how it happens, but I have seen 
>>> this problem every few months.
>>> So it is only occurring sometimes. Maybe if the Kerberos ticket 
>>> expires and the http session is still alive (?)
>>>
>>> Nevertheless, the application should be able to recover from this 
>>> situation and handles it like "not authenticated".
>>
>> So as suspected it may actually be an invalid credential that maybe
>> Tomcat had a hand in. If Tomcat disposed the credential and then
>> subsequently tried to use it for any reason, that would be "invalid".
>> So that might warrant investigation before submitting a bug report.
> 
> That might be possible.
> 
> Tomcat calls dispose when the user explicitly logs out or the session 
> expires. The OP is using http2 so parallel requests are likely.
> 
> I'll look into this some more.

It looks like concurrent requests for an expired session will trigger 
this. Avoiding the IllegalStateExcpetion would require adding 
synchronization to Request.getUserPrincipal(). Given that issue occurs 
once every few months my preference is to catch the ISE rather than 
avoid it since avoiding it has a (small) impact on every request.

I've checked and multiple calls to dispose() are safe so the current 
approach appears to be sound. I'll add some comments to the code for 
future maintainers.

Mark

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


Re: Authentication with Browser stopped working / missing exception handling in getRemainingLifetime

Posted by Mark Thomas <ma...@apache.org>.
On 23/11/2021 20:42, Michael B Allen wrote:
> On Tue, Nov 23, 2021 at 2:59 PM Thomas Hoffmann (Speed4Trade GmbH)
> <Th...@speed4trade.com.invalid> wrote:
>>
>> Short Addendum:
>>
>> The "destroyed" flag gets set, when the dispose-method of the GSSCredentialImpl was invoked.
>> Currently, I have no clue when and how it happens, but I have seen this problem every few months.
>> So it is only occurring sometimes. Maybe if the Kerberos ticket expires and the http session is still alive (?)
>>
>> Nevertheless, the application should be able to recover from this situation and handles it like "not authenticated".
> 
> So as suspected it may actually be an invalid credential that maybe
> Tomcat had a hand in. If Tomcat disposed the credential and then
> subsequently tried to use it for any reason, that would be "invalid".
> So that might warrant investigation before submitting a bug report.

That might be possible.

Tomcat calls dispose when the user explicitly logs out or the session 
expires. The OP is using http2 so parallel requests are likely.

I'll look into this some more.

Mark

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


Re: Authentication with Browser stopped working / missing exception handling in getRemainingLifetime

Posted by Michael B Allen <io...@gmail.com>.
On Tue, Nov 23, 2021 at 2:59 PM Thomas Hoffmann (Speed4Trade GmbH)
<Th...@speed4trade.com.invalid> wrote:
>
> Short Addendum:
>
> The "destroyed" flag gets set, when the dispose-method of the GSSCredentialImpl was invoked.
> Currently, I have no clue when and how it happens, but I have seen this problem every few months.
> So it is only occurring sometimes. Maybe if the Kerberos ticket expires and the http session is still alive (?)
>
> Nevertheless, the application should be able to recover from this situation and handles it like "not authenticated".

So as suspected it may actually be an invalid credential that maybe
Tomcat had a hand in. If Tomcat disposed the credential and then
subsequently tried to use it for any reason, that would be "invalid".
So that might warrant investigation before submitting a bug report.

But I would still argue that a JGSS implementation should not throw
exceptions that are not defined by the API and currently only
GSSException is defined.

Correction: This is not a bug in the JGSS API, it is (almost
certainly) a bug in the *Oracle / Sun implementation* of JGSS.

Mike

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


AW: Authentication with Browser stopped working / missing exception handling in getRemainingLifetime

Posted by "Thomas Hoffmann (Speed4Trade GmbH)" <Th...@speed4trade.com.INVALID>.
Short Addendum:

The "destroyed" flag gets set, when the dispose-method of the GSSCredentialImpl was invoked.
Currently, I have no clue when and how it happens, but I have seen this problem every few months.
So it is only occurring sometimes. Maybe if the Kerberos ticket expires and the http session is still alive (?)

Nevertheless, the application should be able to recover from this situation and handles it like "not authenticated".

Greetings, 
Thomas


-----Ursprüngliche Nachricht-----
Von: Thomas Hoffmann (Speed4Trade GmbH) <Th...@speed4trade.com.INVALID> 
Gesendet: Dienstag, 23. November 2021 20:51
An: Tomcat Users List <us...@tomcat.apache.org>
Betreff: AW: Authentication with Browser stopped working / missing exception handling in getRemainingLifetime

Hello Mike,

I checked the last Java 17 Sources, the illegalStateException is still there:
https://github.com/openjdk/jdk/blob/jdk-17%2B35/src/java.security.jgss/share/classes/sun/security/jgss/GSSCredentialImpl.java

    public int getRemainingLifetime() throws GSSException {

        if (destroyed) {
            throw new IllegalStateException("This credential is " +
                                        "no longer valid");
        }
...

Latest Java 18 Code looks the same.

I agree, that there are better ways to tell the caller about the invalid Kerberos ticket status.
IllegalStateException is a runtime exception whereas the method only declares a checked GSSException which is maybe not the best way to design this method.

If somebody has good connections to the Java developers, maybe he/she can trigger an improvement. Unfortunately it might break the compatibility to other tools if a checked exception is used.

Btw: you are right, the authentication is done via Kerberos. For role assignment, LDAP is used in combination in our case.

Thanks!
Thomas


-----Ursprüngliche Nachricht-----
Von: Michael B Allen <io...@gmail.com>
Gesendet: Dienstag, 23. November 2021 17:32
An: Tomcat Users List <us...@tomcat.apache.org>
Betreff: Re: Authentication with Browser stopped working / missing exception handling in getRemainingLifetime

On Mon, Nov 22, 2021 at 2:39 AM Thomas Hoffmann (Speed4Trade GmbH) <Th...@speed4trade.com.invalid> wrote:
> Would it be better to also catch IllegalStateException and instead of checking left == 0 to change it to left <= 0 ?

I would argue that this is a bug in JGSS. JGSS has been a comedy of errors over the years. I thought it had mostly stabilized over the last 5-10 years but this is a good example of the sort of bad behavior from that lib. Throwing an IllegalStateException there is a bad API choice. I have to wonder if that was not the designers intention. The getRemainingLifetime API documentation does not say anything about it throwing an IllegalStateException when your cred expires. You might want to try the latest JRE if you're using something old. Or maybe there's something screwy about the cred and it's tripping up an unexpected code path. I assume you mean Kerberos and not LDAP BTW.

But I think the only real short term solution for now would be to catch the IllegalStateException and just set left = 0.

Mike

--
Michael B Allen
Java Active Directory Integration
http://www.ioplex.com/

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

B KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKCB  [  X  ܚX KK[XZ[
 \ \  ][  X  ܚX P X ]
 \X K ܙ B  ܈Y][ۘ[  [X[  K[XZ[
 \ \  Z[ X ]
 \X K ܙ B 

AW: Authentication with Browser stopped working / missing exception handling in getRemainingLifetime

Posted by "Thomas Hoffmann (Speed4Trade GmbH)" <Th...@speed4trade.com.INVALID>.
Hello Mike,

I checked the last Java 17 Sources, the illegalStateException is still there:
https://github.com/openjdk/jdk/blob/jdk-17%2B35/src/java.security.jgss/share/classes/sun/security/jgss/GSSCredentialImpl.java

    public int getRemainingLifetime() throws GSSException {

        if (destroyed) {
            throw new IllegalStateException("This credential is " +
                                        "no longer valid");
        }
...

Latest Java 18 Code looks the same.

I agree, that there are better ways to tell the caller about the invalid Kerberos ticket status.
IllegalStateException is a runtime exception whereas the method only declares a checked GSSException which is maybe not the best way to design this method.

If somebody has good connections to the Java developers, maybe he/she can trigger an improvement. Unfortunately it might break the compatibility
to other tools if a checked exception is used.

Btw: you are right, the authentication is done via Kerberos. For role assignment, LDAP is used in combination in our case.

Thanks!
Thomas


-----Ursprüngliche Nachricht-----
Von: Michael B Allen <io...@gmail.com> 
Gesendet: Dienstag, 23. November 2021 17:32
An: Tomcat Users List <us...@tomcat.apache.org>
Betreff: Re: Authentication with Browser stopped working / missing exception handling in getRemainingLifetime

On Mon, Nov 22, 2021 at 2:39 AM Thomas Hoffmann (Speed4Trade GmbH) <Th...@speed4trade.com.invalid> wrote:
> Would it be better to also catch IllegalStateException and instead of checking left == 0 to change it to left <= 0 ?

I would argue that this is a bug in JGSS. JGSS has been a comedy of errors over the years. I thought it had mostly stabilized over the last 5-10 years but this is a good example of the sort of bad behavior from that lib. Throwing an IllegalStateException there is a bad API choice. I have to wonder if that was not the designers intention. The getRemainingLifetime API documentation does not say anything about it throwing an IllegalStateException when your cred expires. You might want to try the latest JRE if you're using something old. Or maybe there's something screwy about the cred and it's tripping up an unexpected code path. I assume you mean Kerberos and not LDAP BTW.

But I think the only real short term solution for now would be to catch the IllegalStateException and just set left = 0.

Mike

--
Michael B Allen
Java Active Directory Integration
http://www.ioplex.com/

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


Re: Authentication with Browser stopped working / missing exception handling in getRemainingLifetime

Posted by Michael B Allen <io...@gmail.com>.
On Mon, Nov 22, 2021 at 2:39 AM Thomas Hoffmann (Speed4Trade GmbH)
<Th...@speed4trade.com.invalid> wrote:
> Would it be better to also catch IllegalStateException and instead of checking left == 0 to change it to left <= 0 ?

I would argue that this is a bug in JGSS. JGSS has been a comedy of
errors over the years. I thought it had mostly stabilized over the
last 5-10 years but this is a good example of the sort of bad behavior
from that lib. Throwing an IllegalStateException there is a bad API
choice. I have to wonder if that was not the designers intention. The
getRemainingLifetime API documentation does not say anything about it
throwing an IllegalStateException when your cred expires. You might
want to try the latest JRE if you're using something old. Or maybe
there's something screwy about the cred and it's tripping up an
unexpected code path. I assume you mean Kerberos and not LDAP BTW.

But I think the only real short term solution for now would be to
catch the IllegalStateException and just set left = 0.

Mike

-- 
Michael B Allen
Java Active Directory Integration
http://www.ioplex.com/

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