Can someone help me understand the difference between the Service Principal created when I create an App Registration in AAD and the Managed Identity that gets created when I enable "System Assigned" on the Identity blade of an App Service?
We have an App Service that we are developing that we have created an App Registration for and we have also enabled the System Assigned identity. When we go into Enterprise Applications under AAD and search for our app, it comes up with 2 entries. One for the Managed Identity and one for the Service Principal created as part of the App Registration. We are trying to understand which one we would use to give the app permissions to write to an Azure SQL DB.
Managed Identities are essentially service principals wrapped with Microsoft logic to make accessing resources simpler. Although, sometimes adding more layers may complicate things, the idea is to make it easier, simpler, and less consumer interactive.
For your scenario, you'll want to think about what you would like to do. Would you like to have more control and implement your own logic with an Azure SQL DB protected by AAD, or try utilizing Microsoft's Managed Identity to protect/access the Azure SQL DB resource. (Ideally the Managed Identity path should be less work)
The tutorial for using Managed Identities to access an azure SQL db from an app service can be found here :
https://learn.microsoft.com/en-us/azure/app-service/app-service-web-tutorial-connect-msi
The docs for protecting an Azure SQL DB using Azure AD can be found here :
https://learn.microsoft.com/en-us/azure/sql-database/sql-database-aad-authentication
Furthermore Managed Identities are explained in the official Microsoft documentation here :
https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview
It's important to note that there are two kinds of Managed Identities.
From the documentation:
A system-assigned managed identity is enabled directly on an Azure
service instance. When the identity is enabled, Azure creates an
identity for the instance in the Azure AD tenant that's trusted by the
subscription of the instance. After the identity is created, the
credentials are provisioned onto the instance. The lifecycle of a
system-assigned identity is directly tied to the Azure service
instance that it's enabled on. If the instance is deleted, Azure
automatically cleans up the credentials and the identity in Azure AD.
A user-assigned managed identity is created as a standalone Azure
resource. Through a create process, Azure creates an identity in the
Azure AD tenant that's trusted by the subscription in use. After the
identity is created, the identity can be assigned to one or more Azure
service instances. The lifecycle of a user-assigned identity is
managed separately from the lifecycle of the Azure service instances
to which it's assigned.
The picture from the official docs also gives a good example of a VM using MSI(Managed Service Identity).
This is Provided below:
In addition to that, the App Service Managed Identity documentation can be found here :
https://learn.microsoft.com/en-us/azure/app-service/overview-managed-identity
I would like to elaborate a little further as the topic around service principals and app registrations in Azure can be confusing.
As you noticed, a service principal will get created in your AAD tenant when you turn on system-assigned managed identity for a resource in Azure. This service principal is tied to the lifecycle of your resource or in other words: If you delete your App Service, Azure will delete the service principal for you [2].
Beside service principals, there are other object types that live inside a tenant: User principals and application objects. As the name suggests, user principals identify a user while a service principal can be used to either identify a resource in Azure or an application object. To both types of principals you can assign roles, as you mentioned you can create a new user in your database and use the system-assigned identity (Service Principal 1 in the image below) to let Azure SQL know that your App Service has permissions to access the database [3]. This is marked in red in the image.
When you create an app registration, two objects are created: An application object and a service principal in your tenant (this is "Service Principal 2") [4]. You could now use this service principal as well to give it permissions to access the database (marked in orange in the image) but this service principal is not tied to your Azure App Service and doesn't represent it. In other words, if you want to use Service Principal 2 in your App Service, beside creating a user for this service principal in your database you'd additionally also need to get an access token for this service principal whenever you create a new SQL connection to the database in your application. It's possible but a bit more inconvenient and the beauty of using system-assigned identities is that your App Service knows about its service principal already and you don't have to manage it on your own (e.g., delete it when your App Service gets deleted).
Long story short: Use the system-assigned managed identity in your use case.
[2] https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview#managed-identity-types
[3] https://learn.microsoft.com/en-us/azure/app-service/app-service-web-tutorial-connect-msi#grant-permissions-to-managed-identity
[4] https://learn.microsoft.com/en-us/azure/active-directory/develop/app-objects-and-service-principals
You can only use the managed identity that you have enabled in your App Service for authentication to AAD which eventually allows you to access your Azure SQL instance based on roles/permissions. I'd tried using the service principal/Enterprise Application created as part of App Registration process for authentication and it didn't work.
The way I see it is that the App Service is what runs/hosts your application and only this managed identity/SP is available to your running application for authentication to AAD.
The Service principal/Enterprise Application is being used internally for some other purpose and, it is not available to our application for authentication to AAD.
Just a wee note. App Registration may live without Service Principal. App Registration may represent an application that is consumed, not necessarily the consumer.
Managed Identity is solely a client-based identity.
E.g. Your App Service is acting as a client, when accessing Azure SQL. In this case you don't need an app registration and its service principal at all. You will only need a Managed Identity (which is a Service Principal).
When your App Service (A) is opposed to access another App Service (B) then again your App Service (A) does not need an app registration. But App Service B needs to have an app registration.
Imo when you want to use the credential-less approach in Azure, an app registration is acting as the server part and a Managed Identity (system - or user-assigned) is considered to be the client part.
Related
Recently I watched a course on Pluralsight.com, Getting Started with Azure Active Directory for Developers. In the section, Service Principals->Apps and Service Principals, the author said that we can create a service principal without app, and it's also possible to create an app without service principal. But he didn't show how to do so, and I cannot find out online how to do so either. So how can we do so? And can we do so from the Azure Portal?
Yes it is possible to create an azure ad app without creating a service principle(using powershell only) . Through portal if you will create it will create service princple along with app.
You can view the newly created app in the App registrations blade, under All applications in the Azure portal
Powershell cmdlet.
New-AzureADApplication -DisplayName "MTS Demo App"
It is not possible to create a service principle without creating an application. Service Principle will create an azure active directory as an application
# Create a service principal for a resource group using a preferred name and role
az ad sp create-for-rbac --name myServicePrincipalName \
--role reader \
--scopes /subscriptions/mySubscriptionID/resourceGroups/myResourceGroupName
Note : For creating Service Principle you need to admin role at the subscription level and Adminsitator role at Azure Active Directory Level.
Reference : https://learn.microsoft.com/en-us/cli/azure/create-an-azure-service-principal-azure-cli#code-try-0***
I have registered an app in AAD and as a admin I want to provide permission for user to read or access the data of particular group list not all group available in my MS team account. How can be achieve this any idea?
No. Azure AD app doesn't provide such a feature that scopes Microsoft Graph application permissions to specific Microsoft Teams/Groups.
The client credential flow is used to as an authorization grant typically when the client is acting on its own behalf. When you give Group.Read.All or Files.Read.All or other similar application permissions, it means the client has access to all the files/groups across the entire tenant.
You can achieve this by implement the business logic in your code. For example, providing a configuration file which includes the particular groups'/teams' object ids. And then restrict the access for users to only these groups/teams by checking if the object ids (which users are trying to access) are in the configuration file.
My WebJobs app uses an Azure Storage Queue Trigger. It runs smoothly when the connection string to the storage account the queue app listens to is set-up in the configuration; i.e. appsettings.json.
{ "AzureWebJobsStorage": "connString" }
However, I do not want to expose any secrets in the configuration and more importantly, I'd like to avoid access keys altogether, relying on Azure AD and role-based access control (RBAC) instead.
For this, I have assigned the service principal running the application the Queue Data Contributor Role and switched in the connectivity type of the queue from Access key to Azure AD in the portal.
My intent was to use the Azure Identity SDK and new-up an instance of DefaultAzureCredential and use that to connect my app to the queue.
But as far as I can see, the Webjobs SDK expects to connect using acres key, i.e. a connection string. When using the standalone storage queue client, this is straightforward, since I can create the queue client using above-mentioned Identity SDK. However in WebJobs it seems I cannot override the means of connecting to that queue.
How can I access that queue via Azure AD and RBAC? Any help on this is greatly appreciated!
Currently, the bindings used with the WebJobs SDK do not support using the identity SDK.
Instead, you could store the connection string in KeyVault and use the KeyVault References feature which relies on Managed Identity to fetch the secret from KeyVault at runtime.
Directly using the respective client SDK would be the way to go otherwise.
when an application is registered to Azure AD via consent, a service principal is created. The application object resides in another tenant.
From my understanding, the applicationID refers back to the application object.
When the application object resides in another tenant, is it possible to find out in which tenant based on the applicationID? Or may there is another value on a service principal which is an indicator where the application object resides (if its not an app registration).
BR
Thomas
Yes, you can. But you need to make sure the service principal is in your tenant.
Navigate to the Azure Active Directory-> Enterprise applications in the portal. Search for the APPLICATION ID (select the Application Type with All Applications option), then you will find the service principal, copy the OBJECT ID.
Then navigate to the MS Graph Explorer, call the MS Graph API : Get servicePrincipal as below, in the result you could find the "appOwnerOrganizationId": "xxxxxxxx","publisherName": "Organization name" which is the tenant id and name you are looking for.
GET https://graph.microsoft.com/beta/servicePrincipals/{OBJECT ID}
I have a multitenant ASP.NET application using OpenIdConnect and Azure AD as an Identity provider for Office 365. When the user is authenticated I receive my claims in ClaimsPrincipal.Current.
I wanted to identify a user and store this id reference in my database. I asked this question.
It was replied that
When trying to identify a user uniquely [NameIdentifier] should be your go-to choice.
But it seems that the NameIdentifier claim, http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier
depends on the application. Precisely, if I create another application in Azure AD then, the NameIdentifier will not be the same for the same real Office365 user. Keep in mind that the we may have to create another Azure AD manifest (because we could need other scopes) and we should be able to find back the same end-users.
Meanwhile, I remarked another claim: ObjectIdentifier http://schemas.microsoft.com/identity/claims/objectidentifier
It seems that ObjectIdentifier, is the same for all Azure AD-secured application for a given Office 365 user.
Can you explain precisely the difference between those two claims? And more importantly, can you confirm that the ObjectIdentifier can be used as an "universal" identifier for a user in any Office 365 subscription.
Precisely, if I create another application in Azure AD then, the NameIdentifier will not be the same for the same real Office365 user.
I made a quick test as following:
Register a multi-tenant-webapp and single-tenant-webapp in AD Contoso.
Log in with user1#contoso.onmicrosoft.com and get the name identifier in both web applications, it turns out the name identifier are the same in both applications. So the name identifier should be able to identify users cross applications, but it can not be used to identify the user in Azure AD.
For the object identifier, it is a GUID which you can used to identify a user in Azure AD. For example, you can use object identifier to query the user in Azure AD.
Powershell:
$msolcred = get-credential
connect-msolservice -credential $msolcred
get-msoluser -ObjectId "{guid:object_identifier}"
And more importantly, can you confirm that the ObjectIdentifier can be used as an "universal" identifier for a user in any Office 365 subscription.
Based on my understanding, the object identifier is a GUID which can identify for a user in Office 365 subscriptions.
Or to put it another way:
The NameIdentifier is the GUID of the Application which is registered in Azure AD. This won't change whether it's a single or multi-tenant application. It won't matter if you are using client credentials (i.e. AppId and AppSecret) to authenticate AS the application or using logging using real user credentials (i.e. delegated), the NameIdentifier will remain the same.
The ObjectIdentifier is the User Principal Name (UPN) for the user when using delegation or Service Principal Name (SPN) of the application when using client creds.
The reason you see different ObjectIdentifier values when an application is multi-tenant is that there is a separate and unique SPN in EACH TENANT which points back to the ApplicationGUID in the tenant where the application is registered. This SPN is used to assign rights to the application against resources in each tenant.