I'm working on an application (one of the core microservices) which will call the Azure ADLS Gen 2 to store files (in a filesystem) for further processing by other components.
I'm trying to obtain an OAuth token for the authentication purposes by calling Azure authentication endpoint using the preliminarily created service principal.
The PowerShell code I'm using to create a service principal:
Add-AzAccount -Subscription <SUBSCRIPTION ID>
$sp = New-AzADServicePrincipal -DisplayName <PRINCIPAL NAME>
Sleep 20
New-AzRoleAssignment -RoleDefinitionName Contributor -ServicePrincipalName $sp.ApplicationId
$sp.ApplicationId
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($sp.Secret)
$UnsecureSecret = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
$UnsecureSecret
I'm using the values of $sp.ApplicationId
as < Azure AD application client ID>
and $UnsecureSecret
as < Azure AD application client secret>.
The Azure AD application is then configured with API permissions:
I've added the Azure AD application as a STORAGE BLOB DATA CONTRIBUTOR to the storage account's IAM blade.
Next, I'm going yo obtain an OAuth token.
Below are the calls I've made using Postman:
GET
https://login.microsoftonline.com/<TENANT ID>/oauth2/token
Headers
Content-Type: application/x-www-form-urlencoded
Request body
grant_type:client_credentials
client_id: <Azure AD application client ID>
client_secret: <Azure AD application client secret>
scope: https://storage.azure.com/.default
After this call I'm able to get the successful response:
{
"token_type": "Bearer",
"expires_in": "3600",
"ext_expires_in": "3600",
"expires_on": "1574686915",
"not_before": "1574683015",
"resource": "00000002-0000-0000-c000-000000000000",
"access_token": "eyJ0eX<..>" .
}
Then I'm trying to create a filesystem by using the following request:
PUT
https://<STORAGE ACCOUNT NAME>.dfs.core.windows.net/<FILESYSTEM NAME>?resource=filesystem
Headers
Authorization: Bearer <JWT token>
x-ms-date: Mon, 25 Nov 2019 12:00:00 GMT
x-ms-version: 2019-02-02
And constantly getting the following error:
{
"error": {
"code": "InvalidAuthenticationInfo",
"message": "Server failed to authenticate the request.
Please refer to the information in the www-authenticate header.
\nRequestId:a6bf42d7-a01f-0006-1d88-a304da000000\nTime:2019-11-25T12:05:32.3049492Z"
}
}
I have tried different scopes but it doesn't help:
https://dfs.core.windows.net/.default
https://blob.core.windows.net/.default
I can reproduce your issue, the Contributor
RBAC role is enough, no need to add any API permission
, the issue was caused by the way you request the token, when using the v1.0
endpoint, you need to use resource: https://storage.azure.com/
.
GET https://login.microsoftonline.com/<TENANT ID>/oauth2/token
grant_type:client_credentials
client_id: <Azure AD application client ID>
client_secret: <Azure AD application client secret>
resource: https://storage.azure.com/
Or you can change the request URL to v2.0
endpoint, it will also work.
GET https://login.microsoftonline.com/<TENANT ID>/oauth2/v2.0/token
grant_type:client_credentials
client_id: <Azure AD application client ID>
client_secret: <Azure AD application client secret>
scope: https://storage.azure.com/.default
Test: