I created Azure service bus and clients are able to access the service bus using Shared Access Token. All this is working fine and now we want to implement authentication using Azure AD.
This is what we know so far:
Using Azure AD we will register client(s).
Each registered client will get an ID and Secret.
We will use this ID, Secret and AppId (Id of service bus) to get access token from Azure AD
This call will return an access token.
We then pass the access token to Azure Service Bus using request headers to post or get messages.
My question is how does Azure service bus actually validates this token ? I have seen another example where API or Service which is consumed by the client, validates the access token using a program like this: https://github.com/mauliksoni/aad-token-validation/blob/main/DotNetFramewrork/validate.cs & then only user is allowed to access the token.
Ideally Service should validate the access token on its own and there should not be any need to validate tokens by externals programs.
You don't need to do any external validation, as long as the service principal got the right RBAC role to perform the desired operation(send/receive/management), the service will do the remaining token validation for you.
Related
Is it possible to send a request to Microsoft Azure OCR using authorization token instead of Subscription-Key? I searched a lot on the internet but found nothing and thus I would be thankful If you can help.
Basically, you can follow this workflow:
users send a request to your App for an access token.
Your app checks the user's permission(you should implement the procedure yourself), if vailed, your app uses a subscription key to get an access token for the user by Authenticate with Azure Active Directory and
reply this token to the user.
Users use this token to call the OCR service from client-side.
As the doc indicated, you should create a new service principal in your Azure AD, and go to Azure Portal=>your Azure cognitive service => Access control to add a cognitive service user role to the new created SP:
So that it could request an access token for this service from Azure AD by request below:
By using this access token, we will be able to call vision ocr service:
Endpoint in this case:
I need to receive list of user's subscriptions using service principal.
For user which has token now it's easy - A GET call to https://management.azure.com/subscriptions?api-version=<API_version>
But how is ti possible for any user in Azure AD, if my service principal has enough permissions in Azure AD?
Thanks in advance!
You could not use the service principal to get the user's subscriptions(i.e. the subscriptions that the user can access in one tenant) via this REST API.
When you use the REST API Subscriptions - List, it will make the request depends on the access token passed, if you use the service principal to get the token, you can just get the subscriptions that the service principal can access, not the user.
In this case, your option here is to use the auth code flow or implicit grant flow(the Try it button in the doc use it, not recommended) to get the token, then use the token to call the REST API to list the subscriptions that the user can access.
I'm trying to call an Azure function from an API Management instance by using Managed Identity.
I have set a System Managed Identity to my APIM instance.
I have granted the Contributor role to this identity on the Azure Function App.
I have also change the App Service Authentication to AD.
Now I'm trying to call the function from an API.
I have two issues:
First One: when I use the authentication-managed-identity policy to get a token, I got an error when I use the audience https://myfunctionapp.azurewebsites.net. AD tells me that this app is not registered in the tenant
Second: If I retrieve a token for https://management.azure.com, I got a token but I received a 401 Unauthorized error from the Azure Function.
Maybe I'm just trying to get a token on the wrong audience, but unfortunately the audience of functions is not listed in the document (for service bus for example, there is a common URI to use, also for KeyVault, ...).
I think that I probably missed something in the picture...
Thanks.
You need to use the authentication-managed-identity policy to authenticate with a backend service using the managed identity of the API Management service.
https://learn.microsoft.com/en-us/azure/api-management/api-management-authentication-policies#ManagedIdentity
EDIT
1-In your APIM application on Azure AD,
grab the Application ID assigned for enterprise application.
2-Then go to Platform features in your Azure Function App, and click on Authentication / Authorization.
3-Select Azure Active Directory as the authentication provider, and the management mode "express".
4-Back to authentication-managed-identity policy, set the Application ID from step 1 as the resource.
you need to add the url in apim required resource. If you're planning to use delegated flow. To check if the issue is with the url registration you can use the AppId instead. This will at least tell you if the token can be retrieved.
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.
I have a native client (console app) from where I am trying to access a WebAPI. The API has been authenticated using Azure AAD. So, in order to acquire a token using the method AuthenticationContext.AcquireToken(), ClientCredentials are needed which in turn need the "client secret" that one is supposed to receive from Azure while registering the application to Azure AAD. Is there any other way for me to be able to retrieve the access token to access the WebAPI?
If you want to call the WebAPI on behalf of (or "as") the current user then you can use the Resource Owner Credentials flow. Otherwise, the client credential flow you described is the appropriate solution.
Note that your client app should be registered separately from your WebAPI in AAD.