How to use WebMapServiceImageryProvider or UrlTemplateImageryProvider with authentication token

1. A concise explanation of the problem you’re experiencing.

We are using WebMapServiceImageryProvider and UrlTemplateImageryProvider which point to Open-ID authenticated services. Therefore we need to include an authentication token to the request. That works fine until the token is not valid anymore (which is the case after a few minutes), Once that happens, we need to update the authentication information.

Now, it is possible to use a “Resource” and add an appropriate “retryCallback”. However, inside this callback it is not possible to persist the updated authentication information. Cesium always first tries the original information, causing a lot of network traffic, server load and log messages which all could be avoided.

  • What is the intended way to use authenticated imagery providers?

  • Is it possible to intercept (any manipulate) the HTTP request?

4. The Cesium version you’re using, your operating system and browser.

Currently 1.62.0

OS and browser version is irrelevant, Cesium shows the exact same behaviour everywhere …

I think the easiest way to handle this would be to create a custom Resource class that wraps some logic around the Resource calls. Cesium ion uses OAuth, and so all resources loaded from ion have the same flow, where a token is required, and a new token is needed when that expires. This is all handled by the IonResource class, so you can use it as kind of a template for implementing a class for your service:

https://github.com/AnalyticalGraphicsInc/cesium/blob/master/Source/Core/IonResource.js

Let me know if this helps.

Thanks for your reply. It helped to direct me to the right path :wink:

I ended up just patching the “fetch” function of the Resource class:

    /**
     * Patches the original Cesium.Resource class to allow updating of authorization header in HTTP requests.
     */
    private patchCesiumResource(): void {
        const orig = Cesium.Resource.prototype.fetch;

        // Store reference to the service, because "this" refers to the resource instance inside the patched function.
        const self = this;

        Cesium.Resource.prototype.fetch = function(callOptions: any) {
            if (this.headers.Authorization === 'system') {
                this.headers.Authorization = self.authentication;
            }

            return orig.call(this, callOptions);
        };
    }

``

(I’m developing an Angular app, so the above code is TypeScript)