認証の処理

認証の種類

拡張機能では、1 つまたは複数の種類の認証をサポートできます。 認証の種類ごとに、資格情報の種類が異なります。 Power Query のエンド ユーザーに表示される認証 UI は、拡張機能がサポートしている資格情報の種類によって決まります。

サポートされている認証の種類の一覧は、拡張機能の [データ ソースの種類] の定義の一部として定義されます。 各認証値は、特定のフィールドを含んだレコードです。 次の表は、各種類の必須フィールドを示したものです。 特に指定しない限り、すべてのフィールドが必須となります。

認証の種類 フィールド 説明
匿名 匿名 (Implicit とも呼ばれる) 認証の種類にはフィールドがありません。
OAuth StartLogin OAuth フローを開始するための URL と状態情報を提供する関数。

OAuth フローの実装セクションに進みます。
FinishLogin OAuth フローに関連する access_token とその他のプロパティを抽出する関数。
最新のステータスに更新 (省略可能) 更新トークンから新しいアクセス トークンを取得する関数。
Logout (省略可能) ユーザーの現在のアクセス トークンを無効にする関数。
Label (省略可能) この AuthenticationKind の既定のラベルをオーバーライドできるテキスト値。
Aad AuthorizationUri Microsoft Entra ID 承認エンドポイントを返す text 値または 1 変数関数 (例: "https://login.microsoftonline.com/common/oauth2/authorize")。

[Microsoft Entra ID 認証] セクションに移動します。
リソース サービスの Microsoft Entra ID リソース値を返す text 値または 1 変数関数。
範囲 (省略可能)認証フローの一部として要求するスコープの一覧を返す text 値または 1 変数関数。 複数のスコープ値はスペースで区切る必要があります。 スコープの値は、アプリケーション ID URI なしのスコープ名にする必要があります (例: Data.Read)。 指定しない場合は、user_impersonation スコープが要求されます。
UsernamePassword UsernameLabel (省略可能) 資格情報 UI の [ユーザー名] テキスト ボックスの既定のラベルを置き換えるテキスト値。
PasswordLabel (省略可能) 資格情報 UI の [パスワード] テキスト ボックスの既定のラベルを置き換えるテキスト値。
Label (省略可能) この AuthenticationKind の既定のラベルをオーバーライドできるテキスト値。
Windows UsernameLabel (省略可能) 資格情報 UI の [ユーザー名] テキスト ボックスの既定のラベルを置き換えるテキスト値。
PasswordLabel (省略可能) 資格情報 UI の [パスワード] テキスト ボックスの既定のラベルを置き換えるテキスト値。
Label (省略可能) この AuthenticationKind の既定のラベルをオーバーライドできるテキスト値。
キー KeyLabel (省略可能) 資格情報 UI の [API キー] テキスト ボックスの既定のラベルを置き換えるテキスト値。
Label (省略可能) この AuthenticationKind の既定のラベルをオーバーライドできるテキスト値。

次のサンプルは、OAuth、キー、Windows、基本 (ユーザー名とパスワード)、および匿名資格情報をサポートするコネクタの認証レコードを示しています。

例:

Authentication = [
    OAuth = [
        StartLogin = StartLogin,
        FinishLogin = FinishLogin,
        Refresh = Refresh,
        Logout = Logout
    ],
    Key = [],
    UsernamePassword = [],
    Windows = [],
    Anonymous = []
]

現在の資格情報へのアクセス

現在の資格情報は、Extension.CurrentCredential 関数を使用して取得できます。

拡張性が有効になっている M データ ソース関数は、拡張機能の資格情報スコープを自動的に継承します。 ほとんどの場合、現在の資格情報に明示的にアクセスする必要はありませんが、次のような例外があります。

  • カスタム ヘッダーまたはクエリ文字列パラメーターで資格情報を渡します (API キー認証タイプを使用している場合など)。
  • ODBC または ADO.NET 拡張機能の接続文字列プロパティを設定します。
  • OAuth トークンのカスタム プロパティを確認します。
  • OAuth v1 フローの一部として資格情報を使用します。

Extension.CurrentCredential 関数はレコード オブジェクトを返します。 これに含まれるフィールドは認証タイプに固有です。 次の表に詳細を示します。

フィールド 説明 使用ページ
AuthenticationKind この資格情報 (UsernamePassword、OAuth など) に割り当てられている認証の種類の名前が含まれます。 すべて
ユーザー名 ユーザー名の値 UsernamePassword、Windows
Password パスワードの値。 通常は UsernamePassword とともに使用されますが、Key にも設定されます。 Key、UsernamePassword、Windows
access_token OAuth アクセス トークンの値。 OAuth
プロパティ 当該の資格情報の他のカスタム プロパティを含んだレコード。 通常、認証フロー中に access_token とともに返される他のプロパティ (refresh_token など) を保存するために OAuth とともに使用されます。 OAuth
キー API キーの値。 このキー値は、[パスワード] フィールドでも使用できます。 デフォルトでは、マッシュアップ エンジンは、この値が基本認証パスワード (ユーザー名なし) であるかのように、このキーを Authorization ヘッダーに挿入します。 このタイプの動作が望ましくない場合は、オプション レコードで ManualCredentials = true オプションを指定する必要があります。 キー
EncryptConnection データソースへの暗号化された接続を必須とするかどうかを決定する論理値。 この値はすべての認証種類で使用できますが、データ ソース 定義で EncryptConnection が指定されている場合にのみ設定されます。 すべて

次のコード サンプルでは、API キーの現在の資格情報にアクセスし、それを使ってカスタム ヘッダー (x-APIKey) を設定しています。

例:

MyConnector.Raw = (_url as text) as binary =>
let
    apiKey = Extension.CurrentCredential()[Key],
    headers = [

        #"x-APIKey" = apiKey,
        Accept = "application/vnd.api+json",
        #"Content-Type" = "application/json"
    ],
    request = Web.Contents(_url, [ Headers = headers, ManualCredentials = true ])
in
    request

OAuth フローの実装

認証の種類として OAuth を使用すると、拡張機能でサービスのカスタム ロジックを実装できます。 これを行うために、拡張機能は StartLogin (OAuth フローを開始するための認可 URI を返す) と FinishLogin (アクセス トークンの認可コードを交換する) の関数を提供します。 拡張機能では、必要に応じて、Refresh (更新トークンを新しいアクセス トークンと交換する) と Logout (現在の更新トークンとアクセス トークンを期限切れにする) の関数も実装できます。

Note

Power Query の拡張機能は、クライアント コンピューターで実行されているアプリケーション内で評価されます。 データ コネクタでは、OAuth フロー内で機密シークレットを使用しないようにしてください。ユーザーが拡張機能やネットワーク トラフィックを調べて、シークレットを探り出す可能性があります。 共有シークレットに依存しないフローの提供の詳細については、「OAuth パブリック クライアントによるコード交換の証明キー RFC (PKCE とも呼ばれる)」を参照してください。 このフローの実装は、Microsoft の GitHub サイトで確認できます。

OAuth 関数のシグネチャには 2 つのセットがあります。1 つは最小限のパラメータを含む元のシグネチャ、もう 1 つはより多くのパラメータを受け入れる高度なシグネチャです。 ほとんどの OAuth フローは、元のシグネチャを使って実装できます。 実装内でシグネチャの種類を組み合わせて使用することもできます。 関数呼び出しは、パラメーターの数 (および種類) に対応したものとなります。 パラメータ名は考慮されません。

詳細については、GitHub サンプル を参照してください。

オリジナルの OAuth 署名

StartLogin = (dataSourcePath, state, display) => ...;

FinishLogin = (context, callbackUri, state) => ...;

Refresh = (dataSourcePath, refreshToken) =>  ...;

Logout = (accessToken) => ...;

高度なOAuth署名

高度なシグネチャに関する注意事項:

  • すべてのシグネチャは、clientApplication レコードの値を受け取ります (これは将来の使用のために予約されています)。
  • すべてのシグネチャは dataSourcePath を受け入れます (多くサンプルでは resourceUrl とも呼ばれます)。
  • Refresh 関数は oldCredential パラメーターを受け取ります。これは、FinishLogin 関数によって返された、以前の record (または Refresh に対する以前の呼び出し) です。
StartLogin = (clientApplication, dataSourcePath, state, display) => ...;

FinishLogin = (clientApplication, dataSourcePath, context, callbackUri, state) => ...;

Refresh = (clientApplication, dataSourcePath, oldCredential) =>  ...;

Logout = (clientApplication, dataSourcePath, accessToken) => ...;

Microsoft Entra ID 認証

Aad 認証は、Microsoft Entra ID のための特殊なバージョンの OAuth です。 組織アカウント認証をサポートした組み込み Power Query コネクタと同じ Microsoft Entra ID クライアントが使用されます。 詳細は、クイックスタート ガイド「カスタム コネクタ用の Microsoft Entra の構成」にあります。

Note

Microsoft Entra ID に対して独自の OAuth フローを実装した場合、自分のテナントに対して条件付きアクセスを有効にしているユーザーは、Power BI サービスを使って更新を行う際に問題に遭遇する可能性があります。 これは、ゲートウェイベースの更新には影響を与えませんが、Power BI サービスからの更新をサポートした認定済みコネクタには影響を与えます。 ユーザーは、Power BI サービスを通じて Web ベースの資格情報を構成する際に、パブリック クライアント アプリケーションを使ったコネクタに起因する問題に遭遇する可能性があります。 このフローによって生成されたアクセス トークンは、最終的に、最初の認証に使用されたコンピューター (つまり、会社のネットワーク上でデータ ソースの資格情報を構成するユーザーのコンピューター) とは異なるコンピューター (つまり、会社のネットワーク上ではなく、Azure データ センター内の Power BI サービス) で使用されます。 組み込みの種類である Aad では、Power BI サービスで資格情報を構成する際に別の Microsoft Entra ID クライアントを使用することで、この問題が回避されます。 このオプションは、OAuth 認証を使用するコネクタでは使用できません。

ほとんどのコネクタは、AuthorizationUriフィールドと Resource フィールドに値を指定する必要があります。 どちらのフィールドにも、text 値を指定するか、text value を返す 1 つの引数関数を指定できます。

AuthorizationUri = "https://login.microsoftonline.com/common/oauth2/authorize"
AuthorizationUri = (dataSourcePath) => FunctionThatDeterminesAadEndpointFromDataSourcePath(dataSourcePath)
Resource = "77256ee0-fe79-11ea-adc1-0242ac120002"   // Microsoft Entra ID resource value for your service - Guid or URL
Resource = (dataSourcePath) => FunctionThatDeterminesResourceFromDataSourcePath(dataSourcePath)

Uri ベースの識別子を使用するコネクタは、Resource 値を提供する必要はありません。 デフォルトでは、値はコネクタの Uri パラメータのルート パスと等しくなります。 データ ソースの Microsoft Entra ID リソースがドメイン値と異なる (たとえば、GUID を使用している) 場合は、Resource 値を指定する必要があります。

Aad 認証のサンプル

次の場合、データ ソースは共通テナントを使用してグローバル クラウド Microsoft Entra ID をサポートします (Azure B2B はサポートされません)。 .default スコープを要求すると、Power Query クライアント アプリケーション ID に対して以前に承認されたすべてのスコープを持つトークンが返されます。

Authentication = [
    Aad = [
        AuthorizationUri = "https://login.microsoftonline.com/common/oauth2/authorize",
        Resource = "77256ee0-fe79-11ea-adc1-0242ac120002", // Entra Application ID URI or app guid
        Scope = ".default"
    ]
]

次の場合、データ ソースは OpenID Connect (OIDC) または同様のプロトコルに基づくテナント検出をサポートします。 この機能により、コネクタは、データ ソース パス内の 1 つ以上のパラメーターに基づいて、使用する正しい Microsoft Entra ID エンドポイントを決定できます。 この動的な検出アプローチにより、コネクタが Azure B2B をサポートできるようになっています。


// Implement this function to retrieve or calculate the service URL based on the data source path parameters
GetServiceRootFromDataSourcePath = (dataSourcePath) as text => ...;

GetAuthorizationUrlFromWwwAuthenticate = (url as text) as text =>
    let
        // Sending an unauthenticated request to the service returns
        // a 302 status with WWW-Authenticate header in the response. The value will
        // contain the correct authorization_uri.
        // 
        // Example:
        // Bearer authorization_uri="https://login.microsoftonline.com/{tenant_guid}/oauth2/authorize"
        responseCodes = {302, 401},
        endpointResponse = Web.Contents(url, [
            ManualCredentials = true,
            ManualStatusHandling = responseCodes
        ])
    in
        if (List.Contains(responseCodes, Value.Metadata(endpointResponse)[Response.Status]?)) then
            let
                headers = Record.FieldOrDefault(Value.Metadata(endpointResponse), "Headers", []),
                wwwAuthenticate = Record.FieldOrDefault(headers, "WWW-Authenticate", ""),
                split = Text.Split(Text.Trim(wwwAuthenticate), " "),
                authorizationUri = List.First(List.Select(split, each Text.Contains(_, "authorization_uri=")), null)
            in
                if (authorizationUri <> null) then
                    // Trim and replace the double quotes inserted before the url
                    Text.Replace(Text.Trim(Text.Trim(Text.AfterDelimiter(authorizationUri, "=")), ","), """", "")
                else
                    error Error.Record("DataSource.Error", "Unexpected WWW-Authenticate header format or value during authentication.", [
                        #"WWW-Authenticate" = wwwAuthenticate
                    ])
        else
            error Error.Unexpected("Unexpected response from server during authentication.");

<... snip ...>

Authentication = [
    Aad = [
        AuthorizationUri = (dataSourcePath) =>
            GetAuthorizationUrlFromWwwAuthenticate(
                GetServiceRootFromDataSourcePath(dataSourcePath)
            ),
        Resource = "https://myAadResourceValue.com", // Microsoft Entra ID resource value for your service - Guid or URL
        Scope = ".default"
    ]
]

他の種類の認証

Kerberos ベースのシングル サインオンなど、この記事で説明されていない他の種類の認証については、追加のコネクタ機能の記事を参照してください。