Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Embedding a Secured Grafana into Web Application

I want to embed Grafana into my web application using AngularJS. The goal is, when user is in my application, she should be able to click on a button and load the Grafana UI. In itself, this is an easy task. To do this, I have apache proxying Grafana and returning any necessary CORS headers. The apache reverse proxy config is as follows:

    Header always set Access-Control-Allow-Origin "*"
    Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
    Header always set Access-Control-Max-Age "1000"
    Header always set Access-Control-Allow-Headers "x-requested-with, Content-Type, origin, Authorization, accept, client-security-token"


    RewriteEngine on
    RewriteCond %{REQUEST_METHOD} OPTIONS
    RewriteRule ^(.*)$ $1 [R=200,L]
    RewriteCond %{REQUEST_METHOD} OPTIONS
    ProxyPass / http://localhost:3000/

All works perfectly fine when no security is involved. The following code is a simple HTML/Javascript that shows what I am doing:

<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="http://requirejs.org/docs/release/2.1.11/minified/require.js"></script>
<script src="https://code.jquery.com/jquery-1.11.3.js"></script>
<body >
<script>
    var app = angular.module('myApp', []);

    app.controller('MainCtrl', function ($scope, $http, $sce) {

    $scope.trustSrc = function(src) {
            console.log(src);
            return $sce.trustAsHtml(src);
    }

    $http({
            method : 'GET',
            url : 'http://grafana-host.com',

    }).success(function(response) {
            $("#test").attr('src', 'http://grafana-host.com')
            $("#test").contents().find('html').html(response);

    }).error(function(error) {
            console.log(error);
    });
});
</script>

<div ng-app="myApp" ng-controller="MainCtrl">

<iframe id="test" style="position: absolute; top: 50px; left: 0px; bottom: 0px; right: 0px; width: 100%; height: 100%; border: none; margin: 0; padding: 0; overflow: hidden;"></iframe>

The challenge now is that once logged in into my application, user should not have to log in into Grafana again.

To resolve this issue, I set up Grafana to use Basic Auth. My goal is for my web app to pass basic auth to Grafana via the browser. Basically, when the user clicks on the button to open Grafana, I would issue a request via AngularJS. This request would include the required Authorization header to load Grafana. To do this, I augment the above code segment with the http blog after the url field:

            headers : {
               'Authorization' : 'Basic YWRtaW46YWRtaW4='
            }

Also, in the success callback function, I replace the first instruction with:

  $("#test").attr('src',"data:text/html;charset=utf-8," + escape(response))

Unfortunately, I do not seem to be able to get this to work.

I know this should work because I can simulate this behavior with ModHeader extension of Chrome browser. If I put the following header in ModHeader: Authorization: Basic YWRtaW46YWRtaW4=, it loads Grafana from without need to log in. And if I remove the Authorization header, I am prompted for login name and password again.

The grafana changes are pretty simple:

[auth.basic]
enabled = true

What am I missing? My guess is this is an AngularJS/Javascript thing.

like image 646
Klaus Avatar asked Feb 23 '16 17:02

Klaus


People also ask

How do you integrate Grafana on the web app?

Login into Grafana dashboard and Select the dashboard which You want to embed. From the dashboard click on (Panel Title -> Share -> Embed). Copy the HTML code shown below. You can now go into your source code and paste the copied HTML code into your HTML page.

How do I share a Grafana dashboard link?

On the Grafana page, go to the dashboard that you want to share. icon. On the Link tab, you can obtain the dashboard sharing link. Quit Grafana's current account, access the link obtained in the previous step, and verify whether the link can be opened.


1 Answers

Don't know if this is an option at the time the question was written, but we're doing this quite successfully by injecting an API token for authorization (http://docs.grafana.org/http_api/auth/).

like image 91
Svet Avatar answered Sep 27 '22 23:09

Svet