如何在 C# 中使用服务主体(clientId 和 clientSecret)为 Azure Data Lake Store(Gen-2)创建 SAS 令牌?
Posted
技术标签:
【中文标题】如何在 C# 中使用服务主体(clientId 和 clientSecret)为 Azure Data Lake Store(Gen-2)创建 SAS 令牌?【英文标题】:How to create SAS token for Azure Data Lake Store (Gen-2) using service principals (clientId and clientSecret) in C#? 【发布时间】:2020-06-30 12:00:06 【问题描述】:我有 Data Lake Store (Gen-2) 的 clientId 和 clientSecret,我正在寻找一种使用 C# 以编程方式为其创建 SAS 令牌的方法。我浏览了文档,但没有找到创建 SAS 令牌的方法。任何指导将不胜感激。谢谢。
按照 Md Farid Uddin Kiron 的建议,我使用了这段代码但没有成功:
//Token Request End Point
string tokenUrl = $"https://login.microsoftonline.com/<tenantId>.onmicrosoft.com/oauth2/token";
var tokenRequest = new HttpRequestMessage(HttpMethod.Post, tokenUrl);
//I am Using client_credentials as It is mostly recommended
tokenRequest.Content = new FormUrlEncodedContent(new Dictionary<string, string>
["grant_type"] = "client_credentials",
["client_id"] = "--------",
["client_secret"] = "-------",
["resource"] = "https://<datalake gen2 name>.dfs.core.windows.net/"
);
dynamic json;
AccessTokenClass results = new AccessTokenClass();
HttpClient client = new HttpClient();
var tokenResponse = client.SendAsync(tokenRequest).GetAwaiter();
json = tokenResponse.GetResult().Content.ReadAsStringAsync().GetAwaiter();
results = JsonConvert.DeserializeObject<AccessTokenClass>(json);
它给了我状态 400 错误。
【问题讨论】:
请看这个answerfollow the token part
。希望这会有所帮助。如果您仍有任何疑虑,请告诉我。
@MdFaridUddinKiron,感谢您的回复,但它不起作用。
能否请您分享您的问题或代码 sn-p 以便它可以重现。
@MdFaridUddinKiron,我已经更新了问题并添加了代码,它给了我 400 状态错误。
您的resource
似乎不正确。应该是https://datalake.azure.net/
【参考方案1】:
如果要使用 Azure AD 访问令牌访问 Azure Data Lake gen2,请参考以下代码
-
创建服务主体并为 sp 分配 Azure RABC 角色。
az login
az account set --subscription "<your subscription id>"
# it will assign Storage Blob Data Contributor to the sp at subscription level
az ad sp create-for-rbac -n "mysample" --role Storage Blob Data Contributor
-
代码
string tokenUrl = $"https://login.microsoftonline.com/<tenantId>.onmicrosoft.com/oauth2/token";
var tokenRequest = new HttpRequestMessage(HttpMethod.Post, tokenUrl);
//I am Using client_credentials as It is mostly recommended
tokenRequest.Content = new FormUrlEncodedContent(new Dictionary<string, string>
["grant_type"] = "client_credentials",
["client_id"] = "--------",
["client_secret"] = "-------",
["resource"] = "https://storage.azure.com/"
);
dynamic json;
AccessTokenClass results = new AccessTokenClass();
HttpClient client = new HttpClient();
var tokenResponse = client.SendAsync(tokenRequest).GetAwaiter();
json = tokenResponse.GetResult().Content.ReadAsStringAsync().GetAwaiter();
results = JsonConvert.DeserializeObject<AccessTokenClass>(json);
如果要创建sas token,请参考以下步骤
通过 Azure 门户获取帐户密钥
代码
var key = account key you copy";
var accountName = "testadls05";
StorageSharedKeyCredential credential = new StorageSharedKeyCredential(accountName, key);
AccountSasBuilder sas = new AccountSasBuilder
Protocol = SasProtocol.None,
Services = AccountSasServices.Blobs,
ResourceTypes = AccountSasResourceTypes.All,
StartsOn = DateTimeOffset.UtcNow.AddHours(-1),
ExpiresOn = DateTimeOffset.UtcNow.AddHours(1),
;
sas.SetPermissions(AccountSasPermissions.All);
var uri = $"https://accountName.dfs.core.windows.net/";
UriBuilder sasUri = new UriBuilder(uri);
sasUri.Query = sas.ToSasQueryParameters(credential).ToString();
DataLakeServiceClient service = new DataLakeServiceClient(sasUri.Uri);
var result =service.GetFileSystems().First();
Console.WriteLine(result.Name);
【讨论】:
感谢您的帮助,但我想使用非密钥的服务主体生成 Data Lake Gen-2 的 SAS。在您的最新代码中,您使用帐户密钥生成 SAS。 @BilalShafqat 我们无法使用服务主体来创建 sas 令牌:docs.microsoft.com/en-us/rest/api/storageservices/… @BilalShafqatb 您还有其他顾虑吗?【参考方案2】:以下代码可用于使用服务原则为 datalake gen2 创建 SAS 令牌:
这里密码是Client Secret,用户名是ClientId。
$securePassword = ConvertTo-SecureString -AsPlainText -Force -String $Password
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $UserName, $securePassword
Connect-AzAccount -Credential $Credential -ServicePrincipal -Tenant $Tenant -Subscription $SubscriptionName
Write-Host -ForegroundColor Green "Creating an account level SAS Token.."
## Get the storage account
$storageAcc=Get-AzStorageAccount -ResourceGroupName $resourceGroupName -Name $storageAccName
## Get the storage account context
$ctx=$storageAcc.Context
## Creates an account-level SAS token.
New-AzStorageAccountSASToken -Context $ctx -Service Blob,File,Table,Queue -ResourceType Service,Container,Object -Permission "racwdlup" -StartTime "2020-06-18" -ExpiryTime "2022-06-18"
【讨论】:
以上是关于如何在 C# 中使用服务主体(clientId 和 clientSecret)为 Azure Data Lake Store(Gen-2)创建 SAS 令牌?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 MQTT 中使用特定类型的 clientId 创建客户端?
在 C# 中,如何使用反射计算表达式主体输出函数中包含的属性数量?
如何根据 clientid 和客户端密码在 Runbook 中运行 powershell 脚本
App Engine 和 Google 游戏服务 clientId 冲突
Spring Oauth2:如何获取所有clientIds?
如何在 POST 中发送 ClientId 和 ClientSecret,而不是在带有 ClientCredentialsAccessTokenProvider 的标头中发送