我正在尝试使用来自Azure AD的访问令牌连接到我的Azure SQL实例。我正在遵循这篇教程:https://medium.com/microsoftazure/deploying-a-dacpac-to-azure-with-azure-pipelines-and-managed-identity-89703d405e00
但是,这种方法似乎有些不对劲。
第一件事是通过以下方式确保我的用户已在数据库中设置:
CREATE USER [myemail@email.com] FROM EXTERNAL PROVIDER WITH DEFAULT_SCHEMA=[dbo]
这与此答案中的过程相同:https://stackoverflow.com/a/62161471/1963929
然后,我测试了SQL Server Management Studio和Azure Data Studio,两者都完美地工作。
但是,当我在 Powershell 中尝试完全相同的操作时,它不起作用,我得到的只是可怕的 Login failed for user '<token-identified principal>'.
以下是我尝试的内容:
$conn = New-Object System.Data.SqlClient.SQLConnection
$conn.ConnectionString = "Server=tcp:azure-sql.database.windows.net,1433;Initial Catalog=default;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30"
$conn.AccessToken = $(az account get-access-token --resource=https://database.windows.net/ --query accessToken)
$conn.Open()
当我连接到数据库时,收到的错误信息如下:
MethodInvocationException: Exception calling "Open" with "0" argument(s): "Login failed for user ''."
随后我想:“也许我在使用错误的设置”,因此我尝试使用我的应用程序用于连接同一数据库的客户端ID。这一次,我测试了多个作用域:无、.default
和 user_impersonation
。
$clientid = "azure-data-studio-client-id"
$request = Invoke-RestMethod -Method GET -Uri "https://login.microsoftonline.com/organizations/oauth2/v2.0/devicecode" -Body @{client_id=$clientid; scope="https://database.windows.net/user_impersonation"} -ContentType "application/x-www-form-urlencoded"
$request.message
$tokens = Invoke-RestMethod -Method POST -Uri "https://login.microsoftonline.com/organizations/oauth2/v2.0/token" -Body @{client_id=$clientid; grant_type="urn:ietf:params:oauth:grant-type:device_code"; code = $request.device_code} -ContentType "application/x-www-form-urlencoded"
$accesstoken = $tokens.access_token
所以我认为Azure数据工作室可能具有超能力,使用另一个帐户而不进行CREATE USER
,我得到了正确的错误。
这个错误证明了CREATE USER
是必要的,但它并没有解释为什么我无法通过Powershell执行此操作。
我还尝试了Node和Tedious:
const dbConfig = {
authentication: {
type: "azure-active-directory-access-token",
options: {
token: token
}
},
server: getDatabasePerEnvironment(environment),
database: databaseName,
options: {
trustServerCertificate: false,
encrypt: true,
port: 1433
}
};
const connection = new tedious.Connection(dbConfig);
同样的错误:
"连接错误:用户登录失败。
有人知道我做错了什么吗?