Dominic Cronin's weblog
Discovering content delivery environment capabilities... on Tridion practice
I recently wrote a script to query the capabilities of a Tridion content delivery environment. Rather than post it here, I've put it up on Tridion Practice. After all, it's about time "practice" got a bit of love. I think I'll try to get a bit more fresh material up there soon.
I hope you'll find the script useful. Dare I also hope that some of you might be inspired to contribute something to Tridion Practice? It's always been the intention that we'd try to get contributions from a range of practitioners, so please feel welcome. Cookbook recipes are probably the most prominent part of the site, but the patterns and practices sections are also interesting. Come on down!
Peering behind the veil of Tridion's discovery service
Many of us have configured applications that use Tridion's discovery service to find the various other content delivery services. All these services can be secured using oAuth, and the discovery service itself is no exception. It's almost a rite of passage to point a browser at the discovery endpoint only to see something like this:
In order to be allowed to use the discovery service, you need to provide an Authorization header when you call it, and otherwise, the "invalid_grant" error is what you get. Some of you may remember a blog post of mine from a few years ago where I showed how to call the content service with such a header. The essense of this was that first you call the token service with some credentials, and it hands you back a token that you can use in your authorization header.
That was when Web 8 was new, and I remember wondering, given that you only need to provide a discovery endpoint, how you could arrive at the location of the token service in order to get a token in the first place. I've seen enough code in the intervening period that takes a very pragmatic line and just assumes that the token service is to be found by taking the URL of the discovery service and replacing "discovery.svc" with "token.svc". That works, but it's somehow unsatisfactory. Wasn't the whole point of these service architectures that things should be discoverable and self-describing. Back then I'm fairly sure, after a cursory glance at https://www.odata.org/, I tried looking for the $metadata properties, but with the discovery service that just gets you an invalid grant.
I recently started looking at this stuff again, and somehow stumbled on how to make it work. (For the life of me, I can't remember what I was doing - maybe it's even documented somewhere.) It turns out that if you call the discovery service like this:
http://cd.local:9082/discovery.svc/TokenServiceCapabilities
it doesn't give you an invalid grant. Instead it gives you an oData response like this:
<?xml version="1.0" encoding="UTF-8"?>
<feed
xmlns:metadata="http://docs.oasis-open.org/odata/ns/metadata"
xmlns:data="http://docs.oasis-open.org/odata/ns/data"
xmlns="http://www.w3.org/2005/Atom" metadata:context="http://cd.local:9082/discovery.svc/$metadata#TokenServiceCapabilities" xml:base="http://cd.local:9082/discovery.svc">
<id>http://cd.local:9082/discovery.svc/TokenServiceCapabilities</id>
<title></title>
<updated>2019-09-04T19:28:36.916Z</updated>
<link rel="self" title="TokenServiceCapabilities" href="TokenServiceCapabilities"></link>
<entry>
<id>http://cd.local:9082/discovery.svc/TokenServiceCapabilities('DefaultTokenService')</id>
<title></title>
<summary></summary>
<updated>2019-09-04T19:28:36.916Z</updated>
<author>
<name>SDL OData v4 framework</name>
</author>
<link rel="edit" title="TokenServiceCapability" href="TokenServiceCapabilities('DefaultTokenService')"></link>
<link rel="http://docs.oasis-open.org/odata/ns/related/Environment" type="application/atom+xml;type=entry" title="Environment" href="TokenServiceCapabilities('DefaultTokenService')/Environment"></link>
<link rel="http://docs.oasis-open.org/odata/ns/relatedlinks/Environment" type="application/xml" title="Environment" href="TokenServiceCapabilities('DefaultTokenService')/Environment/$ref"></link>
<category scheme="http://docs.oasis-open.org/odata/ns/scheme" term="#Tridion.WebDelivery.Platform.TokenServiceCapability"></category>
<content type="application/xml">
<metadata:properties>
<data:id>DefaultTokenService</data:id>
<data:LastUpdateTime metadata:type="Int64">1566417662739</data:LastUpdateTime>
<data:URI>http://cd.local:9082/token.svc</data:URI>
</metadata:properties>
</content>
</entry>
</feed>
Looking at this, you can just reach into the "content" payload and read out the URL of the token service. So that explains the mystery, even if the possibility of doing a replace on the discovery service URL also counts as sufficient to render it unmysterious.
Anyway - who knew? I certainly didn't. Is this a better or more correct way of getting to the token service? I really don't know. Answers on a postcard?