ServiceMatchingStrategy based on serviceId match instead of exact URL match

24 views
Skip to first unread message

Brent Smith

unread,
Apr 16, 2020, 9:08:49 AM4/16/20
to CAS Community
Hi, 

I see the DefaultServiceMatchingStrategy class does a case-insensitive exact match on the service URL passed in.  But couldn't it just call serviceManager.findServiceBy() for both URLs and then compare the resulting RegisteredService objects?

Or is there a problem with this that I'm not seeing?  Thanks!


/**
* This version of the service matching strategy matches on the serviceId regex, instead of exact matching
*/
@Slf4j
@RequiredArgsConstructor
@Getter
public class ServiceManagerServiceMatchingStrategy implements ServiceMatchingStrategy {
private final ServicesManager servicesManager;

@Override
public boolean matches(final Service service, final Service serviceToMatch) {
try {
val thisUrl = URLDecoder.decode(service.getId(), StandardCharsets.UTF_8.name());
val serviceUrl = URLDecoder.decode(serviceToMatch.getId(), StandardCharsets.UTF_8.name());

val thisUrlService = servicesManager.findServiceBy(thisUrl);
val serviceUrlService = servicesManager.findServiceBy(serviceUrl);

LOGGER.trace("Decoded urls and comparing [{}] with [{}]", thisUrl, serviceUrl);
return thisUrlService!=null && serviceUrlService!=null && thisUrlService.compareTo(serviceUrlService)==0;
} catch (final Exception e) {
LOGGER.error(e.getMessage(), e);
}
return false;
}
}

Ray Bon

unread,
Apr 16, 2020, 11:49:28 AM4/16/20
to cas-...@apereo.org
Brent,

I suppose that depends on what findServiceBy returns.
I suspect that most services are defined by a regex, so the comparison will depend on the first/best match. Or am I missing something about the job of serviceManager?

What is the problem you are trying to solve, or is it just interest?

Ray
-- 
Ray Bon
Programmer Analyst
Development Services, University Systems

I respectfully acknowledge that my place of work is located within the ancestral, traditional and unceded territory of the Songhees, Esquimalt and WSÁNEĆ Nations.

Brent Smith

unread,
Apr 16, 2020, 1:49:30 PM4/16/20
to CAS Community
Yes, findServiceBy will match against the serviceId regexes.  It does depend on each service having "non-overlapping" regexes, but I think this is a Service Registry requirement anyway.  

The issue I have is working with a set of services on machines in a load balanced cluster.  In addition to logging in to the services through a common, load-balanced URL (e.g. https://company.com/service), I want to be able to log in to each service on each machine by machine name (e.g. https://machine1/service).  The problem is the services aren't currently smart enough to dynamically determine their service path (using either machine name or common URL).  They always use the common URL.  

So I can initiate a load-balanced login with,


Or a machine-specific service login with,


but the service passed to the CAS ticket validation URL will always be


The problem is, CAS issues the service ticket tied to the value passed in to /cas/login.  Since the DefaultServiceMatchingStrategy does a case-insensitive string compare, the service ticket check fails when using the machine name service.


On the other hand, if I switch the ServiceMatchingStrategy to use ServicesManager.findServiceBy (serviceId), I can configure each serviceId regex in the Service Registry to have both paths (company.com|machine1).

This seems to work, but I was just wondering if there were any gotchas.  

Thanks!

-Brent Smith
Reply all
Reply to author
Forward
0 new messages