为数据源插件添加身份验证
本页面解释了如何配置数据源插件以根据第三方API进行身份验证。
有两种方法可以从插件执行身份验证请求—使用数据源代理,或通过建立一个后端插件.你的选择取决于你的插件如何根据第三方API进行身份验证。
- 如果需要使用基本身份验证或API密钥进行身份验证,请使用数据源代理
- 如果API使用客户端凭证支持OAuth 2.0,则使用数据源代理
- 如果API使用数据源代理不支持的自定义身份验证方法,或者API通过不同于HTTP的协议进行通信,请使用后端插件
无论使用哪种方法,首先都需要加密插件需要存储的敏感信息。
加密数据源配置
数据源插件有两种存储自定义配置的方式:jsonData
而且secureJsonData
.
拥有查看器的内容可以访问数据源配置jsonData
——明文。如果您启用了匿名访问,那么任何可以在浏览器中访问Grafana的人都可以看到jsonData
.只使用jsonData
存储非敏感配置。
注意:通过输入,您可以看到当前用户有权访问的设置
window.grafanaBootData
在浏览器的开发人员控制台中。
如果您需要存储敏感信息,例如密码、令牌和API密钥,请使用secureJsonData
代替。每当用户保存数据源配置时,其中的秘密secureJsonData
被发送到Grafana服务器,并在存储之前进行加密。
一旦安全配置被加密,就不能再从浏览器访问它了。在秘密被保存后,唯一的方法就是使用数据源代理.
向数据源插件添加秘密配置
为了演示如何向数据源插件添加密钥,让我们添加对配置API密钥的支持。
中创建一个新接口types.ts
来保存API键。
导出接口MySecureJsonData {apiKey?:字符串;}
将类型信息添加到secureJsonData
对象的ConfigEditor
将接口作为第二个类型参数接受。
interface Props extends DataSourcePluginOptionsEditorProps {}
方法访问密匙的值选项
道具在你的ConfigEditor
直到用户保存配置。当用户保存配置时,Grafana会清除该值。之后,您可以使用secureJsonFields
以确定是否已配置该属性。
const {secureJsonData, secureJsonFields} = options;const {apiKey} = secureJsonData;
要安全地更新插件配置编辑器中的秘密,请更新secureJsonData
对象使用onOptionsChange
道具。
const onAPIKeyChange = (event: ChangeEvent) => {onOptionsChange({…选项,secureJsonData: {apiKey: event.target。Value,},});};
接下来,定义一个可以接受用户输入的组件。
.
最后,如果希望用户能够重置API键,则需要将属性设置为假
在secureJsonFields
对象。
const onResetAPIKey = () => {onOptionsChange({…secureJsonFields:{…options。secureJsonFields,apiKey:假,},secureJsonData:{ ...options.secureJsonData, apiKey: '', }, }); };
现在用户可以配置秘密了,下一步是看看如何将它们添加到请求中。
使用数据源代理进行身份验证
一旦用户保存了数据源的配置,浏览器中就不再有任何秘密的数据源配置了。加密的秘密只能在服务器上访问。那么如何将它们添加到请求中呢?
Grafana服务器提供了一个代理,允许您为请求定义模板。我们称之为代理航线.Grafana将代理路由发送到服务器,连同其他配置一起解密秘密,并在发送请求之前将它们添加到请求中。
注意:方法,确保不要将数据源代理与身份验证代理.数据源代理用于对数据源进行身份验证,而认证代理用于登录到Grafana本身。
在插件中添加代理路由
如果需要通过Grafana代理转发请求,需要配置一条或多条代理路由。代理路由是由代理处理的任何传出请求的模板。配置代理路由plugin.json文件。
将路由添加到plugin.json。注意,每次对插件进行更改时,都需要重新启动Grafana服务器。json文件。
“路线”:[{“路径”:“例子”,“url”:“https://api.example.com”}]
在
数据源
,从中提取代理URLinstanceSettings
类属性url
.导出类DataSource extends DataSourceApi
{url?:字符串;构造函数(instanceSettings: DataSourceInstanceSettings ){超级(instanceSettings);这一点。url= instanceSettings.url; } // ... } 在
查询
方法,使用BackendSrv
.URL路径的第一部分需要匹配路径
您的代理路由。替换数据源代理这一点。url+ routePath
与url
路线。以下请求将被提出给https://api.example.com/v1/users
.import {getBackendSrv} from '@grafana/runtime';
const routePath = '/example';getBackendSrv()。datasourceRequest({url: this。url +路由路径+ '/v1/users', method: 'GET', });
为插件添加动态代理路由
Grafana将代理路由发送到服务器,数据源代理在服务器上解密任何敏感数据,并在发出请求之前将解密的数据插入模板变量。
如果要在路由中添加自定义配置,请使用add{{.JsonData。apiKey}}
到路线,在哪里apiKey
属性的名称是否在jsonData
对象。
"routes": [{"path": "example", "url": "https://api.example.com/projects/{{. jsondata . "投影}}"}]
您还可以配置路由以使用敏感数据.SecureJsonData
.
“路线”:[{“路径”:“例子”,“url”:“https:// {{.JsonData。用户名}}:{{. securejsondata。密码}}@api.example.com"}]
除了URL之外,还可以向代理路由添加标头、URL参数和请求体。
为代理路由添加HTTP报头
"routes": [{"path": "example", "url": "https://api.example.com", "headers": [{"name": "Authorization", "content": " holder {{. securejsondata . "apiToken}}"}]}]
为代理路由添加URL参数
“路线”:[{“路径”:“例子”,“url”:“http://api.example.com”,“urlParams”:[{“名称”:“apiKey”,“内容”:“{{.SecureJsonData。apiKey}}"}]}]
添加请求体到代理路由
“路线”:[{“路径”:“例子”,“url”:“http://api.example.com”,“身体”:{“用户名”:“{{.JsonData。username}}", "password": "{{. securejsondata . "密码}}"}}]
在插件中添加OAuth 2.0代理路由
数据源代理支持OAuth 2.0身份验证。
由于对每个路由的请求都是在服务器端进行的,因此只支持机器对机器身份验证。换句话说,如果您需要使用不同于客户端凭证的授权,则需要自己实现它。
若要使用OAuth 2.0进行身份验证,请添加atokenAuth
对象指定为代理路由定义。如有必要,Grafana会执行对中定义的URL的请求tokenAuth
在向代理路由中的URL发出请求之前检索令牌。当令牌过期时,Grafana会自动更新令牌。
定义的任何参数tokenAuth.params
编码为应用程序/ x-www-form-urlencoded
并发送到令牌URL。
{"routes": [{"path": "api", "url": "https://api.example.com/v1", "tokenAuth": {"url": "https://api.example.com/v1/oauth/token", "params": {"grant_type": "client_credentials", "client_id": "{{. securejsondata . "clientId}}", "client_secret": "{{. securejsondata . "clientSecret}}"}}}]}
使用后端插件进行身份验证
虽然数据源代理支持HTTP api最常见的身份验证方法,但使用代理路由有一些限制:
- 代理路由只支持HTTP和HTTPS协议
- 代理路由不支持自定义令牌认证
如果这些限制适用于你的插件,你需要添加一个后端插件.由于后端插件运行在服务器上,它们可以访问解密的秘密,这使得更容易实现自定义身份验证方法。
解密的秘密可从DecryptedSecureJSONData
字段。
function (ds *dataSource)Context, req *backend。QueryDataRequest) (*backend.QueryDataResponse, error) { instanceSettings := req.PluginContext.DataSourceInstanceSettings if apiKey, exists := settings.DecryptedSecureJSONData["apiKey"]; exists { // Use the decrypted API key. } // ... }
转发登录用户的OAuth标识
如果您的数据源使用与Grafana本身相同的OAuth提供者,例如使用通用OAuth身份验证,您的数据源插件可以为登录的Grafana用户重用访问令牌。
要允许Grafana将访问令牌传递给插件,请更新数据源配置并设置jsonData.oauthPassThru
财产真正的
.的DataSourceHttpSettings控件提供一个切换前向OAuth标识这个选项。您还可以构建一个适当的切换来设置jsonData.oauthPassThru
在数据源配置页面UI中。
配置时,Grafana将在授权头中将用户的令牌传递给插件QueryDataRequest
对象上的QueryData
请求后端数据源。
function (ds *dataSource) CheckHealth(ctx上下文。Context, req *backend。CheckHealthRequest) (*backend.CheckHealthResult, error) { token := strings.Fields(req.Headers["Authorization"]) var ( tokenType = token[0] accessToken = token[1] ) // ... return &backend.CheckHealthResult{Status: backend.HealthStatusOk}, nil } func (ds *dataSource) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) { token := strings.Fields(req.Headers["Authorization"]) var ( tokenType = token[0] accessToken = token[1] ) for _, q := range req.Queries { // ... } }
此外,如果用户的令牌中包含ID令牌,Grafana将在插件中传递用户的ID令牌X-ID-Token
头文件,可在QueryDataRequest
对象上的QueryData
请求后端数据源。
function (ds *dataSource) CheckHealth(ctx上下文。Context, req *backend。CheckHealthRequest) (*backend.CheckHealthResult, error) { idToken := req.Headers["X-ID-Token"] // ... return &backend.CheckHealthResult{Status: backend.HealthStatusOk}, nil } func (ds *dataSource) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) { idToken := req.Headers["X-ID-Token"] for _, q := range req.Queries { // ... } }
的授权
而且X-ID-Token
的页眉也可用CallResourceRequest
对象上的CallResource
请求后端数据源时jsonData.oauthPassThru
是真正的
.
function (ds *dataSource) CallResource(ctx上下文)Context, req *backend。CallResourceRequest,sender backend.CallResourceResponseSender) error { token := req.Headers["Authorization"] idToken := req.Headers["X-ID-Token"] // present if user's token includes an ID token // ... }
注意:由于Grafana中的一个bug,在PostgreSQL中使用这个特性可能会导致死锁。有关更多信息,请参阅Grafana在PostgreSQL中导致死锁,而试图刷新用户令牌.
为登录用户转发cookie
数据源插件可以为登录的Grafana用户转发某些cookie到数据源。使用DataSourceHttpSettings组件在数据源的配置页上。它提供允许饼干选项,其中可以指定要传递给插件的cookie的名称。
配置时,Grafana会将这些cookie传递给插件饼干
头文件中可用QueryData
,CallResource
而且CheckHealth
后端数据源中的请求。
function (ds *dataSource)Context, req *backend。QueryDataRequest) (*backend.QueryDataResponse, error) { cookies:= req.Headers["Cookie"] // ... } func (ds *dataSource) CallResource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error { cookies := req.Headers["Cookie"] // ... } func (ds *dataSource) CheckHealth(ctx context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) { cookies:= req.Headers["Cookie"] // ... }
相关Grafana资源
开幕主题演讲:《Grafana 9》有什么新内容?
Raj Dutt, Myrle Krantz和Torkel Ödegaard揭开了Grafana 9的新内容。观看2022年GrafanaCONline开幕式主题演讲。随需应变。
使用Grafana插件统一您的数据:Datadog, Splunk, MongoDB等
在本次网络研讨会中,学习如何利用Grafana的插件生态系统访问80多个数据源,包括Datadog、Splunk、MongoDB等的插件。
从Grafana Enterprise和可观察性开始
加入Grafanabob电竞频道实验室团队,进行30分钟的演示,演示如何开始使用Grafana堆栈,这样您就可以在短短几分钟内从零到可观察性。