Imagine that I have:
An Azure Function (func) that exposes an http endpoint (api1)
An Azure App Service (service1) that has a Managed Service Identity configured (msi1)
I would like to configure everything in such a way that service1 can make an HTTP request to api1, and api1 knows that the request is coming from msi1. Furthermore, I would like to be able to configure service1 in the Azure portal to either allow or disallow access to api1.
Basically I want to configure which app services have access to which functions (or vice-versa) as much as possible in the Azure portal, without having to create and manage API tokens or keys in application settings.
I would like to stress that this is service-to-service - service1 does not request any login information from its users.
I believe that this should be possible, but most of the documentation that I have come across describes situations in which a user logs in via Microsoft/Facebook/Google/Whatever and gets an access token in that way. I know that I can use client credentials on an application registration to create a valid bearer token; but that shouldn't be necessary because service1 is executing under the security context of msi1.
As juunas said, you could refer to his article to secure azure function from app service using a managed identity.
Register your api1 as app in AAD and using powershell to assign permission to the service1 MSI. It seems that assigning permission to MSI is not supported on Portal, so you could just use powershell to assign it. Here is a similar thread that assign permission to MSI you could refer to.
Related
I am wondering if it is possible to restrict access to an azure web app (it is functioning as an api, so I dont want public access just via the url) to API Manager through managed identity? Everything I can see is for using Azure HTTP Functions, not to a web app
Im assuming by doing so that users in the AD can also access the web app directly?
Yes, it is possible.
Your back-end API will need to check for either:
An application permission (appRole) defined on the API app registration and assigned to the Managed Identity through PowerShell
Or check that the object id in the token matches the Managed Identity
In the first option, other apps won't be able to use the API directly unless that permission is granted to that client application by an Application Admin/Global Admin.
The second option outright prevents other apps from using the API directly.
In both cases, you'll have the API Management policy get an access token targeting your API app registration.
I've done some reading in regards to Azure AD, but I still can't wrap my head around it. The confusion might be there also because of how my company tries to standarize how a azure project should look like.
Imagine I have two things: SPA app (served by App Service) and API (on this App Service, ASP.NET). The approach that the company is suggesting is that both of those should have their App Registrations.
Now, I'd like the API to have access to Ms Graph. In order to do that, looking at other projects, I updated my AppRegistration to request for Ms Graph roles, Admin gave consent, and in API I used ConfidentialClient to reuse my Client Id/Secret to get token and then access MsGraph.
Why the hustle? Why not just use Managed Identity of my API and grant needed permissions using New-AzureAdServiceAppRoleAssignment?
Why do I need App Registration here? Do I need both? Should I access Ms Graph using my App Registration and confidential client in my API? How does my App Service relate to my App Registration in code?
Let's take a step back and define a few things that will make things easy to understand:
Your app service: this is just a compute environment, just as Azure Functions, Logic apps or VMs. This is where your code executes.
Azure AD App registration: this is an identity that you can use in your code to identify your service and get access to resources you need. The Azure AD app registration has several capabilities:
build an app in one tenant and used in multiple tenants (multi-tenant app)
consent framework, allowing you to request permissions and the owner to grant it
define roles and permissions, so that you can configure who is allowed to call your API
3-legged OAuth flows which allows you to act on behalf of the user
confidential client flows which allow the app to act on its own (like a service account)
Azure Managed Identities: this is also an identity that you can use to identify your service and get access to resources you need. It only has a subset of the capabilities of Azure AD app.
confidential client flow which allows the identity to act on its own (like a service account)
credentials managed for you by the platform
Depending on what you are trying to do, you can use one or the other identity: rarely if ever you will need both.
In your case, you need an identity to act on its own. So either app registration or managed identity will work. Your API may benefit from using an app registration if you want to define roles and permissions. The primary advantage of using an app registration in your scenario is that the consent model is simpler to use and understand. The disadvantage is that you need to manage credentials for the app. This pro/con is reversed when using a managed identity.
You don’t need both at a time. These are two ways to get the access of MS graph for your API. They are used for different purpose.
Managed Identity (Using System Identity)
· Use the Managed Identity if you don’t require your API to be authenticate from any provider.
· A managed identity from Azure Active Directory allows App Service to access resources through role-based access control (RBAC), without requiring app credentials
· It known as safe way to give your web app access to data is to use a system-assigned managed identity
· Currently, there's no option to assign any permissions(MS graph) through the Azure portal for Managed Identity
· When we do Manged Identity of any application its show only for Enterprise application.
Reference : Tutorial - Web app accesses Microsoft Graph as the app - Azure App Service | Microsoft Docs
App Registration.
· To set the authentication and authorization of your app from different provider its need your app registration id.
· It’s required to configure a service and get a token from the Microsoft identity platform endpoint that service can use to call Microsoft Graph under its own identity.
·In this using portal you can add permission (MS Graph) for your application.
Reference : https://learn.microsoft.com/en-us/graph/auth-v2-service
We aim to collect data from the Azure Management APIs. These APIs provide information on the resources we have running in Azure, the consumed budget, etc (example). Following our design choices, we prefer to exclusively use Azure Data Factory to make the HTTP requests and store the data into our data lakes. This is fairly obvious, using the REST linked service. However, we struggle to correctly set up the OAuth2 authentication dance with this method.
Our first idea was to store the token and the refresh token within the Azure Key Vault. A series of HTTP requests within the pipeline would then test whether the token is still valid or otherwise use the refresh token to get a new token. The downside to this approach is that the token within the Azure Key Vault is never updated, when needed, and that the logic becomes more complex.
Alternatively, we were trying to set up the authorization through combination of a registered app and service principal to our Azure AD account. The REST linked service within Data Factory can be created with a service principal, which would then handle most of the information of the scope and consent. The service principal is also accompanied with a Azure app, which would hold the token etc. Unfortunately, we are unable to make this setup function correctly.
Questions we have:
Can we actually use a service principal / app to store our OAuth2 tokens? If so, will these be automatically refreshed within our app?
How do we assign the correct privileges / authorizations to our app that it can use this (external) API?
Is the additional logic with HTTP calls within Azure Data Factory pipeline needed to update the tokens or can these apps / service principals handle this?
Thank you for your time and help!
It is not a good idea to store the tokens in the keyvault, because they will expire.
In your case, two options for you to use.
Use service principal to auth
Use managed identity to auth(best practice)
Steps to use service principal to auth:
1.Register an application with Azure AD and create a service principal.
2.Get values for signing in and create a new application secret.
3.To call the Azure REST API e.g. Resources - List you mentioned, your service principal needs the RBAC role in your subscription.
Navigate to the Azure portal -> Subscription -> add your service principal as a Contributor/Owner role in the subscription like below.
4.In the linked service, configure it like below, fix them with the values got from step 2.
Don't forget to replace the {subscriptionId} in the Base URL.
https://management.azure.com/subscriptions/{subscriptionId}/resources?api-version=2020-06-01
5.Test the linked service with a copy activity, it works fine.
Steps to use managed identity to auth:
1.Make sure your data factory has enabled the MSI(managed identity), if you create it in the portal or powershell, MSI will be enabled automatically, don't worry about that.
2.Navigate to the Subsctiption in the portal, add the role to the MSI like step 3 in Steps to use service principal to auth, just search for your ADF name in the bar, the MSI is essentially a service principal with the same name of your ADF, which is managed by azure.
3.Then in the linked service, just change it like below.
At last, answer your questions.
Can we actually use a service principal / app to store our OAuth2 tokens? If so, will these be automatically refreshed within our app?
As I mentioned, it is not a good idea, just use the service principal/MSI to auth like the steps above.
How do we assign the correct privileges / authorizations to our app that it can use this (external) API?
To use the Azure REST API, just assign the RBAC roles like above, specify the correct AAD resource e.g. https://management.azure.com in this case.
Is the additional logic with HTTP calls within Azure Data Factory pipeline needed to update the tokens or can these apps / service principals handle this?
No need to do other steps, when you use the configuration above, essentially it will use the client credential flow to get the token in the background for you automatically, then use the token to call the API.
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 got a HTTP triggered azure function, which is using by one of my web applications. The user of this site would be anybody who signed up to the site. Now I want to implement authentication to the azure function in such a way that only signed up user would able access the azure function through my web site. I could see many built-in authentications like azure functions, OAuth using Azure AD and other identity providers etc. I am looking for to way to authenticate users signed-up through my website, not with identity providers.
One solution I can think of is while signing up a register that user to Azure AD. Then while calling the API pass user credentials to the API and validate against AD. Can somebody please advice this is a good solution? If not please advise the best solution for my use case.
I don't want to use any external auth provider
Just referring to the documentation:
Azure functions HTTP Trigger - Authorization keys
While keys may help obfuscate your HTTP endpoints during development, they are not intended as a way to secure an HTTP trigger in production. To learn more, see Secure an HTTP endpoint in production.
The second link Secure an HTTP endpoint in production gives more insights on how to secure HTTP triggered functions:
To fully secure your function endpoints in production, you should consider implementing one of the following function app-level security options:
Turn on App Service Authentication / Authorization for your function app. The App Service platform lets use Azure Active Directory (AAD) and several third-party identity providers to authenticate clients. You can use this to implement custom authorization rules for your functions, and you can work with user information from your function code. To learn more, see Authentication and authorization in Azure App Service and Working with client identities.
Use Azure API Management (APIM) to authenticate requests. APIM provides a variety of API security options for incoming requests. To learn more, see API Management authentication policies. With APIM in place, you can configure your function app to accept requests only from the IP address of your APIM instance. To learn more, see IP address restrictions.
Deploy your function app to an Azure App Service Environment (ASE). ASE provides a dedicated hosting environment in which to run your functions. ASE lets you configure a single front-end gateway that you can use to authenticate all incoming requests. For more information, see Configuring a Web Application Firewall (WAF) for App Service Environment.
In my opinion you can do this in following ways.
Using function level Authorization key (Not preferred but easy)
If your web app is the only one that will access the function app you may enable authorization directly on the function. Any one who wants to access the function has to pass the key else you get 401 . Since you want your function to be accessed directly by users then you have to create additonal end point in your web site that will call function app on users' behalf and pass the key. You can find more about here
Authorization Key
Using Azure B2C or AD
You are thinking on the right lines. If your website is external consumer accessed then you may consider Azure B2C. You get many out of box functionalities including sign up using social logins and you may not need to save the users separately. The flow remains the same , users get authenticated by Azure AD (or B2C) and token is issued. The token is then passed when calling azure functions.