Back on March 20, 2010 and April 22, 2010, Mihir Patel pointed out a problem
with ProxyGrantingTickets not being invalidated properly when the granting TGT
was expired. He then showed a solution that modified the isExpired method in
AbstractTicket.
After many years of using CAS at Simon Fraser University, we finally had a
project that will make heavy use of Proxy tickets, and almost immediately ran
into similar, but more extensive, problems with PGTs.
Part of the problem is similar to what Mihir found, but we ran into it from the
other side. We had the PGT expiring even though the PGT and granting TGT were
being kept alive. This problem was exactly the same as Mihir's, in that the
serialization of the PGT in the Cache (MemCache in our case) broke the link
with the granting TGT.
We found another problem as well, and I am not sure if it was a design decision
to have it work like it does, or an oversight. The problem is that if the PGT
is being actively used, but the granting TGT is not then the TGT will
eventually time out and render the PGT invalid. The application that has the
PGT has no way of keeping the TGT alive. It seems to me that when a PGT is used
to generate a PT, this should be registered as a use of the granting TGT as
well.
Because I didn't want to modify anything in the cas-server-core jar file, I
"fixed" the problem in our MemCacheTicketRegistry.java module (which we had
modified slightly anyway). I modified getTicket and updateTicket as you can see
below. I don't pretend that this is the "right" way to fix the problems, but
this is working for us. I think that the "right" solution is to not put the
granting ticket in a ticket, but to put the granting ticket ID there instead.
That way you would have to go back to the cache anytime you needed the granting
ticket (that would solve Mihir's problem, and half of our problem). The other
thing is to decide if changing the lastTimeUsed for a ticket should imply a
similar change for any granting ticket(s).
public Ticket getTicket(final String ticketId) {
final Ticket t = (Ticket) this.client.get(ticketId);
if (t == null) {
return null;
}
/*
* Because the ticket was reconstituted when it was retrieved
from
* the cache, so was the tickets parent, so the parent won't
match
* the cached version of the parent. To fix that, we retrieve
the
* parent now and replace the reconstituted version with that.
*/
AbstractTicket thisTicket = (AbstractTicket) t;
TicketGrantingTicketImpl grantingTicket =
(TicketGrantingTicketImpl) thisTicket.getGrantingTicket();
while (grantingTicket != null) {
TicketGrantingTicketImpl gtFromCache =
(TicketGrantingTicketImpl) this.client.get(grantingTicket.getId());
if (gtFromCache == null) return null;
try {
Field ticketGrantingTicketField =
AbstractTicket.class.getDeclaredField("ticketGrantingTicket");
ticketGrantingTicketField.setAccessible(true);
ticketGrantingTicketField.set(thisTicket
,gtFromCache);
} catch (Exception e) {
log.error("Unable to set ticketGrantingTicket
field.");
}
thisTicket = gtFromCache;
grantingTicket = (TicketGrantingTicketImpl)
gtFromCache.getGrantingTicket();
}
return getProxiedTicketInstance(t);
}
protected void updateTicket(final Ticket ticket) {
if (ticket instanceof AbstractTicket) {
long timeOut =
((AbstractTicket)ticket).getLastTimeUsed();
TicketGrantingTicketImpl grantingTicket =
(TicketGrantingTicketImpl) ticket.getGrantingTicket();
while (grantingTicket != null) {
try {
Field lastTimeUsedField =
AbstractTicket.class.getDeclaredField("lastTimeUsed");
lastTimeUsedField.setAccessible(true);
lastTimeUsedField.setLong(grantingTicket, timeOut);
handleSynchronousRequest(this.client.replace(grantingTicket.getId(),
this.tgtTimeout, grantingTicket));
} catch (Exception e) {
log.error("Unable to set lastTimeUsed
field.");
}
grantingTicket = (TicketGrantingTicketImpl)
grantingTicket.getGrantingTicket();
}
}
if (ticket instanceof TicketGrantingTicket) {
handleSynchronousRequest(this.client.replace(ticket.getId(), this.tgtTimeout,
ticket));
}
if (ticket instanceof ServiceTicket) {
handleSynchronousRequest(this.client.replace(ticket.getId(), this.stTimeout,
ticket));
}
}
--
Ray Davison
University Computing Services
Simon Fraser University
--
You are currently subscribed to [email protected] as:
[email protected]
To unsubscribe, change settings or access archives, see
http://www.ja-sig.org/wiki/display/JSG/cas-dev