ADAL within a Datasource Plugin

Hello all. I’m a long term .net developer.
I am building my first Datasource plugin for Grafana…so far I can get my plugin in and see the config and query editor.
Now exploring how to authenticate against the datasource with is using ADAL.

Normally I would just do this in .Net:

HttpClient client = HttpClientFactory.Create(new WebRequestHandler(),
new AuthenticationHandler(resource, tenant, aadFormat, appId, appKey));
client.BaseAddress = new Uri(address);

I need the equivalent in Angular so that I can make the same API calls.

I’ve seen the adal.js and adal-angular.js files from Microsoft, that I have seen integrated in a pure web app for angular. However, how would I use the same in a Plugin for Grafana?

Has anyone done this before?

Thanks in advance.

Don’t know too much about ADAL but here is how I did it for the Azure Monitor data source plugin (no JavaScript involved):

This defines a route in the plugin.json, “azuremonitor”, when this route is activated then it gets a token using the tenantId, the client id and client secret from the data source config. Grafana will automatically fetch a new token when it expires. The user has to choose proxy mode in the data source config for this to work.

Thanks.
Doesn’t seem to work for me, likely I have something mis-configured.

I have ticked proxy for the http settings.
What URL do I enter in the http seeting, the backend data store that I am trying to access?

I keep getting a 401 no matter the combinations I’ve tried.

Your path says “azuremonitor”, is that detected when you the URL is {grafana_server}/azuremonitor… ?

This is a very new feature that we haven’t documented yet (so I will do that in the next week or two).

The grafana backend will try and match a proxy route with “azuremonitor”:. A proxy url looks like this:

http://localhost:3000/api/datasources/proxy/72/azuremonitor/subscriptions/9935389e-9122-4ef.....

Grafana will strip off http://localhost:3000/api/datasources/proxy/72/azuremonitor and add in https://management.azure.com from the url field and send the request on to:

https://management.azure.com/subscriptions/9935389e-9122-4ef.....

At the same time, it will fetch a token from https://login.microsoftonline.com.

This is what the config page looks like and it is these values (tenantId, clientId etc.) that are used in the route spec in the plugin.json file:

Thanks for you help.
How do I set up the data source as a proxy route then? Excuse my lack of knowledge.

I though setting the URL and setting the type to “Proxy” was how but I don’t see those options in your data source configuration?

For the Azure Monitor plugin, it is hardcoded to Proxy. Direct does not make sense for a cloud service. So you are on the right track.

Got it working (at last). Now behaving as I was expecting.
Thanks for your help!

1 Like

I have everything working as expected now except for the configuration.

If I add this to plugin.json

    "tokenAuth": {
        "url": "https://login.windows.net/{{.JsonData.tenant}}/oauth2/token",

Then the {{.JsonData.tenant}} is not being resolved, it is taken as the literal string.
Is there a setting that needs to be enabled to allow this to resolve?

Everything works hardcoded so this is the last piece of the puzzle.

I updated to v4.6.0 and that has fixed the issue.

1 Like

Oh, sorry. Forgot to say that this is a totally new feature that we built for the Azure plugin and that you needed 4.6.

Is it possible for the url to be dynamic from configuration? It doesn’t appear to be working.

“routes”: [{
“path”: “mycustompath”,
“method”: “GET”,
“url”: “https://{{ .JsonData.customUrl }}”,
“tokenAuth”: {
“url”: “https://login.windows.net/{{ .JsonData.tenant }}/oauth2/token”,
“params”: {
“grant_type”: “client_credentials”,
“client_id”: “{{ .JsonData.applicationid }}”,
“client_secret”: “{{ .JsonData.applicationkey }}”,
“resource”: “{{ .JsonData.resource }}”
}
}

No, my first thought is that could be a security hole. We don’t want frontend code interfering here.

You could have multiple routes and switch between those on the frontend.

Hi @daniellee, i want to setup grafana azure monitor plugin on Azure Stack environemt, so i modify some code, but it does’t work, so how can i add azuerstack route?

Error Log:
angular.js:12837 GET angular.js:12837 GET http://localhost:3000/api/datasources/proxy/4/azurestack/subscriptions/84c670db-eab5-466e-9b96-9b2c3ed9c7f5/resourceGroups?api-version=2018-01-01 502 (Bad Gateway)

@antmtn hard to say with so little detail.