我怎样才能让这个自定义连接器正确地进行身份验证?

问题描述

我希望 PowerBI 自动从此 API 中获取数据,但不幸的是,站点所有者不提供对实现的支持。抱歉,如果这是错误的提问网站,请把它移到其他地方。我找到了 [this][1],我认为这就是我想要做的,但不太明白。可能很明显,我在这个方面有点超出我的技术深度。

具体请求为:https://sitename/index#!/Activities/Activities_GetAll

我有以下文档中提到的客户端凭据和密码。我一直在尝试在 Visual Studio 中创建一个自定义连接器,使用链接的连接器作为模板。我注意到“授权类型”是不同的——我使用客户凭据,而他使用授权代码。我更改了我的赠款类型,但不知道这是否意味着它需要某种结构性更改。 API 文档如下,我正在改编的代码和我的尝试如下。我在连接器上的尝试设法与 API 对话,但 Visual Studio 返回对 Ac​​cesstoken 的请求 - 这是我尝试自动获取的请求,以便我可以在此处登录并查看我需要的信息。

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 (将#修改为@)