Hi Petr,
It looks like I must have changed it after that post. I did not comment out
the entire clearTicketGrantingCookieFromContext call, just commented out
the line contained within it:
// ticketGrantingTicketCookieGenerator.removeCookie(response);
I've dedicated today to debugging this:
ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (default task-76)
Batch entry 0 insert into Postgres_Jpa_Ticket_Entity (body, creation_Time,
parent_Id, principal_Id, type, id) values
('{"@class":"org.apereo.cas.ticket.TransientSessionTicketImpl","@id":1,"expirationPolicy":{"@class":"org.apereo.cas.ticket.expiration.MultiTimeUseOrTimeoutExpirationPolicy$TransientSessionTicketExpirationPolicy","numberOfUses":3,"timeToLive":180,"name":"TransientSessionTicketExpirationPolicy-2547f234-9127-460d-9310-b1f901df3e40"},"id":"TST-xxxxxxx","lastTimeUsed":"2024-04-03T15:15:44.23861Z","creationTime":"2024-04-03T15:15:44.23861Z","properties":{"@class":"java.util.HashMap","AzureAdClient$stateSessionParameter":{"@class":"com.nimbusds.oauth2.sdk.id.State","value":"561f9c172a"}},"prefix":"TST"}',
'2024-04-03 15:15:44.23861+00', NULL, '',
'org.apereo.cas.ticket.TransientSessionTicketImpl', 'TST-xxxxxxx') was
aborted: ERROR: duplicate key value violates unique constraint
"postgres_jpa_ticket_entity_pkey"
Detail: Key (id)=(TST-xxxxxxx) already exists. Call getNextException to
see other errors in the batch.
ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (default task-76)
ERROR: duplicate key value violates unique constraint
"postgres_jpa_ticket_entity_pkey"
Detail: Key (id)=(TST-xxxxxxx) already exists.
-psv
On Saturday, March 30, 2024 at 12:46:24 PM UTC-5 Petr Bodnár wrote:
> Hi Pablo,
>
> I should have probably added that I haven't tested the proposed solutions
> yet. From what I've studied so far, I expected that commenting out just the
> call to *removeCookie()* should work.
>
> Or is it so, that as you mention in the other thread
> <https://groups.google.com/a/apereo.org/g/cas-user/c/QWRAFfqFwqY/m/_wfCtFD9AQAJ>,
>
> you had to comment out even the call to the whole
> *clearTicketGrantingCookieFromContex()*? I would guess *that* could
> possibly cause the "tgt primary key constraint violation" you write about
> (in the case of obtaining an expired TGC). But yes, this is just guessing
> from me now...
>
> Petr
>
> On Wednesday 27 March 2024 at 19:13:25 UTC+1 Pablo Vidaurri wrote:
>
>> IPetr, you haven't seen any other issues with this work around? For my
>> users authenticatng via delegated azure ad I'm getting a cas client not
>> authorized error which is misleading because the issue in logs show a tgt
>> primary key constraint violation.
>>
>> -psv
>>
>> On Tuesday, March 26, 2024 at 11:40:57 AM UTC-7 Petr Bodnár wrote:
>>
>>> Hi all,
>>>
>>> thanks for the fruitful discussion. Some more fresh remarks to the topic:
>>>
>>> 1) The order of "Set-Cookie" response headers indeed depends on the
>>> server
>>>
>>> While *Tomcat *clearly uses deterministic, insertion-time order (see
>>> its Response.java
>>> <https://github.com/apache/tomcat/blob/510c71b009085f94122bc18501d1981322846540/java/org/apache/catalina/connector/Response.java#L880>),
>>>
>>> *JBoss*/*WildFly *for some weird reason stores cookies in a *TreeSet*,
>>> so their output order should be random (see its
>>> HttpServletResponseImpl.java
>>> <https://github.com/undertow-io/undertow/blob/ddb4aeeb32f7ed58d715124acf1d464fc14b30dd/servlet/src/main/java/io/undertow/servlet/spec/HttpServletResponseImpl.java#L112>
>>>
>>> and from there, HttpServerExchange.java
>>> <https://github.com/undertow-io/undertow/blob/ddb4aeeb32f7ed58d715124acf1d464fc14b30dd/core/src/main/java/io/undertow/server/HttpServerExchange.java#L1255>
>>> ).
>>>
>>> 2) Since version 6.4.0, CAS deletes TGC cookie more aggressively
>>>
>>> In https://github.com/apereo/cas/commit/02e9c27a6b60505, a new method
>>> *removeAll(request,
>>> response)* was added (and is called) that additionally removes the
>>> cookie only if it is present in the request.
>>>
>>> 3) Since version v7.0.0-RC2, CAS deletes TGC only when it is present in
>>> the request
>>>
>>> In https://github.com/apereo/cas/commit/9454b38b8d95d7, just the
>>> aforementioned new method *removeAll(request, response)* is used.
>>>
>>> 4) This issue doesn't affect just the delegated authentication, but also
>>> authentication via Kerberos (SPNEGO)
>>>
>>> The Kerberos authentication seems to be affected in the very same way,
>>> but possibly no one really noticed or cares, because the automatic login is
>>> practically invisible to the user.
>>>
>>> 5) Conclusion
>>>
>>> All that being said, it looks like removing the unconditional call to
>>> *ticketGrantingTicketCookieGenerator.removeCookie(response)
>>> *actually IS the correct solution. And leaving just the new call to
>>> *removeAll(request,
>>> response)* should be just fine - because this call should be effective
>>> only when being initially redirected to CAS login page with an invalid
>>> (e.g. expired) TGC cookie.
>>>
>>> Feel free to correct me.
>>>
>>> Regards
>>> Petr
>>>
>>> On Thursday 4 January 2024 at 04:39:17 UTC+1 Pablo Vidaurri wrote:
>>>
>>>> Ran into the same issue with v6.6.8 and v6.6.14. Also removed the line
>>>> in InitialFlowSetupAction.java that sets empty cookie and I get proper
>>>> session now. But this does not look like a correct fix.
>>>>
>>>> On Monday, January 11, 2021 at 4:00:17 PM UTC-6 Ulrich Mayring wrote:
>>>>
>>>>> Ray,
>>>>> thanks a lot for your comments. I believe this more or less settles
>>>>> the issue that we have a bug here, but it doesn't bite everyone. So I
>>>>> suppose those, who are unaffected, can just carry on.
>>>>>
>>>>> We have fixed the issue in our overlay by simply removing the code
>>>>> that sets the "empty" cookie. If you ever find that the order of cookies
>>>>> changes on you, you can do the same thing. Our test suite is green, so I
>>>>> guess that for our purposes this rather brute-force fix will work. I have
>>>>> no idea what it would take to fix this in CAS main, but I did notice that
>>>>> the code to remove a cookie was changed from using the Servlet API to a
>>>>> custom implementation, where the header is set manually. So perhaps going
>>>>> back to using the Servlet API (response.addCookie) would be enough.
>>>>>
>>>>> On Monday, 11 January 2021 at 17:25:28 UTC+1 Ray Bon wrote:
>>>>>
>>>>>> Ulrich,
>>>>>>
>>>>>> You are correct.
>>>>>> And I do receive the cookies with the expired cookie first.
>>>>>>
>>>>>> Ray
>>>>>>
>>>>>> On Sat, 2021-01-09 at 11:39 -0800, Ulrich Mayring wrote:
>>>>>>
>>>>>> Notice: This message was sent from outside the University of Victoria
>>>>>> email system. Please be cautious with links and sensitive information.
>>>>>>
>>>>>> Ray,
>>>>>> the section you refer to applies to the "Cookie" header the browser
>>>>>> sends back. However, I was talking about the "Set-Cookie" header sent by
>>>>>> the server. Its semantics are defined in section 4.1.2 of the RFC and it
>>>>>> clearly states that the server can delete a cookie by sending a
>>>>>> Set-Cookie
>>>>>> header with an expired date.
>>>>>>
>>>>>> What's more, RFC 6265 clearly states that the server SHOULD NOT
>>>>>> include more than one Set-Cookie header field in the same response with
>>>>>> the
>>>>>> same cookie-name. So CAS clearly is in violation of that. Most
>>>>>> user-agents
>>>>>> will probably react to that by accepting the last Set-Cookie header and
>>>>>> so
>>>>>> the order of those headers really matters.
>>>>>>
>>>>>> Therefore my question to you was whether you are receiving the
>>>>>> "Set-Cookie" headers in a different order than I am, because that would
>>>>>> explain why your browser processes them differently.
>>>>>>
>>>>>> Kind regards,
>>>>>> Ulrich
>>>>>> On Friday, 8 January 2021 at 21:01:44 UTC+1 Ray Bon wrote:
>>>>>>
>>>>>> Ulrich,
>>>>>>
>>>>>> According to, https://tools.ietf.org/html/rfc6265, in particular
>>>>>> 4.2.2, the order of cookies in the header should not matter.
>>>>>> Is it possible that the app server is setting/modifying the order?
>>>>>> I am using tomcat 9.
>>>>>>
>>>>>> Ray
>>>>>>
>>>>>> On Fri, 2021-01-08 at 10:01 -0800, Ulrich Mayring wrote:
>>>>>>
>>>>>> Notice: This message was sent from outside the University of Victoria
>>>>>> email system. Please be cautious with links and sensitive information.
>>>>>>
>>>>>> Different workflow here. I access my application and it redirects to
>>>>>> the CAS Login Page. On the CAS Login Page I can choose whether to log in
>>>>>> directly (via CAS protocol) or externally (via Azure). To that end there
>>>>>> is
>>>>>> a button that will take me to the Azure login page.
>>>>>>
>>>>>> However, my browser will also have seen the "empty" cookie, since I'm
>>>>>> passing through the CAS login page. But I don't think that can have any
>>>>>> effect - what difference should it make to the browser, whether a cookie
>>>>>> has been seen before? Have you checked in which order you receive the
>>>>>> two
>>>>>> cookies? Perhaps the "empty" cookie comes first in your case, so it is
>>>>>> then
>>>>>> overwritten by the "full" cookie?
>>>>>>
>>>>>> My cookie is also named TGC-1.2.3, I'm using the CAS default as well.
>>>>>>
>>>>>> cheers,
>>>>>> Ulrich
>>>>>>
>>>>>> On Friday, 8 January 2021 at 18:29:19 UTC+1 Ray Bon wrote:
>>>>>>
>>>>>> Ulrich,
>>>>>>
>>>>>> Same versions of chrome and firefox on linux.
>>>>>> When I use delegated auth to azure, I first pass through the cas log
>>>>>> in page and it redirects to azure. Thus my browser has already 'seen'
>>>>>> the
>>>>>> empty TGC.
>>>>>> Is this your flow, or do you go to azure first?
>>>>>>
>>>>>> Also, does your TGC have a suffix, '-1.2.3'?
>>>>>> I am using the default cas setting that has no suffix, the cookie
>>>>>> label is 'TGC'. This should not matter, but stranger things have
>>>>>> happened.
>>>>>>
>>>>>> Ray
>>>>>>
>>>>>> On Fri, 2021-01-08 at 01:21 -0800, Ulrich Mayring wrote:
>>>>>>
>>>>>> Notice: This message was sent from outside the University of Victoria
>>>>>> email system. Please be cautious with links and sensitive information.
>>>>>>
>>>>>> I have tested this with Firefox 84 and Chrome 87.0.4280.88 and in
>>>>>> both cases no cookie is sent with the next request, thus failing to
>>>>>> login
>>>>>> the user.
>>>>>>
>>>>>> As far as I understand, the server is allowed to send multiple
>>>>>> "Set-Cookie" headers with different values. The client (browser),
>>>>>> however,
>>>>>> is only allowed to send one "Cookie" header back. He can concatenate the
>>>>>> multiple values into that one field, though. But it appears that in my
>>>>>> case
>>>>>> the browser looks at the two Set-Cookie headers seperately. The first
>>>>>> one
>>>>>> is accepted as a new cookie, but the second one without a value is
>>>>>> apparently interpreted as "delete this cookie". Thus no cookie is sent
>>>>>> with
>>>>>> the next request.
>>>>>>
>>>>>> If I understand you correctly, then in your case the browser is
>>>>>> sending the correct TGC-Cookie, even though you also receive the two
>>>>>> Set-Cookie headers?
>>>>>>
>>>>>> Kind regards,
>>>>>> Ulrich
>>>>>> On Thursday, 7 January 2021 at 19:22:14 UTC+1 Ray Bon wrote:
>>>>>>
>>>>>> Ulrich,
>>>>>>
>>>>>> I see the two TGCs on return from azure. I can not tell which arrived
>>>>>> first, but the stored TGC does have a value, and subsequent login does
>>>>>> send
>>>>>> this value.
>>>>>> Could this be related to browser behaviour?
>>>>>>
>>>>>> I tested in firefox and chrome. The empty cookie has Expires=1970...
>>>>>> and Max-Age=0; the one with a value has no Max-Age and no Expires but
>>>>>> does
>>>>>> have a SameSite.
>>>>>>
>>>>>> Ray
>>>>>>
>>>>>> On Thu, 2021-01-07 at 05:00 -0800, Ulrich Mayring wrote:
>>>>>>
>>>>>> Notice: This message was sent from outside the University of Victoria
>>>>>> email system. Please be cautious with links and sensitive information.
>>>>>>
>>>>>>
>>>>>> Before posting a bug report I'd like to hear your opinions - perhaps
>>>>>> I'm on the wrong page.
>>>>>>
>>>>>> When authenticating with an application that uses CAS, the first
>>>>>> thing that happens is that the CAS login form appears. Before that form
>>>>>> is
>>>>>> sent to the browser, CAS is internally trying to delete any TGC-Cookies
>>>>>> that might exist.
>>>>>>
>>>>>> This happens in line 95 of this class:
>>>>>> https://github.com/apereo/cas/blob/6.2.x/support/cas-server-support-actions/src/main/java/org/apereo/cas/web/flow/login/InitialFlowSetupAction.java
>>>>>>
>>>>>> The result is that the following header is sent to the browser (JSON
>>>>>> notation as copied from the Firefox Dev Tools):
>>>>>>
>>>>>> "name": "set-cookie",
>>>>>> "value": "TGC-1.2.3=\"\"; Version=1; Path=/mycas/; Secure; HttpOnly;
>>>>>> Max-Age=0; Expires=Thu, 01-Jan-1970 00:00:00 GMT; Comment=\"CAS Cookie\""
>>>>>>
>>>>>> The reason for that "empty" cookie is probably that the only way to
>>>>>> delete a cookie as per the Servlet API is to set a new one with an empty
>>>>>> value. Apparently CAS is trying to do that here. It doesn't matter much,
>>>>>> because we are talking only about the login page, but this becomes
>>>>>> important later on.
>>>>>>
>>>>>> When I login via CAS protocol, i.e . POSTing my credentials to
>>>>>> https://cas-server/mycas/login?locale=de
>>>>>> <https://172.16.16.16:8443/ooscas/login?locale=de> I'll get back a
>>>>>> proper TGC cookie and am authenticated:
>>>>>>
>>>>>> "name": "set-cookie",
>>>>>> "value": "TGC-1.2.3=eyJhbG...; Path=/mycas/; SameSite=None; Secure;
>>>>>> HttpOnly"
>>>>>>
>>>>>> However, when I do the same thing via external authentication (Azure
>>>>>> OpenID Connect), I am entering the OAuth2 Authorization Code flow and
>>>>>> arrive at POSTing to the URL
>>>>>> https://cas-server/mycas/login?code=0.ATAAHe5... - in other words, I
>>>>>> am not sending my credentials, but an Authorization Code I have obtained
>>>>>> from Azure. Upon POSTing to that URL I am getting both of the
>>>>>> above-mentioned headers back.
>>>>>>
>>>>>> So the browser is getting the "full" TGC-Cookie and an "empty" one.
>>>>>> Because the "empty" one arrives last, the browser sends it for its next
>>>>>> request and obviously authentication fails at that point.
>>>>>>
>>>>>> I have debugged into the CAS code and found that the above-mentioned
>>>>>> code in line 95 of InitialFlowSetupAction is called again during
>>>>>> authentication, which results in the extra "empty" header.
>>>>>>
>>>>>> Bottom line: the TGC cookie is not removed properly, resulting in two
>>>>>> "set-cookie" headers. But this only breaks external authentication. When
>>>>>> authenticating directly with CAS the cookie removal code is not called
>>>>>> during authentication and thus we only have one "set-cookie" header.
>>>>>>
>>>>>> I have noted that the code to remove cookies was changed between CAS
>>>>>> 5.3 (where this issue does not exist) to CAS 6.2. So what do you think?
>>>>>> Is
>>>>>> this a bug or do I misunderstand something about cookie handling or CAS?
>>>>>>
>>>>>> --
>>>>>>
>>>>>>
>>>>>> Ray Bon
>>>>>> Programmer Analyst
>>>>>> Development Services, University Systems
>>>>>> 2507218831 <(250)%20721-8831> | CLE 019 | [email protected]
>>>>>>
>>>>>> I respectfully acknowledge that my place of work is located within
>>>>>> the ancestral, traditional and unceded territory of the Songhees,
>>>>>> Esquimalt
>>>>>> and WSÁNEĆ Nations.
>>>>>>
>>>>>> --
>>>>>>
>>>>>>
>>>>>> Ray Bon
>>>>>> Programmer Analyst
>>>>>> Development Services, University Systems
>>>>>> 2507218831 <(250)%20721-8831> | CLE 019 | [email protected]
>>>>>>
>>>>>> I respectfully acknowledge that my place of work is located within
>>>>>> the ancestral, traditional and unceded territory of the Songhees,
>>>>>> Esquimalt
>>>>>> and WSÁNEĆ Nations.
>>>>>>
>>>>>> --
>>>>>>
>>>>>>
>>>>>> Ray Bon
>>>>>> Programmer Analyst
>>>>>> Development Services, University Systems
>>>>>> 2507218831 <(250)%20721-8831> | CLE 019 | [email protected]
>>>>>>
>>>>>> I respectfully acknowledge that my place of work is located within
>>>>>> the ancestral, traditional and unceded territory of the Songhees,
>>>>>> Esquimalt
>>>>>> and WSÁNEĆ Nations.
>>>>>>
>>>>>> --
>>>>>>
>>>>>> Ray Bon
>>>>>> Programmer Analyst
>>>>>> Development Services, University Systems
>>>>>> 2507218831 <(250)%20721-8831> | CLE 019 | [email protected]
>>>>>>
>>>>>> I respectfully acknowledge that my place of work is located within
>>>>>> the ancestral, traditional and unceded territory of the Songhees,
>>>>>> Esquimalt
>>>>>> and WSÁNEĆ Nations.
>>>>>>
>>>>>
--
- Website: https://apereo.github.io/cas
- Gitter Chatroom: https://gitter.im/apereo/cas
- List Guidelines: https://goo.gl/1VRrw7
- Contributions: https://goo.gl/mh7qDG
---
You received this message because you are subscribed to the Google Groups "CAS
Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/a/apereo.org/d/msgid/cas-user/6d5e525d-3eca-4cc4-aced-678c8979d227n%40apereo.org.