Both support ticket replication:
ehcache: https://wiki.jasig.org/display/CASUM/EhcacheTicketRegistry
Hazelcast*:
https://github.com/Unicon/cas-addons/wiki/Configuring-HazelcastTicketRegistry

*This is an add-on project that Unicon maintains. It might be worth
mentioning that the ehcache inventor is now Hazelcast's CEO.

On 7/29/14, 10:38 AM, Nick Sayer wrote:
> 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
>>
>

-- 
*John Gasper*
IAM Consultant
Unicon, Inc.
PGP/GPG Key: 0xbafee3ef

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