Alternative solution for "401: Unauthorized" in Grafana iframe card

Many users are getting the “401: Unauthorized” error when embedding Grafana into an iframe card.

The community suggests adding GF_AUTH_ANONYMOUS_ENABLED or GF_SECURITY_ALLOW_EMBEDDING to Grafana configration, but this did not solve the problem in my environment.

Finally, I found another solution and I’ll share it with the community.
In my environment, I use Nginx Proxy Manager, Let’s Encrypt, Google Cloud DNS, and Home Assistant OS, but I think this method will work for other DNS services and reverse proxy based environments.

Create Proxy Host for Grafana

  1. Create a proxy host that supports Grafana’s port

  2. Set the letsencrypt SSL Certificate.

  3. You will see the following screen.

    • Home Assistant: port 8123
    • Grafana: port 3000.

Configure Grafana

Open the Grafana settings page in Supervisor and configure the ports. (no need to change Option)

Create a view only user

  1. Open “Grafana Web UI > Configuration > Users”

  2. Click “Invite” and create a new user

  3. Click “Submit”

  4. Click “Pending Invites”, then “Copy Invite”

    The invitation code of the clipboard should look like this.
    http://localhost:3000/api/hassio_ingress/xxxxxx-yyyyyy/invite/zzzzzzz
    Change “htt://localhost:3000” to the domain you assigned. (Don’t forget to change http to https)
    https://grafana.your-domain.tld/api/hassio_ingress/xxxxxx-yyyyyy/invite/zzzzzzz

  5. Access the modified invitation URL and enter your username and password to create a user.

Configure an iframe card

  1. Set the ingress url for the iframe card with the Grafana url, not the Home Assistant url.
- type: iframe
  url: >-
    https://grafana.your-domain.tld/api/hassio_ingress/xxxxxx-xxxxxx/d/xxxx-xxxx/sensor-monitor?orgId=1&from=now-24h&to=now&fullscreen&kiosk=1&refresh=30s
  aspect_ratio: 200%
  1. When you access the Loverace dashboard with the iframe card, you will see the Grafana login page and login with the viewer account you created.

  2. Now you can access Grafana embedded in the iframe card.

5 Likes

Thank you for taking the time to explain this process in detail!
Did you manage to change the default admin password, or did you just delete that user? (as it doesn’t appear in the screenshots). Cheers!

I have not made any changes to the admin account, just removed it from the screenshot.

Hello @kojirof i have tested your solution but the link is ok with direct link but not with iframe .
The page still request username and password…
The login is work but the page return on login screen.
How to fix this issue??
Regards

It does not solve it for me. I honestly do not know why your approach would change anything. I am using Homa Assistant on my domain, hosted on my synology NAS. The only difference is that I created another subdomain for grafana. The result is understandably the same. 401 unauthorized. There should be some configuration in grafana itself.

401 is because of cross-site scripting. Not allowing to render within another site

Change your NPM for the proxy host to remove the headers. By setting a custom location and configuration

I have grafana on my subdomain and running on port 3000 as everybody around try as well. I use reverse proxy on my synology nas to point to that domain, to be out of home assistant. I do not get 401 but just a white blank window now.

Well set your proxy on the Synology to drop x-frame-options header. And you won’t have a problem rendering an iframe of that fqdn on a other fqdn

Can you be more precise how can I do that? Here?

Interestingly, I cannot embedd the link to iframe in HA when I use https://192.168.2.xx:3000/ but if I use https://grafana.mydomain.com/. it can embed but still with the error.

You’ll have to look up the Synology container you are using for proxy and follow the documentation.

I use the Nginx Proxy Manager add-on which I’ve described above. I could tell you how to do it on. Apache or Tomcat as well. But Synology isn’t something I use.

X-frame-options however is used by every modern browser, and where your issue lies trying to render another fqdn site within an fqdn. So it is solvable… I just don’t know Synology reverse proxy

That is normal. IP addresses are not fully qualified domain names. So they render fine.

Most public sites facing the world use fqdn not IP, and all modern browsers block cross-site scripting so that people can’t render someone else’s site inside of theirs say fake rendering objects from a bank login page on your fake site.

You’ll need to drop the x-frame-options header between your proxy and backend to render the iframe across a fqdn

You apparently know the theory. Synology proxy just have this dialog and the one for some advanced configuration I showed you above, nothing else.

What does it mean to “drop a header”? Can I achieve it in the previous dialog? Thanks!

Go-to custom headers tab…what’s that show when you click create?

In the config shot I showed of NPM

proxy_hide_header X-Frame-Options;

If I understand you correctly, it should look like this. But there’s no change for me. Still white blank window.

There is another way to solve this problem. It works for me, but it doesn’t work when I’m connected over nabu casa.
I’m using ssl cert and nginx but just for local connection. For remote connection I use nabu casa.
In grafana I use port 8182. I have also some env variables but I don’t think it’s related to this. But this is it

- name: GF_AUTH_ANONYMOUS_ENABLED
  value: "true"
- name: GF_DASHBOARDS_MIN_REFRESH_INTERVAL
  value: 30s
- name: GF_DATE_FORMATS_INTERVAL_HOUR
  value: DD/MM HH:mm
- name: GF_DATE_FORMATS_INTERVAL_DAY
  value: DD/MM

I use also ssl.
I can access grafana on my https://my_domain:8182
For iframe card I’m using
https://my_host:8182/some_link&refresh=10s&kiosk

You can use NPM for remote access to HA

Then you only open 80 and 443, 80 to rewrite to 443.

Then you won’t need to port forward other ports like you do for graphana

Use Adguard or other dns server and make dns rewrites so

  • create your external dns record

  • create NPM proxy host yourdomain → your host:8182

  • in Adguard or local dns, make a dns rewrite so the dns rewrite points to NPM https://graphana.yourdomain → NPM internal IP address

Now when you are on your home network or out in the world you can use the same URL which also means your iframe will render wherever too. Ie you don’t need two separate iframe entries for external vs internal url

What is NPM?
I run PiHole here so this might be an option.

PiHole can do dns rewrites for you. So you can do dns rewrites with it.

NPM, Nginx Proxy Manager in the community add-on store

It’s an all in one add on for proxy management and certificate renewal through letsencrypt… the proxy serves the SSL and auto renews, so you don’t have to generate certificates and manually add them to the configuration of every add on you’d like to serve over ssl