Grafana: 通过令牌URL自动登录

创建于 2016-01-15  ·  95评论  ·  资料来源: grafana/grafana

自动登录通过网址传递用户令牌应该很好,这可能是将iframe嵌入网站的部分解决方案。

arebackenauth help wanted prioritimportant-longterm prioritunscheduled typfeature-request

最有用的评论

这对于与SaaS的互操作性非常重要。
我们拥有自己的身份验证和仪表板,我们希望能够将用户从仪表板传递到Grafana-类似于Heroku如何与New Relic和其他使用零密码的服务进行互操作。

当然,提供url + token身份验证方法也是一样的。
如果有人随后将其嵌入公共网站,则没有任何安全措施可以使该人免受其害。 那是他们的错。
为此,应该在文档/ UI中提供足够的警告。

如果没有此功能,则用户必须遇到第二个登录屏幕,在该屏幕上他们会迷惑要输入的用户名/密码。

这对我们来说是一个很大的障碍。

所有95条评论

因为任何人都可以看到令牌,所以这是非常不安全的,您可以创建可见数据的快照并将其嵌入,这样会更加安全

是的,但是使用快照您无权对其进行编辑,或者是否可以通过快照来编辑仪表板?

这对于与SaaS的互操作性非常重要。
我们拥有自己的身份验证和仪表板,我们希望能够将用户从仪表板传递到Grafana-类似于Heroku如何与New Relic和其他使用零密码的服务进行互操作。

当然,提供url + token身份验证方法也是一样的。
如果有人随后将其嵌入公共网站,则没有任何安全措施可以使该人免受其害。 那是他们的错。
为此,应该在文档/ UI中提供足够的警告。

如果没有此功能,则用户必须遇到第二个登录屏幕,在该屏幕上他们会迷惑要输入的用户名/密码。

这对我们来说是一个很大的障碍。

听起来像是Grafana中的一个好功能。 想要提供公关方面的帮助,因为目前还有很多其他事情非常重要

很好的解释@adamlwgriffiths同样的事情发生在我身上。

现在,我们通过一点技巧解决了这个问题,添加了一个自动登录grafana的javascript,但这是一个临时解决方案

+10!
为了确保安全,令牌中应包含用户名+密码+日期的哈希。 这可以用来在x小时后使令牌过期,以提高安全性。

如果有时间我会认真考虑的

如果您要存储令牌的创建日期以便可以过期,那么您还将存储哈希和关联的帐户,因此我认为不需要从任何特定数据中生成哈希。 它只需要足够大的搜索空间就可以使猜测变得不可行。

@adamlwgriffiths

我认为-从长远来看-用户/ org / api令牌需要合并,而不是添加新方法。
如果将API令牌扩展为允许从HTML界面使用,那么这将不是问题。
API令牌已经具有角色,并且可以被撤消,因此只需要用于Web视图即可,而不是纯API。

IMO API令牌应与普通用户相同。 有没有记录的任意隔离,我发现这是违反直觉的。 我认为最好使所有登录检查也能检查API密钥。

是否已实现此功能? 我试图让用户自动从我的网站重定向到grafana仪表板。

@comcomservices作为令牌本身的后续操作,您肯定可以使用用户ID和令牌到期时间对令牌内部的信息进行加密。 这样,您就可以读取令牌本身并获取信息,而无需将令牌存储在数据库中并在旧令牌上运行“清除和清除”。

我不愿推荐这样的东西,我坚信加密很难,而且如果不完全了解您的工作,尝试这样做并不是一个好主意。

加密令牌的另一个问题是,它们很大,而且信息越多,它们就会变得越大。
可以将任意长度的字符串制成任意长度的字符串,只要该空格足够大,就无法使用蛮力。

@adamlwgriffiths就密码学而言,我有一个正式的背景并且喜欢它,但是在这种情况下,我完全同意令牌是最好的。.只是想弄清楚这个go的东西,一直在做c ++和asm时间太长了...我会得到的,这是我名单上的第一位

我很期待这个功能! 关于上述@adamlwgriffiths关于将令牌嵌入网站的评论,我认为减轻这种情况的方法是将该令牌与应该请求它的域相关联。 这样,令牌仅在原点匹配时才起作用。 再比如,如果我对问题的理解正确的话,那就是Sentry的raven-js ; 它将创建一个公共URL,然后按来源对其进行限制(请参见下文)。 这样可以减轻安全隐患吗?

screen shot 2016-03-24 at 10 57 18 am

@ Germanaz0您的自动登录JS是否公开可用? 我正在针对master分支实施类似的操作,并且在访问仪表板页面之前,后端似乎重定向到登录屏幕。 我对项目结构还不是很熟悉,所以我可能没有插入JS代码的正确部分。

@rca是的,但是我的解决方案非常简单https://gist.github.com/Germanaz0/d41b5f60dd8097405b6b

您会收到{user:_USERNAME_,传递:_PASS_,redirect_to:_URL_TO_REDIRECT}这样的json输入参数,例如?t = base64

您应将该脚本包含在登录页面中。

@ Germanaz0 ,谢谢分享! 发送我的评论后,我开始看一看,正如您所指出的,我发现我需要更新登录页面。 我采用了稍微不同的方法,并更新了登录控制器,而不是制作独立的脚本。 我的更改在这里: https :

这值得提出请求吗? 我很乐意使mod成为使它可以合并的必要条件。

这事有进一步更新吗?
@rca您是否创建了PR?

@rca的PR +1

@ Germanaz0 ,您要将.js文件包括在哪个文件中?

@rca您是否有关于如何使用登录控制器mod的说明? 我是grafana的新手,并试图使其在无人值守的自助服务终端上正常工作。

顺便说一句,如果其他人需要一种方式来实现自助服务终端等的功能,请检查Grafana的authproxy 。 我能够用这个和apache完成我所需要的。

@scottfuhrman没有正式写过,但是,这是我的用例和实现:

我不是在寻找信息亭模式,而是在内部页面上将仪表板作为iframe嵌入的一种方法。 图表嵌入得非常干净,例如:

screen shot 2016-12-14 at 10 24 06 am

在您想要嵌入仪表板的页面上,需要以下标记:

<div id='grafana-dashboard' class="col-lg-12"></div>


<script type="text/javascript">
    GrafanaEmbed = {
        grafanaUrl: 'https://your.grafana.example.com',
        dashboard: 'dashboad-name',
        queryParams: {
            dashnav: 0,
            // this is a base64-encoded string of username:password
            // for example on a *NIX machine (and Mac OS X):
            // $ echo "kiosk1:supersecret" | base64
            // a2lvc2sxOnN1cGVyc2VjcmV0Cg==
            auth: 'a2lvc2sxOnN1cGVyc2VjcmV0Cg==',
            theme: 'light'
        }
    };

    (function() {
        var d = document.createElement('script'); d.type = 'text/javascript'; d.async = true;
        d.src = GrafanaEmbed.grafanaUrl + '/public/app/features/dashboard/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(d);
    })();
</script>

希望这可以帮助。

+1

我没有人力资源,但我很乐意为此筹集资金。

以为我解决了这个问题,直到尝试使用播放列表。 对于给定的仪表板使用authproxy可以工作,但是一旦我尝试了具有多个仪表板的播放列表,就会遇到相同的问题。 如果无法完全实现查看安全性,则无法实现真正​​的自助服务机应用程序时,我不知道采用自助服务机模式的意义?

@torkelo我招募了@ over64来为我工作。

您如何建议将其实施? 基本上,我需要在URL字符串中包含一个绕过/解决身份验证的令牌。 最好的方法是什么?

不确定,必须研究如何安全地实现此功能

得到它了。 一旦您制定了计划,我们就可以准备好:)

如果您对操作方法有任何想法,请告诉我,我可以对其进行评估

好的。 @ over64会看一下并提出一些建议。

@torkelo您能看看#7431中的@ over64的PR来看看是否有意义。

任何简单的解决方法? 我正在尝试实现@ Germanaz0解决方案,但它对我不起作用:(

这是必须具备的功能,否则在将快照嵌入iframe时会被阻止。 嵌入式快照网址应支持登录密钥/令牌。

嘿大家,

此线程中的最新评论涉及:

  • 安全
  • 嵌入到iframe中

关于安全性,请考虑我上面的旧评论: https :

关于嵌入iframe: https

该分支(虽然很旧)包含从Discourse借来的代码,该代码可以很好地调整iframe的大小,并可以通过令牌进行身份验证,如上面的注释中所述。

@torkelo请让我知道是否考虑合并以上元素的请求。

@rca上面的代码中的

@zoell是从Discourse项目借来的一些js,用于根据框架内嵌的内容很好地调整页面上iframe的大小。

@rca哦,谢谢。 我在您提到的分支中找不到该文件。 在别的地方有吗?

@zoell ,我将分叉该存储库,并在该文件中包含该文件。

@rca谢谢,那太好了。

@rca对不起,我仍然无法在您之前提到的分支中找到该文件。

@TinaRen @zoell我对此表示歉意。

但是,现在看一看,看起来文件一直存在! 😬

我将在以下位置对此进行任何其他工作:

https://github.com/rca/grafana

文件位于:

https://github.com/rca/grafana/blob/embedding/public/app/features/dashboard/embed.js

如果此文件没有建立并且最终不在public_gen/目录中,请告诉我。

谢谢!

是否有可能至少将grafana限制为localhost访问? (以缩小面板共享到同一服务器站点)

我很乐意看到有人为此采取适当的实施措施,从而向上游发展。 我们提出的解决方案(#7431)从未被接受:(

我很高兴有我们这边的人花一些时间在此上,但是我们需要上游可以接受的指导。

使用Grafana的auth.proxy和Nginx的ngx_http_secure_link_module成功做到了这一点

我使用的链接格式http://grafana/?user=nayar&md5=2tutcea9nfdsfdsfdsw&expires=1505386800

一旦用户单击它,就设置了会话cookie,并且用户可以像正常登录一样浏览grafana。

优点:

  • 一段时间后链接失效+安全性
  • 链接使用用户ID,时间戳和密码+安全性生成哈希
  • 无需输入密码+方便

我的nginx conf就是这样

server {
    listen 3001 default_server;
#   listen [::]:3001 default_server;

    server_name _;

        location / {
        set $user "";
        set $state "";

        if ($args ~ "^user=(.+)&md5") {
                    set $user $1;
                    set $state "${state}U";
                }

        secure_link $arg_md5,$arg_expires;
                secure_link_md5 "$secure_link_expires$uri$user grafanarocks";

                if ($secure_link = "") { 
                    set $state "${state}S1";
                }

                if ($secure_link = "0") { 
                    set $state "${state}S2";
                }

                add_header X-uristate "$state";

                if ($state = "US1") { return 403; }
                if ($state = "US2") { return 410; }

                add_header X-uri "$user";

                proxy_set_header X-WEBAUTH-USER $user;

                proxy_pass http://127.0.0.1:3000;
            }
    }

如果您需要帮助,请随时与我联系

非常有趣,@ Nayar。 但是,我对此解决方案的担心是,它需要大量的自定义。 我更喜欢Grafana本机内置的东西。

我使用了股票Grafana。 只需在启用该模块的情况下重新编译普通的nginx即可。

Nayar,请让我知道您实现的解决方案是否适用于grafana.i的所有版本。 在我的组织中,他们已经安装了

提出一些有关如何解决此问题的想法(和问题)。

最快的解决方案:

1)在API密钥上添加特殊类型(标志),以便可以在url中使用它来登录。

提议:API密钥只能由组织管理员添加。


2)使用户可以创建api键和url键(api键的变体)。

与此相关的问题将是oauth设置,在该设置中,如果用户可以创建api密钥或url密钥,则在从Grafana(从oauth系统)中删除访问权限后,他们将能够使用此密钥。 由于api键或url键将不需要oauth登录。 当我们最终使用用户api键时,这将成为一个大问题。 一种缓解的解决方案是仅允许组织管理员或grafana服务器管理员创建用户api密钥。

有想法@DanCech吗? 继续使用带有AllowUrlLogin标志的API密钥吗?

我不认为使用API​​密钥基础结构是正确的方法,因为这样会使以后添加更多功能变得困难(例如,将URL限制为一组特定的仪表板,从而允许非管理员创建登录链接) ),可能会使用户感到困惑。 我们当然可以使用相同的概念,并且具有类似的后端结构,但是如果我们将其分开,它将为我们提供更多选择,并且我认为对于用户而言,它将更加清晰。

至于oauth登录问题,我认为我们必须弄清楚这里的范围。 如果您还启用了密码,则oauth用户也会遇到同样的问题,因为他们可以设置本地密码,并且在禁用oauth帐户后可以以这种方式登录。 解决该问题的唯一真正方法是将链接存储在用户帐户中,并在接受用户登录之前始终通过oauth重定向循环发送oauth用户。

我也认为我们需要为此功能起一个合理的名称。 “登录URL”可能太宽泛,将来并不会真正留下使用的余地,例如,它只能共享特定仪表板的实时链接。

@mattttt很想得到您的想法

因为这使得以后很难添加更多功能(例如,将URL限制为一组特定的仪表板,从而允许非管理员创建登录链接)

我不愿意将此登录功能链接到权限或将其限制为特定的仪表板(而不是将其链接到组织角色或用户)。 因为这会将其变成共享功能并设置未满足的安全期望(因为您可以从组织使用的数据源中查询所有数据)。

解决该问题的唯一真正方法是将链接存储在用户帐户中,并在接受用户登录之前始终通过oauth重定向循环发送oauth用户。

不确定如何解决“撤销”登录网址/用户api令牌。 如果他们在访问权被删除后从未尝试使用oauth登录,那么Grafana永远不会知道。

@hemsush根据此博客文章,它应该从Grafana 2.0起开始工作: https ://grafana.com/blog/2015/12/07/grafana-authproxy-have-it-your-way/

我不愿意将此登录功能链接到权限或将其限制为特定的仪表板(而不是将其链接到组织角色或用户)。 因为这会将其变成共享功能并设置未满足的安全期望(因为您可以从组织使用的数据源中查询所有数据)。

这是一个需要解决的问题,所以我的建议是在设计该系统时就考虑到将来的用例。

不确定如何解决“撤销”登录网址/用户api令牌。 如果他们在访问权被删除后从未尝试使用oauth登录,那么Grafana永远不会知道。

我的想法是,使用这些链接之一时,客户端获得的视图应类似于“匿名”用户,在这种情况下,他们不是以特定用户的身份神奇登录的,而是获得了受限的查看器帐户,这将使该功能完全脱离来自单个用户帐户。 这样可以避免单个用户帐户权限的问题,由于不能使用链接进行任何更改,因此可以降低风险级别,并且可以由组织管理员集中管理所有活动的访问链接。

解决方案建议

1)引入新概念“查看器URL令牌”,您可以在“ API密钥”页面中添加/删除(我们以后可以为此创建新页面)。 存储在新表url_token中,从安全角度来看,它们将与api键非常相似。 也就是说,它们将按照与api键相同的方式生成和验证。 不过,您可以使用,通过使用“&url-auth-token =”。
2)限制令牌只能与PNG渲染API一起使用的选项(由于使用URL令牌的用户将无法发出任何查询,只能查看现有的仪表板/面板,因此将更加安全)
3)将来,我们将不得不找到一种将令牌链接到用户组和仪表板权限的方法,尚不确定该方法将如何工作。 我认为为此创建一个虚拟用户可能会很好,该虚拟用户可用于为“ URL令牌”用户提供对特定仪表板和数据源的权限。 讨厌在权限检查中必须对URL令牌进行显式检查/联接。

4)明确指出,具有url令牌的任何人都可以访问所有组织的数据源(并且可以从技术上发出任何查询)(除非使用了render api的限制选项)。

想法@bergquist @DanCech

限制令牌仅与PNG渲染API一起使用的选项(由于使用URL令牌的用户将无法发出任何查询,而只能查看现有的仪表板/面板,因此将更加安全)

我认为PNG渲染不是很好的解决方案。 它会闪烁,看起来不会像真正的Grafana一样好。

我喜欢将令牌连接到用户的想法。 将令牌/登录连接到用户组和仪表板文件夹权限的最简单方法。 但是我认为使用令牌登录(电视登录/查看模式/电视模式)应强制用户处于Viewer角色。

明确说明,拥有url令牌的任何人都可以访问所有组织的数据源(并且可以从技术上发出任何查询)(除非使用了render api的限制选项)。

创建新令牌时添加信息和警告可能会有所帮助。

将令牌绑定到“普通”用户的问题在于,当用户被修改或删除时,它会引起各种问题。 如果url令牌能够以与用户相同的方式成为组的成员,那么在设置访问特定仪表板等的单个url时将具有极大的灵活性。

我不确定这会增加权限检查的复杂性,您将为组成员使用不同的表,具体取决于查看器是常规用户还是url令牌,但整个系统的访问检查不应该这样需要改变。

至于实际强制访问数据源,这里与普通用户没有什么不同。 该问题的最终解决方案是将数据源插件移动到后端,并通过指定仪表板,面板,时间范围和模板var值,并在验证用户身份后在后端构建实际查询,从而使前端发出数据源请求有权访问并且模板var值合法。

将令牌与“普通”用户绑定在一起的问题是,当用户被修改或删除时,它将引起各种问题

两种解决方案都知道,知道令牌的任何人(即使帐户已关闭)都可以查看仪表板的问题。 可以通过删除用户或令牌来撤消访问。

我不确定这会增加权限检查的复杂性,您将为组成员使用不同的表,具体取决于查看器是常规用户还是url令牌,但整个系统的访问检查不应该这样需要改变。

不论身份验证如何,检查的外观应相同。 因此,这不会是一个大问题。 用于将令牌/用户添加到组,仪表板等的UI可能很杂乱,只会帮助很少的用户。

至于实际强制访问数据源,这里与普通用户没有什么不同。 该问题的最终解决方案是将数据源插件移动到后端,并通过指定仪表板,面板,时间范围和模板var值,并在验证用户身份后在后端构建实际查询,从而使前端发出数据源请求有权访问并且模板var值合法。

我认为这是我们应该开始致力于以安全方式共享仪表板的良好体验的地方。 没有这种解决方案,所有的解决方案都将面临不利的平衡。 我认为在解决数据源访问之前,应该保持最低水平。

我还遇到了在username+passwd+ldap auth模式下嵌入仪表板的问题...
关于这个有任何更新吗?

我对查看器令牌选项非常感兴趣。 如果我能以任何方式提供帮助,我将很高兴为您提供帮助。

大家好!
我正在尝试为dashbord创建经过身份验证的链接,我在Java中有一个后端,在JSF中有一个前端,我想在屏幕上放置一个用户,单击该用户将其直接重定向到他的仪表板,我我对这个概念不太了解,有人吗?

你好

只是一个想法,试图提供帮助。 为什么不使用这样的基本身份验证添加新的用户API
? curl https://admin:admin<strong i="7">@localhost</strong>:3000/api/user/cookie
并获得JSON结果,例如
{"user_name":"admin","cookie_name":"grafana_,session":"a0b1c2d3e4","remember":"da27ef425e9e0d"}

它将通过https保护,我可以使用此信息来伪造cookie并授权用户查看其漂亮的图表。

非常注意您的代码,我认为(
而是发送:
user.Rands+user.Password, setting.CookieRememberName, user.Login, days, setting.AppSubUrl+"/"

到SetSuperSecureCookie函数,您可以创建一个受SetSuperSecureCookie启发的新函数,如下所示:

func (ctx *Context) NewFunc(secret, name, value string, others ...interface{}) {
   key := pbkdf2.Key([]byte(secret), []byte(secret), 1000, 16, sha256.New)
   text, err := com.AESGCMEncrypt(key, []byte(value))
   return hex.EncodeToString(text)
}

答案可能很详尽,并且像您的函数之一一样发送:

func getUserUserProfile(userId int64) Response {
    query := m.GetUserProfileQuery{UserId: userId}

    if err := bus.Dispatch(&query); err != nil {
        return ApiError(500, "Failed to get user", err)
    }

    cook:= array
    result := {
        user_name: user.name,
                cookie_name:   cookie.name,
        session: s.session,
                remember: cokie.remember

    }

    return Json(200, &result)
}

我知道您不是魔术师,并且编码不是在玩乐高玩具,但这对我来说是非常重要的功能。 我会尽力的。

在GrafanaCon @DanCech期间提到了使用GUID键创建公共播放列表的想法。 类似于今天的快照工作方式。 共享/存储此类密钥可被视为与API令牌一样安全,但仅限于查看播放列表。 播放列表可以与创建者/更新者关联,以验证仪表板视图权限。

该网址可能类似于https://play.grafana.com/playlists/public/<hash>

我喜欢此解决方案的一件事是,它将功能限制为仅查看播放列表(仪表板),我认为这是此类令牌的最大用例。

但是我们仍然需要以某种方式登录用户,因为仪表板acl /注释等将需要服务器端身份验证。

我想我们可以更多地考虑这种解决方案。 我主要是想从GrafanaCon中转储我们的对话:)

感谢@bergquist ,将这些东西记下来还不错,这绝对好!

这种思想的下一个发展是增加了“屏幕”的概念,以进一步使事物脱钩,以便用户可以创建一个“屏幕”,然后具有一个将要连接的秘密哈希网址。 这将达到相同的目的,但将允许从Grafana内部管理屏幕,因此用户可以控制显示的播放列表,等等。

此处的最终目标是为用户提供一种机制,以支持用户轻松创建sd卡或usb映像,该机制可用于引导专用树莓派并从Grafana安全地显示所需的播放列表,而不必跳过身份验证箍。

此处的最终目标是为用户提供一种机制,以支持用户轻松创建sd卡或usb映像,该机制可用于引导专用树莓派并从Grafana安全地显示所需的播放列表,而不必跳过身份验证箍。

@DanCech这正是我正在寻找的用例。

这种思想的下一个发展是增加了“屏幕”的概念,以进一步使事物脱钩,以便用户可以创建一个“屏幕”,然后具有一个将要连接的秘密哈希网址。

@DanCech听起来很完美!

嗨,大家好,

这似乎与Germanaz0最初提出的问题有点距离

自动登录通过网址传递用户令牌应该很好,这可能是将iframe嵌入网站的部分解决方案。

并由adamlwgriffiths解释

我们拥有自己的身份验证和仪表板,我们希望能够将用户从仪表板传递到Grafana-类似于Heroku如何与New Relic和其他使用零密码的服务进行互操作。 当然,提供url + token身份验证方法也是一样的。

Germanaz0开发一个js脚本

现在,我们通过一点技巧解决了这个问题,添加了一个自动登录grafana的javascript,但这是一个临时解决方案

我了解他们需要自动登录才能在自己的网站上使用grafana图表。 我根本不需要使用播放列表,这有可能吗?

如果您只是想自动登录用户,最好的方法是使用http://docs.grafana.org/tutorials/authproxy/

@DanCech的问题是,所有用户都可以自动登录。我们想要一种仅自动登录具有特定URL的用户的方法。

@gzzo取决于代理的设计

我也在Grafana中寻找此功能。
我认为嵌入Microsoft Power BI是很好的解决方案。 请参阅下面的链接。
https://github.com/Microsoft/PowerBI-JavaScript/wiki/Embedding-Basics
https://microsoft.github.io/PowerBI-JavaScript/demo/v2-demo/index.html

我认为上面的PowerBi解决方案基于OAuth2。
Grafana服务器端应支持OAuth2并启用CORS。

@Nayar我是Grafana的新手。 您在2017年9月14日发表评论的股票Grafana和股票Nginx是什么意思? 两者都有链接吗?

我猜急于等待5.4版本的发布。

使用Grafana的auth.proxy和Nginx的ngx_http_secure_link_module成功做到了这一点

我使用的链接格式http://grafana/?user=nayar&md5=2tutcea9nfdsfdsfdsw&expires=1505386800

一旦用户单击它,就设置了会话cookie,并且用户可以像正常登录一样浏览grafana。

优点:

  • 一段时间后链接失效+安全性
  • 链接使用用户ID,时间戳和密码+安全性生成哈希
  • 无需输入密码+方便

我的nginx conf就是这样

server {
  listen 3001 default_server;
#     listen [::]:3001 default_server;

  server_name _;

        location / {
      set $user "";
      set $state "";

      if ($args ~ "^user=(.+)&md5") {
                    set $user $1;
                    set $state "${state}U";
                }

      secure_link $arg_md5,$arg_expires;
                secure_link_md5 "$secure_link_expires$uri$user grafanarocks";

                if ($secure_link = "") { 
                    set $state "${state}S1";
                }

                if ($secure_link = "0") { 
                    set $state "${state}S2";
                }

                add_header X-uristate "$state";

                if ($state = "US1") { return 403; }
                if ($state = "US2") { return 410; }

                add_header X-uri "$user";

                proxy_set_header X-WEBAUTH-USER $user;

                proxy_pass http://127.0.0.1:3000;
            }
    }

如果您需要帮助,请随时与我联系

嗨Nayar,
我正在尝试与SaaS集成grafana。
要求是在用户登录我的Web应用程序后,然后单击我页面中的“ grafana”链接后,它将重定向到grafana仪表板,而无需输入用户名和密码。

您的评论似乎符合我的要求。 但是我仍然不清楚身份验证过程。
当proxy_pass到grafana时,如何验证用户是否由我自己的应用程序认证。

我的Web应用程序是通过X-XSRF-TOKEN来检查用户权限的。

我是服务器配置的新手,感谢您的帮助。

@ torkelo / @ bergquist请注意,这就是我们在Screenly中解决此问题的方式。 它是实时的,而且效果很好! 谢谢大家的辛苦!

@ torkelo / @ bergquist请注意,这就是我们在Screenly中解决此问题的方式。 它是实时的,而且效果很好! 谢谢大家的辛苦!

@vpetersson我没有使用屏幕显示,但是很好奇您如何实现此功能。 我了解生成API令牌的过程。 您是否仍在网址中内嵌框架? 您如何将身份验证令牌附加到请求标头中?

@GimpMaster我们只使用auth标头,因此不需要iframe。 自从我们编写了播放器/浏览器以来,我们就能够在页面加载中注入auth标头。

通过使用@GimpMaster链接的Screenly的方法,我刚刚使Kiosk模式工作。 我使用了Chrome扩展程序ModHeader ,在其中添加了带有Bearer API密钥的Authorization标头。 但是,由于Extensions需要一些时间来加载10秒钟的睡眠,因此在树莓派上设置信息亭成为了诀窍。 该解决方案也适用于iframe,但随后必须在每个客户端上进行配置。

@Nayar我已成功调整您建议的ngnix配置以使用_unsecure_访问。 也就是说,它只是从查询字符串中获取用户名,并将其放入X-WEBAUTH-USER中。 然后,它获得了grafana会话ID,我们就离开了。 谢谢!

我无法使md5方法正常工作。 我不清楚我需要制作md5指纹的确切内容。 你能详细说明吗? 制作md5有什么技巧吗?

可以在grafana 6. *中实施任何通过令牌/ cookie /标题/ ...登录的解决方案吗?

我无法使用空白PHP中的简单链接面板来完成此操作

index.php

<html>
<body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script language="javaScript">
$( document ).ready(function() {
$.ajax({
        type: "GET",
        //url: "http://page.test;/grafana/",
        url: "http://page.test;/grafana/d/o24Tt1Cik/dashboard-test?orgId=1",
        contentType: "application/json",
        xhrFields: {
            withCredentials: false
        },
        beforeSend: function(request) {
                     request.setRequestHeader("X-WEBAUTH-USER", "admin");
                },
        headers: {
            // Set any custom headers here.
        "X-WEBAUTH-USER" : "admin"
        },
        success: function(data){
                var iframeDoc = $("#monitoringframe").get(0).contentDocument;
                iframeDoc.open();
                iframeDoc.write(data);
                iframeDoc.close();
//$("#monitoringframe").attr('srcdoc',data)
        },
        error : function(err) {
            console.log('Error!', err)
        }
    });
});

</script>
<iframe name="monitoringframe" id="monitoringframe" src="about:blank" sandbox="allow-forms allow-popups allow-same-origin allow-scripts" width=100% height=600 border="0" frameborder="0" />
</body>
</html>

Nginx的

 server {
  listen 80;
  server_name page.test;
  root /var/www/page;
  index index.html index.htm index.php;

        location ~ \.php$ {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
        location /grafana/ {

                proxy_pass http://localhost:3000/;

       }

}

grafana.ini

[auth.proxy]
# Defaults to false, but set to true to enable this feature
enabled = true
# HTTP Header name that will contain the username or email
header_name = X-WEBAUTH-USER
# HTTP Header property, defaults to `username` but can also be `email`
header_property = username
# Set to `true` to enable auto sign up of users who do not exist in Grafana DB. Defaults to `true`.
auto_sign_up = true
# If combined with Grafana LDAP integration define sync interval
ldap_sync_ttl = 60
# Limit where auth proxy requests come from by configuring a list of IP addresses.
# This can be used to prevent users spoofing the X-WEBAUTH-USER header.
# Example `whitelist = 192.168.1.1, 192.168.1.0/24, 2001::23, 2001::0/120`
whitelist = 127.0.0.1, ::1/120
# Optionally define more headers to sync other user attributes
# Example `headers = Name:X-WEBAUTH-NAME Email:X-WEBAUTH-EMAIL`
headers =

[auth.basic]
;enabled = true

我测试过将我的nginx配置更改为此,并在URL中设置“?user = myUser”,但仅得到未经授权的响应

location /grafana/ {

                error_log /var/www/grafana/error.log;
                access_log /var/www/grafana/access.log;

                set $user "";

                if ($args ~ "^user=(.+)") {
                    set $user $1;
                }

                add_header X-uri "$user";

                proxy_set_header X-WEBAUTH-USER $user;

                proxy_pass http://localhost:3000/;

       }

recorte

@ mr0bles有关身份验证代理的所有内容在文档中进行了"X-WEBAUTH-USER来调用代理-通常您在代理中进行身份验证,而代理又会填充并向grafana提供X-WEBAUTH-USER

@marefr谢谢您的回答。
我阅读了文档,并且我的API正常工作,但是我需要动态用户身份验证(并非页面的所有用户都具有相同的权限)

@Nayar的此解决方案标题中包含X-WEBAUTH-USER,而没有对其进行硬编码,但是我无法使其工作

我认为6.0或6.1出现了问题。
我昨天在Apache2中将使用auth代理的完全正常的安装更新为6.1(从5.3),并获得了与@ mr0bles完全相同的屏幕

请注意,Grafana似乎确实了解代理标头:最初确实使用户登录,但随后的请求获得401响应。

@Bitblade我们还没有收到其他与您相似的报告。 由于此问题与功能请求有关,请打开新的错误报告。

使用Grafana的auth.proxy和Nginx的ngx_http_secure_link_module成功做到了这一点

我使用的链接格式http://grafana/?user=nayar&md5=2tutcea9nfdsfdsfdsw&expires=1505386800

一旦用户单击它,就设置了会话cookie,并且用户可以像正常登录一样浏览grafana。

优点:

  • 一段时间后链接失效+安全性
  • 链接使用用户ID,时间戳和密码+安全性生成哈希
  • 无需输入密码+方便

我的nginx conf就是这样

server {
  listen 3001 default_server;
#     listen [::]:3001 default_server;

  server_name _;

        location / {
      set $user "";
      set $state "";

      if ($args ~ "^user=(.+)&md5") {
                    set $user $1;
                    set $state "${state}U";
                }

      secure_link $arg_md5,$arg_expires;
                secure_link_md5 "$secure_link_expires$uri$user grafanarocks";

                if ($secure_link = "") { 
                    set $state "${state}S1";
                }

                if ($secure_link = "0") { 
                    set $state "${state}S2";
                }

                add_header X-uristate "$state";

                if ($state = "US1") { return 403; }
                if ($state = "US2") { return 410; }

                add_header X-uri "$user";

                proxy_set_header X-WEBAUTH-USER $user;

                proxy_pass http://127.0.0.1:3000;
            }
    }

如果您需要帮助,请随时与我联系

该解决方案对我不起作用。 因为我认为每个请求都应包含有效的X-WEBAUTH-USER标头。 如果您在第一个请求上填写标头,获取cookie并使用它们,那将不起作用。

我结束了下一个解决方案:

server {
  listen 80 default_server;
  listen [::]:80 default_server;

  client_max_body_size 10m;
  root /foo/public;

  location /grafana/ {
    auth_request /gauth;
    auth_request_set $user $upstream_http_user;

    proxy_set_header X-WEBAUTH-USER $user;
    proxy_pass http://localhost:4000/;
  }

  location / {
    try_files $uri @app;
  }

  location <strong i="23">@app</strong> {
    proxy_pass http://127.0.0.1:3000;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-SSL-Client-Cert $ssl_client_cert;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_redirect  off;
  }
}

因此该解决方案使用auth_request nginx模块。 我的应用负责访问控制(/ gauth请求),并在User响应标头中返回用户名。

嗨,同时,您可以使用此处描述的我的解决方案: https :

这是我使用Grafana的通用OAuth身份验证和PHP的解决方法: https :

希望这会帮助你。

只是想评论我如何使用http基本身份验证解决此问题https://github.com/grafana/grafana/issues/13706#issuecomment -540958284

自动登录通过网址传递用户令牌应该很好,这可能是将iframe嵌入网站的部分解决方案。

@rca您能用代码举例吗?我复制了代码并嵌入embed.js,但没有用。

如果您使用的是oauth,则有一种无需再次登录即可提取嵌入式grafana的方法

  1. 使用单个oauth提供程序设置grafana,无需其他登录机制
  2. GF_AUTH_OAUTH_AUTO_LOGIN为true
  3. 在子路径上托管grafana,并使用反向代理,以便grafana与您的主应用程序位于同一主机上
  4. 将您的主应用程序和grafana挂接到相同的oauth提供程序(对于oauth提供程序,它们将是相同的“应用程序”)
  5. 嵌入格拉法纳
  6. 加载iframe时,grafana将尝试使用oauth自动登录(由于它与您的主应用程序位于同一域,因此应会成功登录),从而共享相同的身份验证cookie

编辑:您可能需要在grafana中设置security.cookie_samesite=none以使其在某些浏览器中正常工作(这是因为在iframe中,发生了重定向到oauth提供程序(不同域)的操作,然后重定向回您的grafana域。目前,firefox不允许将设置为lax同一站点cookie以这种方式持久化:https://bugzilla.mozilla.org/show_bug.cgi?id = 1454027,这意味着grafana会松开其oauth_state cookie(如果cookie_samesite未设置为none

@seanlaff我使用AWS Cognito尝试了您的解决方案,但它返回的标头不允许将其放在iframe中(X-Frame-Options:deny),对此有任何提示吗?

使用Grafana的auth.proxy和Nginx的ngx_http_secure_link_module成功做到了这一点
我使用的链接格式http://grafana/?user=nayar&md5=2tutcea9nfdsfdsfdsw&expires=1505386800
一旦用户单击它,就设置了会话cookie,并且用户可以像正常登录一样浏览grafana。
优点:

  • 一段时间后链接失效+安全性
  • 链接使用用户ID,时间戳和密码+安全性生成哈希
  • 无需输入密码+方便

我的nginx conf就是这样

server {
    listen 3001 default_server;
#   listen [::]:3001 default_server;

    server_name _;

        location / {
        set $user "";
        set $state "";

        if ($args ~ "^user=(.+)&md5") {
                    set $user $1;
                    set $state "${state}U";
                }

        secure_link $arg_md5,$arg_expires;
                secure_link_md5 "$secure_link_expires$uri$user grafanarocks";

                if ($secure_link = "") { 
                    set $state "${state}S1";
                }

                if ($secure_link = "0") { 
                    set $state "${state}S2";
                }

                add_header X-uristate "$state";

                if ($state = "US1") { return 403; }
                if ($state = "US2") { return 410; }

                add_header X-uri "$user";

                proxy_set_header X-WEBAUTH-USER $user;

                proxy_pass http://127.0.0.1:3000;
            }
    }

如果您需要帮助,请随时与我联系

该解决方案对我不起作用。 因为我认为每个请求都应包含有效的X-WEBAUTH-USER标头。 如果您在第一个请求上填写标头,获取cookie并使用它们,那将不起作用。

我结束了下一个解决方案:

server {
  listen 80 default_server;
  listen [::]:80 default_server;

  client_max_body_size 10m;
  root /foo/public;

  location /grafana/ {
    auth_request /gauth;
    auth_request_set $user $upstream_http_user;

    proxy_set_header X-WEBAUTH-USER $user;
    proxy_pass http://localhost:4000/;
  }

  location / {
    try_files $uri @app;
  }

  location <strong i="24">@app</strong> {
    proxy_pass http://127.0.0.1:3000;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-SSL-Client-Cert $ssl_client_cert;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_redirect  off;
  }
}

因此该解决方案使用auth_request nginx模块。 我的应用负责访问控制(/ gauth请求),并在User响应标头中返回用户名。

如何搭配iframe使用?
我是Grafana和NGINX的新手
所以请立即分享最大详细信息以进行修改

如何搭配iframe使用?

@pgsekaran此解决方案不适用于iframe,但适用于获取grafana UI的用户,而无需为您的应用程序用户提供明确的grafana登录名。 在这种情况下,应用程序是代理,它知道如何登录grafana。

你好
感谢您的快速回复。 您是否有任何参考链接以使用iframe将Grafana与其他应用程序添加。我将Grafana添加至我的应用程序,但我无法设置使用管理。
问候古纳
2020年6月23日星期二,格林尼治标准时间+5:30,09:54:57 PM,康斯坦丁·科洛蒂克(Konstantin Kolotyuk) [email protected]写道:

如何搭配iframe使用?

@pgsekaran此解决方案不适用于iframe,但适用于获取grafana UI的用户,而无需为您的应用程序用户提供明确的grafana登录名。 在这种情况下,应用程序是代理,它知道如何登录grafana。

-
您收到此邮件是因为有人提到您。
直接回复此电子邮件,在GitHub上查看或取消订阅。

仍然不执行吗? 认真地说,这是一个很好的功能。

@pgsekaran我有一个针对iframe的解决方案,它不是很安全,因为它使用基于用户名的登录名,并且依赖于不容易猜测的用户名。 基本上,用户名是令牌。
我在这里写了关于它的内容,虽然不是很详细,但是可以帮助您入门
https://blog.yadamiel.com/tutorials/embed-and-authenticate-grafana-in-a-iframe

@pgsekaran我有一个针对iframe的解决方案,它不是很安全,因为它使用基于用户名的登录名,并且依赖于不容易猜测的用户名。 基本上,用户名是令牌。
我在这里写了关于它的内容,虽然不是很详细,但是可以帮助您入门
https://blog.yadamiel.com/tutorials/embed-and-authenticate-grafana-in-a-iframe

你好

我需要通过自动登录使用NGINX和iframe进行设置

确切的问题在https://github.com/grafana/grafana/issues/16319#issuecomment -483272921中进行了解释:会话ID不会与包含页面“ skeleton”的页面的第一个响应一起返回。 后续请求不包含自动登录令牌,因此失败。

我们在信息亭模式下使用铬在不同的地方显示Grafana仪表板。 由于相同的Grafana实例也可供用户使用,因此我们使用auth.generic_oauth (直到5.x之前auth.basic )登录人员,并使用auth.proxy登录信息亭模式的计算机:

/usr/bin/chromium --app="https://server.localdomain/grafana/d/000000004/002-the-big-picture?orgId=1&refresh=5m&autologin=lHOrdypkhxzNYb2lRaIjbNPlOCZw9gWE"

正如其他人指出的那样,这并不简单。 什么工作是先调用的URL http://prometheus.localdomain/grafana/login?autologin=lHOrdypkhxzNYb2lRaIjbNPlOCZw9gWE (现在设置了grafana_session饼干),然后重定向到真正的仪表盘。 但是...信息亭模式🤷和iframe ♂‍♂️

我们最终的解决方案是将autologin查询参数与自定义Cookie结合在一起。 是的,您不能通过GUI注销,因为未删除自定义cookie,但是由于此机制仅在信息亭模式的计算机上使用,因此不需要这样做。

因此,这是Grafana服务器的nginx配置:

# this maps tokens to grafana users
map $arg_autologin $autologin {
    lHOrdypkhxzNYb2lRaIjbNPlOCZw9gWE "display-1";
    default "";
}

server {
    listen 80;

    server_name server.localdomain;

    # add_header cannot be used in an "if"-context
    # so we set it to an empty string here as 
    # `add_header Set-Cookie "";` just removes the complete
    # header from the response
    set $setCookieHeader "";

    # when the autologin query param is not set, use
    # the value from the cookie named `grafana_autologin`
    if ($arg_autologin = "") {
        set $arg_autologin $cookie_grafana_autologin;
    }

    # when either the autologin query param or the `grafana_autologin`
    # cookie was set, place the autologin token and the cookie path
    # in the variable. `path=/` is needed to allow deeplinking
    if ($arg_autologin != "") {
        set $setCookieHeader "grafana_autologin=$arg_autologin;path=/";
    }

    location /grafana/ {
        rewrite  ^/grafana/(.*)  /$1 break;

        # now send the Set-Cookie header when an autologin token was provided
        add_header Set-Cookie $setCookieHeader;

        # look up the autologin token in the map above and set the grafana user
        proxy_set_header X-WEBAUTH-USER $autologin;
        proxy_pass http://localhost:3000;
    }
}
此页面是否有帮助?
1 / 5 - 1 等级

相关问题

SATHVIKRAJU picture SATHVIKRAJU  ·  3评论

tuxinaut picture tuxinaut  ·  3评论

jackmeagher picture jackmeagher  ·  3评论

royemmerich picture royemmerich  ·  3评论

ahmetkakici picture ahmetkakici  ·  3评论