首页 > 解决方案 > Azure Datalake Gen1 到 Azure 分析服务的服务到服务身份验证失败

问题描述

我正在使用 Azure 数据湖 Gen1 和 Azure 分析服务。我正在使用 Azure 数据湖连接授权我的 Azure 分析服务数据模型。

对于此活动,Microsoft 维护了一个文档。我遵循同样的方式。基于本文档的理论,我创建了一个 PowerShell 脚本,它执行并带来 access_token。当我获得 access_token 时,我更新 Azure Analysis Services 数据模型连接部分的 XMLA 并部署它。

我曾尝试使用最终用户身份验证机制来实现它,但这不起作用。

当我部署和处理相同的模型时,它工作正常,但是当我在 1 小时后处理时,它给了我以下错误。

Failed to save modifications to the server. Error returned: '<pii>The credentials provided cannot be used for the DataLake source. (Source at https://mydatalake.azuredatalakestore.net/.)</pii>. The exception was raised by the IDbCommand interface.

Technical Details:
RootActivityId: 46646584-7ccb-4946-a38c-b91c1963e82c
Date (UTC): 9/13/2021 7:53:10 PM
<pii>The credentials provided cannot be used for the DataLake source. (Source at https://mydatalake.azuredatalakestore.net/.)</pii>. The exception was raised by the IDbCommand interface.
<pii>The credentials provided cannot be used for the DataLake source. (Source at https://mydatalake.azuredatalakestore.net/.)</pii>. The exception was raised by the IDbCommand interface.
The command has been canceled.. The exception was raised by the IDbCommand interface.
'.

我的 PowerShell 代码

$dataModelsList = "MY-DM-Cost-Test"
$datalakeName= 'mydatalakename'
$aasName= 'asazure://aspaaseastus2.asazure.windows.net/myaasname'

$password = ConvertTo-SecureString -String "lajsdfkjjfdakasjdfhjkud&98asdllfkf" -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",$password)
Connect-AzAccount -Credential $credential -Tenant $tenantID -ServicePrincipal

$authUrl = "https://login.windows.net/" + $tenantID + "/oauth2/token/"
$body = @{
    "resource" = "https://management.azure.com/";
    "grant_type" = "client_credentials";
    "client_id" = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    "client_secret" = "lajsdfkjjfdakasjdfhjkud&98asdllfkf"
}

$adlsToken = Invoke-RestMethod -Uri $authUrl –Method POST -Body $body

$date = Get-Date -Format r
$password = ConvertTo-SecureString -String $secretKey -AsPlainText -Force
$credentials = New-Object System.Management.Automation.PSCredential($ClientID,$password)
Connect-AzAccount -Credential $credentials -Tenant $tenantID

for($f = 0; $f -lt $dataModelsList.Count; $f++)
{
    if($dataModelsList.Count -eq 1)
    {
        $AASDatabaseName = $dataModelsList
    }
    else
    {
        $AASDatabaseName = $dataModelsList[$f]
    }

    Write-Output "Refreshing $AASDatabaseName data model ..."
    $updateDataSource = '
    {
        "createOrReplace": {
            "object": {
                "database": "'+$AASDatabaseName+'",
                "dataSource": "DataLake/https://'+$datalakeName+' azuredatalakestore net/",
            },
            "dataSource": {
                "type": "structured",
                "name": "DataLake/https://'+$datalakeName+' azuredatalakestore net/",
                "connectionDetails": {
                    "protocol": "data-lake-store",
                    "address": {
                        "url": "https://' + $datalakeName + '.azuredatalakestore.net"
                    }
                },
                "options": {
                    "pageSize": 999999999
                },
                "credential": {
                    "DataSourceKind": "DataLake",
                    "AuthenticationKind": "OAuth2",
                    "Expires": "'+$date+'",
                    "RefreshToken":"'+$adlsToken.access_token+'",
                    "token_type": "Bearer",
                    "scope": "user_impersonation",
                    "ext_expires_in": "'+$adlsToken.ext_expires_in+'",
                    "expires_on": "'+$adlsToken.expires_on+'",
                    "not_before": "'+$adlsToken.not_before+'",
                    "resource": "https://management.azure.com",
                    "AccessToken":"'+$adlsToken.access_token+'"
                }
            }
        }
    }'

    $result = Invoke-ASCmd -Server $AASServerName -Database $AASDatabaseName -Query $updateDataSource -Credential $credentials #-ServicePrincipal
}

上面的代码在响应之后返回。

token_type     : Bearer
expires_in     : 3599
ext_expires_in : 3599
expires_on     : 1631542903
not_before     : 1631539003
resource       : https://management.azure.com/
access_token   : eyxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxx-xxxx-xxxx-xx.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxx-xxx
                 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
                 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
                 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
                 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
                 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

据我了解,我的数据模型在 1 小时后无法刷新,因为我没有得到刷新令牌作为响应,所以在可能的帮助下,我可以获得新的访问令牌。但这对我来说只是一个想象的想法。

请帮助我了解为什么我的 Azure Analysis Services 数据模型在一小时后无法处理,然后使用上述脚本刷新凭据。

标签: powershelloauth-2.0azure-active-directoryazure-data-lakeazure-analysis-services

解决方案


您的令牌即将到期,这并不是一个真正的大问题,因为您可以测试您的令牌是否有效,如果不是,则获取一个新的。因此,令牌响应expires_on中有一个属性,即 1970-01-01T0:0:0Z UTC 之后的秒数,表示令牌何时到期。因此,我们可以通过以下方式简单地对此进行测试:

If(([datetime]::UtcNow - [datetime]'01/01/1970 00:00:00Z').totalseconds -gt $adlsToken.expires_on){ $adlsToken = Invoke-RestMethod -Uri $authUrl –Method POST -Body $body }

现在我们只是在你引用访问令牌之前把它放好,你应该已经准备好了。

    Write-Output "Refreshing $AASDatabaseName data model ..."
    If(([datetime]::UtcNow - [datetime]'01/01/1970 00:00:00Z').totalseconds -gt $adlsToken.expires_on){ $adlsToken = Invoke-RestMethod -Uri $authUrl –Method POST -Body $body }
    $updateDataSource = '

推荐阅读