2018-05-15 18:26:46

Grafana 如何整合 SSO

grafana 和 SSO 整合有两种途径,本文简单介绍一下

1. 直接把账号塞进 Grafana 数据库

这个方法主要使用了 Grafana 的参数 auth.proxy,auth.proxy 是 Grafana 内置的方法,使用方便,网络上已经有详细的集成文章了。不过唯一的劣势是需要知道账号和对应的密码,通常来说权限不够高是拿不到密码的,只有一个随时会过期的 SSO token,因此选择了下一种办法。

2. OAuth 2

想要和现有的一些系统集成,拿账号密码是肯定行不通的,比如 Github 不可能把用户的密码暴露给 Grafana ,最多给你一个 OAuth 2 相关的 token 令牌。 OAuth 2 当然也被 Grafana 支持了,配置参数见官方文档,默认有 Okta、Google、ldap、Github 等集成,通用的集成则是 Generic-oauth 了。

OAuth 2 对于初接触者可能有点绕,不过在内网中,拥有域名时很容易就能拿到用户的 SSO token,此时 OAuth 2 其实简化成唯一的目的:把 SSO token 塞到 OAuth 2 用这个 token 去调鉴权 API这最后一步:

2.1 Grafana 参数 auth_url

auth_url 是 Generic-oauth 的 OAuth 2 流程的第一步,Grafana 会在前端跳转到 auth_url 里填写的地址,我们需要在这个地址里做的事情是:

  1. 校验 SSO token,如果未通过则跳转到 SSO 登录地址里去,有登录完回调地址的话记得拼一个能跳回来的地址
  2. Grafana 跳转过来的地址的 querystring 中会带有 redirect_uri 和 state 参数,此时用这个两个参数构造一个回调地址,并加上 code=${SSO_token} 这个querystring ,让前端可以跳回到正确的 Grafana 地址

2.2 Grafana 参数 token_url

第二步本来是 Grafana 后端用刚刚传回去的那个 code 去调用 token_url 以获取 OAuth 2 的令牌,不过第一步传回去的那个 code 本身就是令牌了,因此只需要简单的返回一个形如 {"access_token": ${token}, token_type: 'balbla', refresh_token: 'balbala', expires_int: 6000} 的 JSON 字符串返回即可。多的那三个参数是 Grafana 后端中要求的,但是对值却没有强校验,可能是其他的 OAuth 2 集成有用到。

2.3 Grafana 参数 api_url

第二步 Grafana 后端请求完 token_url 后拿到了一个令牌,最后它会继续在后端用这个令牌去请求 api_url 以获得它需要的用户数据了,此时在该 API 构造一个包含 email id name work_code username 的 JSON 字符串返回,即可不用账号密码就登陆上 Grafana 啦!

结尾

我整合 SSO 时既有类似 serverless 的平台可用又有类似 nginx 的网关层可用,因此构造响应和处理代理非常方便,整个流程从探索方案到上线只花了一下午的时间。如果没有这些基础设施,确实就需要额外写不少代码,要麻烦许多了。

本文链接:https://smallpath.me/post/grafana-with-sso

-- EOF --