Grafana: How to auth via browser URL without enabling anonymous?

Created on 11 Sep 2015  ·  39Comments  ·  Source: grafana/grafana

First sorry for posting this prob really stupid Q...

Im spawning a browser from an inhouse application which should authenticate automatically via the browser URL to a dashboard but i cant get it to work with http://username:pass@grafanaserver/dash.......tried to pass an api key in the url aswell but cant figure it out (if it even should work?)

(the URL will reach a templated dashboard with repeat panels and will have the host as a variable from the inhouse app)

again,,sorry :)

Most helpful comment

+1 from Grafana.net user

The second use case is for our NOC screens. Having a /dashboard/db/demo?key=AAAA where the key is (or like) an API key to allow very simple views would be great.

All 39 comments

there is no url based auth :(

@torkelo ok if there is no plan for url based authentication, do you have idea how to share rendered image with some password/token so that it doesn't require login?

The use case where I would need the url based auth is that I would like to embed a graph to our monitoring email alert.

the snapshot sharing is exactly for this case :)

You can snapshot a single graph or whole dashboard, it will store the data in the panel and use can then use the snapshot to get a rendered png that is public
http://docs.grafana.org/reference/sharing/

No that doesn't work. I need a url what I can add to the email template what get updated when the email get sent. With snapshot sharing it store the current data :/

Same thing has happened to me had to scrap 3 months of work because i never managed to figure out how to extract the graphs into a pdf. Management want reports not browsing......Tried to install hubot but that was a total flop, my ubuntu crashed after i installed it, I am really over board with this.....

+1 from Grafana.net user

The second use case is for our NOC screens. Having a /dashboard/db/demo?key=AAAA where the key is (or like) an API key to allow very simple views would be great.

+1

+1

+1

I have the NOC screen usecase, too.

+1

+1

+1

Woo, Expectation of a closed ticket was this is working, but seems is simply closed to report that is not working without any statement this feature will be added or not.
We having 12 NOC screens as well and there is no way to get them authenticated somehow.

Anybody knows another solution?

+1

+1

+1

+1

This can be achieved with Grafana API keys + a browser extension that allows for Header insertion.
I use the Modify Header Value HTTP extension as this extension allows you to limit the header insertion to a certain domain.

  1. In Grafana, go to Configuration > API Keys
  2. Create a new key and note down the key
  3. In the Modify Header Value HTTP configuration, add a line:

    • URL: Grafana URL

    • Header Name: Authorization

    • Header Value: Bearer GRAFANA_API_KEY

I confirm this is more than needing, we are migrating from Datadog to Grafana/Prometheus and I was quite surprised of this limitation.
Typically on Datadog you can generate an unique, shareable URL for dashboard without authentication (For those NOC screens)

+1

+1

+1

+1

+1

+1

+2

+1 for a NOC screen not using auth. It's tedious having to log in manually to each one when they are reset or changed for any reason.

+1

+1

+1

+1

+1

👍

+1

+1

+1

+1
Anyone got a solution?

Here is my solution for iframe access by using auth proxy(https://grafana.com/docs/grafana/latest/auth/auth-proxy/#auth-proxy-authentication). Hope it will help someone.

The structure is Grafana Server(port:3000) + Nginx Auth Proxy(port:8088) + web auth service.
Here is the setting in grafana.ini.

#################################### Auth Proxy ##########################
[auth.proxy]
enabled = true
header_name = X-WEBAUTH-USER
header_property = username
auto_sign_up = true

Here is the setting in nginx.conf.

location / {
            set $cors "1";

            # OPTIONS indicates a CORS pre-flight request
            if ($request_method = 'OPTIONS') {
                set $cors "${cors}o";
            }

            # OPTIONS (pre-flight) request from allowed
            # CORS domain. return response directly
            if ($cors = "1o") {
                add_header 'Access-Control-Allow-Origin' '$http_origin' always;
                add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
                add_header 'Access-Control-Allow-Credentials' 'true' always;
                add_header 'Access-Control-Allow-Headers' 'Origin,Content-Type,Accept,Authorization,X-WEBAUTH-USER' always;
                add_header Content-Length 0;
                add_header Content-Type text/plain;
                return 204;
            }

            add_header Access-Control-Allow-Origin '*' always;
            add_header Access-Control-Allow-Credentials  true always;
            add_header Access-Control-Allow-Headers 'Origin,Content-Type,Accept,Authorization' always;


            #auth_basic "grafana";
            #auth_basic_user_file "/etc/nginx/htpasswd";

            auth_request     /auth;

            proxy_set_header X-WEBAUTH-USER "admin";
            proxy_set_header Authorization "";

            proxy_pass http://localhost:3000/;
        }

        location = /auth {
            internal;
            proxy_pass              http://test.org/auth; #The Auth request will send here. Return 2xx status code for success, and return 4xx for failure.
            proxy_pass_request_body off;
            proxy_set_header        Content-Length "";
            proxy_set_header        X-Original-URI $request_uri;
        }

Here is the web auth service

@GetMapping(value = "/auth", produces = "application/json;charset=UTF-8")
    @ResponseBody
    /* Auth should return 2xx ok. 4xx error. */
    public JSONObject auth(@RequestParam Map<String, String> paramMap, HttpServletRequest request) {
        if(checkHeaderAuth(request.getHeader("X-Original-URI"))){
            return new JSONObject();
        }
        throw new IllegalArgumentException("Error token");
    }

    private boolean checkHeaderAuth(String uri) {
        if(uri == null) {
            return false;
        }

        // filter the resource requests
        if(!uri.startsWith("/d-solo/")){
            LOG.info("auth header(skip):" + uri);
            return true;
        }
        LOG.info("auth header:" + uri);

        // get token and org
        String token = null;
        Long orgId = null;
        String paramString = uri.split("\\?")[1];
        String[] params = paramString.split("&");
        for(String param : params) {
            if(token == null && param.contains("token=")){
                token = param.split("token=")[1];
            }
            if(orgId == null && param.contains("orgId=")){
                orgId = Long.parseLong(param.split("orgId=")[1]);
            }
        }
        LOG.info("auth:" + token + " orgId:" + orgId);

        // use token and orgId to judge 
        ......
    }

When using the iframe way for embedding, we can add the token to the url, like http://test.org:8088/d-solo/123456/test?orgId=1&token=XXXXX.

But there are some shortcomings.

  1. All user are logged in with the system admin. I don't find a way to pass the username to the grafana server.
  2. Skip the authentication for all resource requests.
Was this page helpful?
0 / 5 - 0 ratings