I want to be able to call Databricks API from DevOps pipeline. I can do this usint personal access token for my account, however I want to make API calls user independent so I wanted to use Service principal (App registration). I followed this tutorial https://learn.microsoft.com/en-us/azure/databricks/dev-tools/api/latest/aad/service-prin-aad-token to create access token for the service principal, however I have 2 issues:
such generated token expires in 1 hour - is there any elegant was to automatically refresh it?
even when calling the ADB API using this token I get 403 unauthorized - is there anything else I should do? The app registration has Contributor role for the ADB service.
EDIT: Added API Permission for the AzureDatabricks in App registration and Granted admin consent, however still no luck.
So I found 3 possible solutions at the end.
Generate access token for service principal, generate management service token for service principal and use both of these to access Databricks API - reference
Use access token and management token to generate Databricks Personal access token for the service principal using Databricks Token API, then you can use it for Databricks CLI - reference
Authenticate to Databricks via CLI using AAD token (reference and Databricks CLI help):
az login --service-principal -u <app-id> -p <app-password> --tenant <tenant-id>
token_response=$(az account get-access-token --resource 2ff814a6-3304-4ab8-85cb-cd0e6f879c1d)
export DATABRICKS_AAD_TOKEN=$(jq .accessToken -r <<< "$token_response")
databricks configure --host https://<adb-url> --aad-token
such generated token expires in 1 hour - is there any elegant was to
automatically refresh it?
No, client credentials flow doesn't support refresh token. You can try to get a new token, please refer to this issue.
even when calling the ADB API using this token I get 403 unauthorized - is there anything else I should do? The app
registration has User role for the ADB service.
Make sure your service principal have a Contributor role assigned.
There are two kinds of resource in different situations.
API access for service principals that are Azure Databricks workspace users and admins
resource=2ff814a6-3304-4ab8-85cb-cd0e6f879c1d
API access for service principals that are not workspace users
resource=https://management.core.windows.net/
Related
All of the examples on the microsoft azure site having to do with a client application or a service principal having access to azure apis all show the graph apis as the example.
I got those to work, but what I need to do is access the azure service management apis.
If I take an auth token that works for the graph api and use it for the service management api, I get an "Authentication failed." error.
I have added the api permission for "azure service management" and the user_impersonation delegated permission type to my public client app, but the management apis still fail.
Am I going about this all wrong?
I get the idea that the service management apis are authenticated a different way since there's absolutely no mention of using them anywhere in any of the auth examples.
I suppose you are using the client application or a service principal to access azure resources. If so, you are using the client credential flow, but the user_impersonation of Azure Service Management API is a delegated permission, it will not take effect in this flow.
The permission is used to be consent by the user who login to the AD App e.g. in the auth code flow, when it has been consent by the user, the App will be able to represent the user to access the azure resources, note the permission is from the user, not the app. So if you want to use this flow, the user should have a role in the subscription or specific resources.
To access the azure resources with the client application or a service principal, you just need to add the service principal as an RBAC role in the Access control (IAM) of your subscription or specific resource, no need to add any API permission in Azure AD, see this link. Then the service principal will be able to access the azure resources.
When you getting the token to access the azure resources, e.g. call the REST APIs, the scope should be https://management.azure.com/.default, not the https://graph.microsoft.com/.default, you can just get the token for one resource in one time.
I'm building an Android app that will access Azure REST API and read some data from azure monitoring.
I'm having problem on the authentication process because not sure is it possible to use MSAL library to authenticate to access Azure REST API?
In your mentioned demo code that the resource is microsoft graph.
If you want to use Azure service management API, we need to change the resource to https://management.azure.com. And we need to assign role to the registried Application.
I am not familiar with preview SDK, but we also could do that with following way to get the access token for Azure management API.
By default the V2 application is not displayed in the Azure portal. So we need to consent the permission. Then we could found it in the Azure portal.
https://login.microsoftonline.com/{tenantId}/adminconsent?
client_id={clientId}
&state=12345
&redirect_uri={redirectUrl}
Then use the admin account to approve the consent. After that we could find the V2 application in the Azure portal and assign the role to application.
From this document, we could know that the v2.0 endpoint does not supportĀ OAuth 2.0 Resource Owner Password Credentials Grant.
So we could use the authorization code follow to get the access token.
get the authorization_code
https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/authorize?
client_id={clientId}&response_type=code
&redirect_uri={redirect_uri}
&response_mode=query
&scope=https://management.azure.com/user_impersonation
&state=12345
get access token
https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token?
scope=https://management.azure.com/.default
&client_id={clientId}
&grant_type=authorization_code
&redirect_uri={redirectUri}
&code =AQABAAIAAAC5una0EUFgTIF8ElaxtWjT6o1ePh...
Test Accesstoken
I have a web application running on Azure App Services. The front-end (javascript + html + css) communicates with the backend (Flask). Both are runing on the same app service instance.
My app is protected by Active Directory Authentication (configured using Azure Portal).
User authentication to the app works perfectly. When a user navigates to the app, they are redirected to the login for our azure AD tenant. When they try to sign in, their permission to the app is controlled by their membership to an azure AD group. This bit works as expected
The challenge is that the front-end needs to send authenticated requests in order for them to actually reach the backend. They must be authenticated using a service principal token, not the user's token. And to this end, we are using the new, recommended approach; Managed Service Identity (MSI), not the service principal account workflow directly.
There are 2 stages to this:
1) Adding the authorization header
2) Ensuring that the MSI principal has access (i.e. belongs to the AD group)
1) The server generates an access token using the below code:
credentials = azure_active_directory.MSIAuthentication()
session = credentials.signed_session()
return session.headers.get("Authorization")
We then add the {"Authorization": "Bearer "} header where is the result of the above code.
This appears to work as expected - we are seeing long alphanumeric access tokens
2) The tricky bit was ensuring the MSI was added to the AD group. The GUIs at myapps.microsoft.com and mygroups.microsoft.com only allow the adding of users. Instead, I used the Azure CLI and ran the following:
a) Retrieve MSI principal ID
msiobjectid=$(az webapp identity show --resource-group <resource-group-name> --name <azure app services name> --query principalId)
b) Add principal to group
az ad group member add --group <group name> --member-id $msiobjectid
We are still getting 401 Unauthorized and we have exhausted all documentation :(
I should note that I only completed step 2 (adding the principal to the azure AD group via Azure CLI) about an hour ago. Perhaps there is a delay?
Edit: my scenario is closest to https://github.com/uglide/azure-content/blob/master/articles/app-service-api/app-service-api-dotnet-service-principal-auth.md except a) I'm using MSI, not a direct service principal and b) I have an extra layer of authorization, which is the ad groups, restricting access to the app to a few users rather than the whole tenant.
I believe you got this all backwards.
Your scenario is SPA + backend.
What you need to implement is OAuth 2.0 implicit grant flow as described here.
Source for diagram: dzimchuk.net
With the resulting access_token placed in the user-agent's session storage you can then call your backend. Use adal.js to make your life easier.
Since your Python backend IS a confidential client, you can now request an access token from the MSI endpoint for the desired audience (Azure resource), call it then filter the results so that it matches your access rights logic.
Note that at the time of writing only a subset of Azure resources are able to consume MSI-issued access tokens.
My requirement is simple. I want to login to Azure through my shell script in non-interactive mode, but "az login -u username -p password" command gives the following error:
Get Token request returned http error: 400 and server response: {"error":"invalid_grant","error_description":"AADSTS70002: Error validating credentials. : SAML token is invalid. : The element with ID 'xxxxxx' was either unsigned or the signature was invalid.
Some site told me to create a service principal. Now my question is, what is a service principal, and how do I create a service principal so that I can execute my commands (for creating different resources like app gateway) from my shell script?
Please refer to this official document.
An Azure service principal is a security identity used by user-created
apps, services, and automation tools to access specific Azure
resources. Think of it as a 'user identity' (login and password or
certificate) with a specific role, and tightly controlled permissions
to access your resources. It only needs to be able to do specific
things, unlike a general user identity. It improves security if you
only grant it the minimum permissions level needed to perform its
management tasks.
If you want to create a new service principal(sp) with Azure CLi 2.0. You could login with your Azure AD user. Then execute following command.
az ad sp create-for-rbac --name {appId} --password "{strong password}"
The result like below:
{
"appId": "a487e0c1-82af-47d9-9a0b-af184eb87646d",
"displayName": "MyDemoWebApp",
"name": "http://MyDemoWebApp",
"password": {strong password},
"tenant": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
}
appId is your login user, password is login password.
After the sp is created, you also need give it Contributor role, then you could manage your Azure resource.
az role assignment create --assignee <objectID> --role Contributor
Now, you could login in non interctive mode with following command.
az login --service-principal -u <appid> --password {password-or-path-to-cert} --tenant {tenant}
Service principal just work as an impersonation for user in Azure AD. Refer - https://sanganakauthority.blogspot.com/2019/04/how-to-create-service-principal-or-app.html
Using this you can perform any type of management task against Azure using REST APIs. This way you avoid need of providing credentials in pop up and hence help to automate things in Azure using REST APIs.
Here your go: Use portal to create an Azure Active Directory application and service principal that can access resources.
When you have an application that needs to access or modify resources, you must set up an Azure Active Directory (AD) application and assign the required permissions to it. This approach is preferable to running the app under your own credentials because:
You can assign permissions to the app identity that are different than your own permissions. Typically, these permissions are restricted to exactly what the app needs to do.
You do not have to change the app's credentials if your responsibilities change.
You can use a certificate to automate authentication when executing an unattended script.
We are using Azure AD B2C and I'm trying to implement the changePassword function for signed-in users. We have followed this tutorial https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-devquickstarts-graph-dotnet, and we have succeeded to make it worked.
But we want signed-in users to have the possibility to change their existing password (directly in applications). We found this method (https://msdn.microsoft.com/fr-fr/library/azure/ad/graph/api/functions-and-actions#changePassword) but we failed to make it work...
What is the standard workflow for using AD Graph API in AD B2C with signed-in users ?
I have an application linked to a B2C tenant. I have created both Android and iOS apps and I am able to connect and get tokens thanks to the sign-up or sign-in policy, this point is OK...
In parallel I have created a service app in order to use the AD Graph API (thanks to the first link above).
We have suceeded in testing some operations like get the lists of users, find a specific user, change some.... But now I want to use the method "changePassword" for the connected users (second li) and I have failed using it. I don't know which access token to provide, both tests (using the token from the app service credential or using the access token received thanks to the signin policy) have failed ??
Other question, is it normal that the app service I have created with PowerShell is not visible in the Azure Portal ??
Thanks ;)
Other question, is it normal that the app service I have created with PowerShell is not visible in the Azure Portal ??
We can locate the service principal which created by PowerShell by searching the appPrincipalId like below:
Update
To perform the change password REST API of Azure AD Graph, we need to provide the delegate access token. In this scenario, we can use resource owner password credentials flow which require users' username and password for the authentication. To use this flow we can register the service principal like below:
$app = New-AzureRmADApplication -DisplayName "appPS2" -HomePage "https://adb2cfei.onmicrosoft.com/appPS2" -IdentifierUris "https://adb2cfei.onmicrosoft.com/appPS2" -Password "123"
New-AzureRmADServicePrincipal -ApplicationId $app.ApplicationId
Then we need to login the Azure classic portal to grant the delegate permission Directory.AccessAsUser.All as figure below:
Here is the code to acquire the token using the resource owner password credentials flow:
Post: https://login.microsoftonline.com/adb2cfei.onmicrosoft.com/oauth2/token
resource=https%3a%2f%2fgraph.windows.net&client_id={ $app.ApplicationId}&grant_type=password&username=fx%40adb2cfei.onmicrosoft.com&password={currentPassword}&client_secret=123
Then we can use this token to change the password of the sign-in user like below:
POST: https://graph.windows.net/adb2cfei.onmicrosoft.com/me/changePassword?api-version=1.6
authorization: bearer {access_token}
content-type: application/json
{
"currentPassword":"{currentPassword}",
"newPassword":"{newPassword}"
}