Используйте Azure Powershell Runbook, чтобы добавить пользователя AzureAD как db_owner в базу данных SQL Azure.

У меня есть Runbook Powershell, в котором я пытаюсь добавить пользователя AzureAD в качестве владельца базы данных в базе данных SQL Azure.

## Connect
$servicePrincipalConnection = Get-AutomationConnection -Name "AzureRunAsConnection"
Connect-AzureAD `
    -TenantId $servicePrincipalConnection.TenantId `
    -ApplicationId $servicePrincipalConnection.ApplicationId `
    -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint 

## Generate new access token
$cert = Get-AutomationCertificate -Name 'AzureRunAsCertificate'
# Set Resource URI to Azure Database
$resourceAppIdURI = 'https://database.windows.net/'
# Set Authority to Azure AD Tenant
$authority = 'https://login.windows.net/' + $servicePrincipalConnection.TenantId
$ClientCred = [Microsoft.IdentityModel.Clients.ActiveDirectory.ClientAssertionCertificate]::new($servicePrincipalConnection.ApplicationId, $cert)
$authContext = [Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext]::new($authority)
$authResult = $authContext.AcquireTokenAsync($resourceAppIdURI, $ClientCred)
$AccessToken = $authResult.Result.AccessToken

## Execute sql
$AccessToken
$connectionString = "Data Source=MYCOOLSQLSERVER.database.windows.net;Initial Catalog=MYCOOLDATABASE;Connect Timeout=30"
$connection = New-Object -TypeName System.Data.SqlClient.SqlConnection($connectionString)
$query = "Create User [[email protected]] From EXTERNAL PROVIDER;"

$command = New-Object -TypeName System.Data.SqlClient.SqlCommand($query, $connection)
$connection.AccessToken = $AccessToken
$connection.Open()
$command.ExecuteNonQuery()
$connection.Close()

Я получаю сообщение об ошибке ниже, где [email protected] является пользователем AzureAD.

Не удалось разрешить принципала [email protected].

Я что-то упустил?

Как только пользователь будет создан, я намерен использовать Alter role, чтобы сделать его db_owner.

Ссылки: https://blogs.technet.microsoft.com/stefan_stranger/2018/06/06/connect-to-azure-sql-database-by-obtain-a-token-from-azure-active-directory-aad/

https://techcommunity.microsoft.com/t5/Azure-Database-Support-Blog/Azure-SQL-Database-Token-based-authentication-with-PowerShell/ba-p/369078


comment
Подскажите, пожалуйста, можно ли выполнить команду «Создать пользователя [[email protected]] из ВНЕШНЕГО ПРОВАЙДЕРА»; в SSMS?   -  person Jim Xu    schedule 09.09.2019
comment
Да, работает через SSMS. Но в SSMS я подключаюсь с использованием своего собственного пользователя AzureAD, тогда как в приведенном выше сценарии используется SPN учетной записи службы автоматизации.   -  person bit    schedule 09.09.2019


Ответы (2)


Оказывается, есть недокументированный способ сделать это. Обнаружил его с помощью службы поддержки Azure.

Фактически, используемый SQL-запрос:

СОЗДАТЬ ПОЛЬЗОВАТЕЛЯ [[email protected]] С SID = $ hexSid, тип E;

Здесь $hexSid можно получить с помощью следующего SQL-запроса

  1. Получите ObjectId пользователя AzureAD

$objectId = (Get-AzureADUser -ObjectId "[email protected]").ObjectId

  1. Используйте приведенный ниже SQL, чтобы получить sid

DECLARE @sid = uniqueidentifier = cast ('$ objectId' как uniqueidentifier) ​​select cast (@sid as varbinary (max))

  1. В идеале эффективный запрос должен был бы напрямую использовать @sid, но это невозможно, поскольку для With SID требуется жестко закодированное значение. Поэтому мне пришлось обрабатывать вывод sid-запроса отдельно, как показано ниже:
$result = $command.ExecuteScalar() # result is byte array
$hexSid = ($result | ForEach-Object ToString X2) -Join ''  # convert to hex format
$hexSid = "0x$hexSid"

С этими изменениями код, о котором идет речь, работает нормально!

Фактически, мы передаем только objectId пользователя AzureAD в запросе Create User.

person bit    schedule 10.09.2019
comment
Я понимаю подход, а также проголосовал за ответ, так как пришел к такому же выводу. однако у меня возникли проблемы с созданием шестнадцатеричного значения. Не могли бы вы быть более подробным - person Tiju John; 15.07.2020
comment
Что за беда? Вам нужно только выполнить SQL, чтобы сначала получить hexSid, а затем преобразовать его в шестнадцатеричный формат. - person bit; 17.07.2020

в этом сценарии мы должны использовать поток паролей пользователей, чтобы эта команда работала. Пожалуйста, попробуйте PS ниже:

$tenant='<your tenant name/id>'
$username='<SQL admin account>'
$password='<SQL admin password>'
$appid='<app id>'
$appsec='<app secret>'

$SQLServerName = '<azure sql servername>'
$DatabaseName='<db name>'

$body=@{
    "grant_type"="password";
    "resource"="https://database.windows.net/";
    "client_id"=$appid;
    "client_secret"=$appsec;
    "username"=$username;
    "password" = $password;
}
 
$result=Invoke-RestMethod -Uri "https://login.windows.net/$tenant/oauth2/token" -Method POST -Body $body 



$conn = New-Object System.Data.SqlClient.SQLConnection 
$conn.ConnectionString = "Data Source=$SQLServerName.database.windows.net;Initial Catalog=$DatabaseName;Connect Timeout=30"
$conn.AccessToken = $result.access_token

Write-Verbose "Connect to database and execute SQL script"
$conn.Open() 

$query = 'CREATE USER [Account] FROM EXTERNAL PROVIDER;'

$command = New-Object -TypeName System.Data.SqlClient.SqlCommand($query, $conn)     
$Result = $command.ExecuteScalar()
$Result
$conn.Close() 

Перед запуском сценария is необходимо предоставить разрешение доступа к API Azure SQL для имени пользователя для вашего SPN в Azure AD здесь: введите описание изображения здесь  введите описание изображения здесь Предоставьте разрешение после добавлено:  введите здесь описание изображения

Кстати, пожалуйста, убедитесь, что учетная запись администратора SQL и имя участника-службы являются членами группы администраторов Active Directory: < img src = "https://i.stack.imgur.com/rkx5i.png" alt = "введите описание изображения здесь">

Это работает на моей стороне, и запись была успешно добавлена:  введите описание изображения здесь

Если что-то неясно, пожалуйста, дайте мне знать :)

person Stanley Gong    schedule 10.09.2019
comment
На самом деле я пытаюсь напрямую указать нам SPN, что, как указано в документации, возможно. Мне не разрешено обновлять разрешения в соответствии с определениями API в клиентском Tenant. - person bit; 10.09.2019
comment
Я вижу, я боюсь, что вам следует использовать для этого способ аутентификации пользователя + приложения ... в этом сценарии требуется разрешение user_impersonation - person Stanley Gong; 11.09.2019