@Transactional(readOnly = false)
public Assertion validateServiceTicket(final String serviceTicketId, final Service service) throws TicketException {
Assert.notNull(serviceTicketId, "serviceTicketId cannot be null");
Assert.notNull(service, "service cannot be null");
final ServiceTicket serviceTicket = (ServiceTicket) this.serviceTicketRegistry.getTicket(serviceTicketId, ServiceTicket.class);
final RegisteredService registeredService = this.servicesManager.findServiceBy(service);
if (registeredService == null || !registeredService.isEnabled()) {
log.warn("ServiceManagement: Service does not exist is not enabled, and thus not allowed to validate tickets. Service: [" + service.getId() + "]");
throw new UnauthorizedServiceException("Service not allowed to validate tickets.");
}
if (serviceTicket == null) {
log.info("ServiceTicket [" + serviceTicketId + "] does not exist.");
throw new InvalidTicketException();
}
try {
synchronized (serviceTicket) {
if (serviceTicket.isExpired()) {
log.info("ServiceTicket [" + serviceTicketId + "] has expired.");
throw new InvalidTicketException();
}
if (!serviceTicket.isValidFor(service)) {
log.error("ServiceTicket [" + serviceTicketId + "] with service [" + serviceTicket.getService().getId() + " does not match supplied service [" + service + "]");
throw new TicketValidationException(serviceTicket.getService());
}
}
final int authenticationChainSize = serviceTicket
.getGrantingTicket().getChainedAuthentications().size();
final Authentication authentication = serviceTicket
.getGrantingTicket().getChainedAuthentications().get(
authenticationChainSize - 1);
final Principal principal = authentication.getPrincipal();
final String principalId = registeredService.isAnonymousAccess()
? this.persistentIdGenerator.generate(principal, serviceTicket
.getService()) : principal.getId();
final Authentication authToUse;
if (!registeredService.isIgnoreAttributes()) {
final Map<String, Object> attributes = new HashMap<String, Object>();
for (final String attribute : registeredService
.getAllowedAttributes()) {
final Object value = principal.getAttributes().get(
attribute);
if (value != null) {
attributes.put(attribute, value);
}
}
final Principal modifiedPrincipal = new SimplePrincipal(
principalId, attributes);
final MutableAuthentication mutableAuthentication = new MutableAuthentication(
modifiedPrincipal, authentication.getAuthenticatedDate());
mutableAuthentication.getAttributes().putAll(
authentication.getAttributes());
mutableAuthentication.getAuthenticatedDate().setTime(
authentication.getAuthenticatedDate().getTime());
authToUse = mutableAuthentication;
} else {
authToUse = authentication;
}
final List<Authentication> authentications = new ArrayList<Authentication>();
for (int i = 0; i < authenticationChainSize - 1; i++) {
authentications.add(serviceTicket.getGrantingTicket().getChainedAuthentications().get(i));
}
authentications.add(authToUse);
return new ImmutableAssertionImpl(authentications, serviceTicket.getService(), serviceTicket.isFromNewLogin());
} finally {
if (serviceTicket.isExpired()) {
this.serviceTicketRegistry.deleteTicket(serviceTicketId);
}
}
}