如何解决我怎样才能让这个自定义连接器正确地进行身份验证?
我希望 PowerBI 自动从此 API 中获取数据,但不幸的是,站点所有者不提供对实现的支持。抱歉,如果这是错误的提问网站,请把它移到其他地方。我找到了 [this][1],我认为这就是我想要做的,但不太明白。可能很明显,我在这个方面有点超出我的技术深度。
具体请求为:https://sitename/index#!/Activities/Activities_GetAll
我有以下文档中提到的客户端凭据和密码。我一直在尝试在 Visual Studio 中创建一个自定义连接器,使用链接的连接器作为模板。我注意到“授权类型”是不同的——我使用客户凭据,而他使用授权代码。我更改了我的赠款类型,但不知道这是否意味着它需要某种结构性更改。 API 文档如下,我正在改编的代码和我的尝试如下。我在连接器上的尝试设法与 API 对话,但 Visual Studio 返回对 Accesstoken 的请求 - 这是我尝试自动获取的请求,以便我可以在此处登录并查看我需要的信息。
API 文档:
下面定义的方法允许 API 的使用者 检索包含授权详细信息的 JSON Web 令牌 描述他们的用户帐户/API 凭证(例如哪些 角色/特权)。此令牌在 Authorization 标头中传递 作为不记名令牌,格式为:Bearer TOKEN。
将客户端凭据与 Identity Server 令牌端点一起使用 https://###/connect/token POST 也可以检索您的访问令牌 到期时被告知。
使用值 Bearer 将“授权”标头添加到您的请求中 你的访问令牌
一旦您的访问令牌过期,只需重复步骤 1
请求属性
您必须在请求正文中包含 x-www-form-urlencoded 数据:
client_id:YOUR_CLIENT_CREDENTIAL_ID
client_secret:你的密码
grant_type:client_credentials
范围:apiname
我的尝试:
// This file contains your Data Connector logic
section OuraCloudConnector;
// OuraCloud OAuth2 values
client_id = Text.FromBinary(Extension.Contents("client_id.txt"));
client_secret = Text.FromBinary(Extension.Contents("client_secret.txt"));
redirect_uri = "https://oauth.powerbi.com/views/oauthredirect.html";
token_uri = "https://id.#.ac.uk/connect/token";
authorize_uri = "https://id.#.ac.uk/connect/authorize";
logout_uri = "about:blank";
// Login modal window dimensions
windowWidth = 720;
windowHeight = 1024;
// OAuth2 scope
scope_prefix = "";
scopes = {
"#api"
};
[DataSource.Kind="OuraCloudConnector",Publish="OuraCloudConnector.Publish"]
shared OuraCloudConnector.Contents = (url as text) =>
let
source = Json.Document(Web.Contents(url))
in
source;
// Data Source Kind description
OuraCloudConnector= [
TestConnection = (dataSourcePath) => { "OuraCloudConnector.Contents",dataSourcePath },Authentication = [
OAuth = [
StartLogin=StartLogin,FinishLogin=FinishLogin,Refresh=Refresh,logout=logout
]
],Label = Extension.LoadString("DataSourceLabel")
];
// Data Source UI publishing description
OuraCloudConnector.Publish = [
Beta = true,Category = "Other",ButtonText = { Extension.LoadString("ButtonTitle"),Extension.LoadString("ButtonHelp") },LearnMoreUrl = "https://powerbi.microsoft.com/",SourceImage = OuraCloudConnector.Icons,SourceTypeImage = OuraCloudConnector.Icons
];
// Helper functions for OAuth2: StartLogin,FinishLogin,Refresh,logout
StartLogin = (resourceUrl,state,display) =>
let
authorizeUrl = authorize_uri & "?" & Uri.BuildQueryString([
response_type = "code",client_id = client_id,redirect_uri = redirect_uri,state = state,scope = GetScopestring(scopes,scope_prefix)
])
in
[
LoginUri = authorizeUrl,CallbackUri = redirect_uri,WindowHeight = 720,WindowWidth = 1024,Context = null
];
FinishLogin = (context,callbackUri,state) =>
let
// parse the full callbackUri,and extract the Query string
parts = Uri.Parts(callbackUri)[Query],// if the query string contains an "error" field,raise an error
// otherwise call TokenMethod to exchange our code for an access_token
result = if (Record.HasFields(parts,{"error","error_description"})) then
error Error.Record(parts[error],parts[error_description],parts)
else
TokenMethod("authorization_code","code",parts[code])
in
result;
Refresh = (resourceUrl,refresh_token) => TokenMethod("refresh_token","refresh_token",refresh_token);
logout = (token) => logout_uri;
// see "Exchange code for access token: POST /oauth/token" at https://cloud.ouraring.com/docs/authentication for details
TokenMethod = (grantType,tokenField,code) =>
let
queryString = [
grant_type = "client_credentials",client_secret = client_secret
],queryWithCode = Record.AddField(queryString,code),tokenResponse = Web.Contents(token_uri,[
Content = Text.ToBinary(Uri.BuildQueryString(queryWithCode)),Headers = [
#"Content-type" = "application/x-www-form-urlencoded",#"Accept" = "application/json"
],ManualStatusHandling = {400}
]),body = Json.Document(tokenResponse),result = if (Record.HasFields(body,"error_description"})) then
error Error.Record(body[error],body[error_description],body)
else
body
in
result;
Value.IfNull = (a,b) => if a <> null then a else b;
GetScopestring = (scopes as list,optional scopePrefix as text) as text =>
let
prefix = Value.IfNull(scopePrefix,""),addPrefix = List.Transform(scopes,each prefix & _),asText = Text.Combine(addPrefix," ")
in
asText;
OuraCloudConnector.Icons = [
Icon16 = { Extension.Contents("OuraCloudConnector16.png"),Extension.Contents("OuraCloudConnector20.png"),Extension.Contents("OuraCloudConnector24.png"),Extension.Contents("OuraCloudConnector32.png") },Icon32 = { Extension.Contents("OuraCloudConnector32.png"),Extension.Contents("OuraCloudConnector40.png"),Extension.Contents("OuraCloudConnector48.png"),Extension.Contents("OuraCloudConnector64.png") }
];
> // This file contains your Data Connector logic section
> OuraCloudConnector;
>
> // OuraCloud OAuth2 values client_id =
> Text.FromBinary(Extension.Contents("client_id.txt")); client_secret =
> Text.FromBinary(Extension.Contents("client_secret.txt")); redirect_uri
> = "https://oauth.powerbi.com/views/oauthredirect.html"; token_uri = "https://id.#.ac.uk/connect/token"; authorize_uri =
> "https://id.#.ac.uk/connect/authorize"; logout_uri = "about:blank";
>
> // Login modal window dimensions windowWidth = 720; windowHeight =
> 1024;
>
> // OAuth2 scope scope_prefix = ""; scopes = {
> "#api" };
>
> [DataSource.Kind="OuraCloudConnector",> Publish="OuraCloudConnector.Publish"] shared
> OuraCloudConnector.Contents = (url as text) =>
> let
> source = Json.Document(Web.Contents(url))
> in
> source;
>
> // Data Source Kind description OuraCloudConnector= [
> TestConnection = (dataSourcePath) => { "OuraCloudConnector.Contents",> Authentication = [
> OAuth = [
> StartLogin=StartLogin,> FinishLogin=FinishLogin,> Refresh=Refresh,> logout=logout
> ]
> ],> Label = Extension.LoadString("DataSourceLabel") ];
>
> // Data Source UI publishing description OuraCloudConnector.Publish =
> [
> Beta = true,> Category = "Other",> ButtonText = { Extension.LoadString("ButtonTitle"),> LearnMoreUrl = "https://powerbi.microsoft.com/",> SourceImage = OuraCloudConnector.Icons,> SourceTypeImage = OuraCloudConnector.Icons ];
>
> // Helper functions for OAuth2: StartLogin,> logout StartLogin = (resourceUrl,display) =>
> let
> authorizeUrl = authorize_uri & "?" & Uri.BuildQueryString([
> response_type = "code",> client_id = client_id,> redirect_uri = redirect_uri,> state = state,> scope = GetScopestring(scopes,scope_prefix)
> ])
> in
> [
> LoginUri = authorizeUrl,> CallbackUri = redirect_uri,> WindowHeight = 720,> WindowWidth = 1024,> Context = null
> ];
>
> FinishLogin = (context,state) =>
> let
> // parse the full callbackUri,and extract the Query string
> parts = Uri.Parts(callbackUri)[Query],> // if the query string contains an "error" field,raise an error
> // otherwise call TokenMethod to exchange our code for an access_token
> result = if (Record.HasFields(parts,"error_description"})) then
> error Error.Record(parts[error],parts)
> else
> TokenMethod("authorization_code",parts[code])
> in
> result;
>
> Refresh = (resourceUrl,> "refresh_token",refresh_token);
>
> logout = (token) => logout_uri;
>
> // see "Exchange code for access token: POST /oauth/token" at
> https://cloud.ouraring.com/docs/authentication for details TokenMethod
> = (grantType,code) =>
> let
> queryString = [
> grant_type = "client_credentials",> client_secret = client_secret
> ],> queryWithCode = Record.AddField(queryString,>
> tokenResponse = Web.Contents(token_uri,[
> Content = Text.ToBinary(Uri.BuildQueryString(queryWithCode)),> Headers = [
> #"Content-type" = "application/x-www-form-urlencoded",> #"Accept" = "application/json"
> ],> ManualStatusHandling = {400}
> ]),> body = Json.Document(tokenResponse),> result = if (Record.HasFields(body,"error_description"})) then
> error Error.Record(body[error],body)
> else
> body
> in
> result;
>
> Value.IfNull = (a,b) => if a <> null then a else b;
>
> GetScopestring = (scopes as list,optional scopePrefix as text) as
> text =>
> let
> prefix = Value.IfNull(scopePrefix,> addPrefix = List.Transform(scopes,> asText = Text.Combine(addPrefix," ")
> in
> asText;
>
>
> OuraCloudConnector.Icons = [
> Icon16 = { Extension.Contents("OuraCloudConnector16.png"),> Extension.Contents("OuraCloudConnector24.png"),> Extension.Contents("OuraCloudConnector32.png") },> Icon32 = { Extension.Contents("OuraCloudConnector32.png"),> Extension.Contents("OuraCloudConnector48.png"),> Extension.Contents("OuraCloudConnector64.png") } ];
我正在尝试改编的原始代码:
// This file contains your Data Connector logic
section OuraCloudConnector;
// OuraCloud OAuth2 values
client_id = Text.FromBinary(Extension.Contents("client_id.txt"));
client_secret = Text.FromBinary(Extension.Contents("client_secret.txt"));
redirect_uri = "https://oauth.powerbi.com/views/oauthredirect.html";
token_uri = "https://api.ouraring.com/oauth/token";
authorize_uri = "https://cloud.ouraring.com/oauth/authorize";
logout_uri = "https://login.microsoftonline.com/logout.srf";
// Login modal window dimensions
windowWidth = 720;
windowHeight = 1024;
// OAuth2 scope
scope_prefix = "";
scopes = {
"daily"
};
[DataSource.Kind="OuraCloudConnector",code) =>
let
queryString = [
grant_type = "authorization_code",Extension.Contents("OuraCloudConnector64.png") }
];
[1]: https://jussiroine.com/2019/02/building-a-custom-connector-for-power-bi-that-supports-oauth2-to-visualize-my-wellness-data/
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。