public Authentication authenticate(Authentication authentication) throws AuthenticationException {
   CasAuthentication casauth = (CasAuthentication) authentication;
   // If an existing CasAuthenticationToken, just check we created it
   if (casauth.isAuthenticated()) {
     if (key.hashCode() == casauth.getKeyHash()) {
       return authentication;
     } else {
       throw new BadCredentialsException("CasAuthenticationProvider.incorrectKey");
     }
   }
   // Ensure credentials are presented
   if (Strings.isEmpty(String.valueOf(casauth.getCredentials()))) {
     throw new BadCredentialsException("CasAuthenticationProvider.noServiceTicket");
   }
   boolean stateless = false;
   if (STATELESS_ID.equals(casauth.getPrincipal())) {
     stateless = true;
   }
   CasAuthentication result = null;
   // Try to obtain from cache
   if (stateless) {
     result = statelessTicketCache.get(casauth.getCredentials().toString());
   }
   if (result == null) {
     result = authenticateNow(casauth);
     result.setDetails(casauth.getDetails());
   }
   // Add to cache
   if (stateless) {
     statelessTicketCache.put(result);
   }
   return result;
 }
 private CasAuthentication authenticateNow(CasAuthentication auth) throws AuthenticationException {
   try {
     final Assertion assertion =
         ticketValidator.validate(auth.getCredentials().toString(), auth.getLoginUrl());
     String name = assertion.getPrincipal();
     final UserDetail userDetail = userDetailService.loadDetail(name);
     if (null == userDetail) {
       logger.error("cannot load {}'s detail from system", name);
       throw new UsernameNotFoundException(Strings.concat("user ", name, " not found in system"));
     }
     userDetailChecker.check(userDetail);
     return new CasAuthentication(
         key,
         userDetail,
         auth.getCredentials(),
         userDetail.getAuthorities(),
         userDetail,
         assertion);
   } catch (final TicketValidationException e) {
     throw new BadCredentialsException("Bad credentials :" + auth.getCredentials().toString(), e);
   }
 }