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. -- 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