On Jul 29, 2014, at 8:15 AM, John Gasper <jgas...@unicon.net> wrote:

> Hi Nick,
> 
> I apologize in advance for this non-answer, but the JPA Ticket Registry has 
> been plague with deadlock issues for some time. I'd recommend looking at 
> another ticket registry such as ehCache or Hazelcast as an alternative to 
> JPA. You should still be able to do what you are planning with either of 
> those.

Thanks. I did see that note on the 4.0.0 JPA ticket registry wiki page, but 
still thought fixing it might have been a shorter path forward. We went with 
JPA for the sake of HA. Are either of those an HA solution (that is, parallel 
load balanced CAS servers sharing the ticket registry)? Where are they 
documented?

> 
> John
> 
> On 7/28/14, 12:22 PM, Nick Sayer wrote:
>> We?re extending CAS 3.5.2.1 for our enterprise?s use. We?re using hibernate 
>> core 4.1.0.Final and validator 4.2.0.Final. One requirement is to allow 
>> installers to permit only a single TGT per user or permitting a single user 
>> to only persist TGTs that are associated with a single IP address.
>> 
>> For the most part, we?ve got this working, but what we run into in 
>> production are database deadlocks when these features are enabled.
>> 
>> The only difference of any consequence is this method:
>> 
>>     private void stripTickets(String id) {
>>         TicketGrantingTicket tgt = 
>> (TicketGrantingTicket)ticketRegistry.getTicket(id, 
>> TicketGrantingTicket.class);
>>         if (tgt == null)
>>                 throw new RuntimeException("Could not find freshly minted 
>> TGT - should never happen!");
>>         Authentication auth = tgt.getAuthentication();
>>         if (auth == null)
>>                 throw new RuntimeException("TGT has no authentication - 
>> should never happen!");
>>         Principal myPrincipal = auth.getPrincipal();
>>         if (myPrincipal == null)
>>                 throw new RuntimeException("TGT auth has no principal - 
>> should never happen!");
>>         InetAddress myAddr = 
>> (InetAddress)auth.getAttributes().get("InetAddress");
>>         if (myAddr == null) {
>>                 logger.warn("Newly minted TGT has no InetAddress.");
>>                 return;
>>         }
>>         logger.trace("About to go through the ticket registry to 
>> stripTickets");
>>         Collection<TicketGrantingTicket> toExpire = new 
>> ArrayList<TicketGrantingTicket>();
>>         for(Ticket ticket : this.ticketRegistry.getTickets()) {
>>                 logger.trace("Examining ticket " + ticket.toString());
>>                 if (!(ticket instanceof TicketGrantingTicket)) continue;
>>                 TicketGrantingTicket thisTGT = (TicketGrantingTicket)ticket;
>>                 if (thisTGT.equals(tgt)) continue; // Don't kill yourself!
>>                 auth = thisTGT.getAuthentication();
>>                 if (auth == null) {
>>                         logger.warn("TGT in registry has no 
>> authentication.");
>>                         continue;
>>                 }
>>                 Principal thisPrincipal = auth.getPrincipal();
>>                 InetAddress thisAddr = 
>> (InetAddress)auth.getAttributes().get("InetAddress");
>>                 if (myPrincipal.getId().equals(thisPrincipal.getId())) {
>>                         // It's the same user. Do we kill it?
>>                         if (singleSessionPerUser || 
>> !myAddr.equals(thisAddr)) {
>>                                 logger.info("Expiring TGT ID " + 
>> thisTGT.getId() + " for user " + thisPrincipal.getId() + " from IP " + 
>> thisAddr.toString());
>>                                 toExpire.add(thisTGT);
>>                         }
>>                 }
>>         }
>>         logger.trace("Now we've got a ticket expiration list with " + 
>> toExpire.size());
>>         for(TicketGrantingTicket ticket : toExpire) {
>>                 ticket.expire();
>>                 this.ticketRegistry.deleteTicket(ticket.getId());
>>         }
>>         System.err.println("Exiting the purge");
>>     }
>> 
>> 
>> So, in a nutshell, what we?re doing is iterating through 
>> this.ticketRegistry.getTickets() and selecting a list of tickets on which we 
>> wish to take action. Once we?re finished iterating, we go through the list 
>> of actionable tickets, expire each one and delete it from the registry.
>> 
>> Is this method fraught with peril? Is there anything we can do to attempt to 
>> prevent deadlocks? They seem to happen in testing even with a single user 
>> just logging in once after another in isolation - which seems awfully 
>> fragile to me.
>> 
>> 
>> 
>> 
>> 
> 
> -- 
> John Gasper
> IAM Consultant
> Unicon, Inc.
> PGP/GPG Key: 0xbafee3ef
> -- 
> You are currently subscribed to 
> cas-dev@lists.jasig.org
>  as: nsa...@silverspringnet.com
> To unsubscribe, change settings or access archives, see 
> http://www.ja-sig.org/wiki/display/JSG/cas-dev
> 


-- 
You are currently subscribed to cas-dev@lists.jasig.org as: 
arch...@mail-archive.com
To unsubscribe, change settings or access archives, see 
http://www.ja-sig.org/wiki/display/JSG/cas-dev

Reply via email to