Store User info in app database for Azure AD Authenticated users - asp.net-core

When creating ASP.NET Core web app, if you use Azure AD for authentication, is it possible to store user info in your app database? And if so, is there a best practice approach to doing this?
I'd like to store user role info in my app's database; I know you can use AD groups but
(a) I'd like to be able control this from within the app and
(b) I don't know if I have permissions to create new groups in my company's Azure AD.

yes, you can. After authentication with Azure AD, you can get userinfo from ID token if you are using OIDC. Then you can store the userinfo in your app's local database.

For (a), you wanna control user role in your app which used to edit in azure portal. Then you may take microsoft graph api user role into consideration. You may check the link if this api is what you need.
(b) create new groups, this can achieved by this api.
Calling microsoft graph api required an azure ad application which can be assigned api permission by admin, then it can be used to generate access token to call the api.

Related

Get AzureAd users of specific tenant for Multi tenant .net-core web app

I have a multi tenant app registered on Azure Ad, and each time a user logs in I want to get all the users of the organization. I configured the app in my code and on Azure
My .net-core app with azure and
ms graph authorizations
So when someone logs in it asks for "read" permissions. Now I want to get all users of a specific tenant, I tried first on Postman
to get the access token and
get users with the token
it worked for this tenant because it is the app owner on Azure, but when I try with another tenant which is using my app, it doesn't work.
I got the access token for another tenant and then
I have an error
I'm a little bit confused, is it the right way to do that or did I miss something ?
EDIT : It works if someone of the other tenant grant admin consent here on Azure Ad, it adds Application Permissions but I don't want to do it on Azure but on the App

Interacting with Azure Service from Azure Function from Client app on behalf of the user (user impersonation)

Context
I have a client app, represented through an Azure Active Directory app that needs to send a HTTP request to a HTTP trigger Azure Function on behalf of the user that is logged in to the client app. To achieve that I followed https://learn.microsoft.com/en-us/azure/app-service/configure-authentication-provider-aad. Doing so I am successfully able to execute the function on behalf of the user.
Goal
From this triggered Azure Function on behalf of the user I want now to achieve that I can interact with another Azure Service (let's say an Azure Storage Account) on behalf of the user. The user can do on this Storage Account what is allowed by the roles the user has on the Storage Account.
Problem
I don't get it working. I tried the approaches described in How to impersonate logged in user to manage other Azure service and https://blog.brooksjc.com/2020/06/21/accessing-graph-api-with-an-azure-function-through-impersonation/ And in this context I also don't get it working for Azure Data Factory respective Graph as described in the posts. For instance, when I call .auth/me I just get an empty array.
Question
Given this context how can I achieve my goal of interacting with the Storage Account on behalf of the user via the Azure Function that has been triggered on behalf of the user?
Thanks
EDIT
I am aware of the OAuth 2.0 On-Behalf-Of flow (see https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow) and this one works (i.e., I am able to authenticate the user, retrieve another token and use this one to interact with the Storage Account on the users behalf). What I would like to achieve is similar to the posts shared above that the user authenticates against the app and by doing so already a token is made available for the interaction with the Storage Account, so that I don't have to make the additional request to https://login.microsoftonline.com/{{tenant_id}}/oauth2/v2.0/token to get that token using e.g. client credentials. And this is not about specific code (e.g. C#) but about the general set up. Is this possible?

Authorizing by updating Claim with data from database (Blazor WebAssembly ASP.NET Core hosted)

I have a question regarding authentication in my web-app using Blazor WebAssembly ASP.NET Core hosted. The database used is Azure SQL.
I want to avoid storing passwords in the database and the users are therefore restricted to having a Microsoft-account (relevant to the project).
As of now, the user logs in with Azure AD as the third-party authentication provider. When redirected back to the web-app, a user is created with a claim which only consists of the Email from Azure. The user is directed to a registration page where the Email-input is set to the current user-claim email. When the user clicks the register button, the information provided is now stored in the database.
The problem is that I now have a user in the db, but the claim is still just the Email. I want to be able to use the AuthorizeView role tag on the different pages, and therefore wondered if its possible to update the claim with a role that the user specified in the registration-page? This data is at this point only stored in the database.
If this is a bad practice, is there any other similar way I could make this work?
To use the AuthorizeView role, roles claims should be return by your Identity provider (Azure AD in your case). Your application should ask those claims by asking the corresponding scope.
According to the doc : Permissions and consent in the Microsoft identity platform endpoint, the profile scope should return roles claims.
The doc Secure an ASP.NET Core Blazor WebAssembly standalone app with Azure Active Directory explains how to request scopes from Azure AD

How to authenticate to Azure database with the users credentials not the web apps

I have an ASP.Net MVC web application that connects to an azure sql database. I have an account set up on that database using my AAD login. When I run locally (localhost) the web application loads fine and my credentials are authenticated successfully and I am able to query the database. When i publish the application to an app service on the cloud i am unable to authenticate on the database.
I followed this tutorial https://learn.microsoft.com/en-us/azure/app-service/app-service-web-tutorial-connect-msi initially, which I understand authenticates as the app itself once published (I've proved this by registering the app to AAD and adding the Application API login to the Database)
What i really want is a way to authenticate as the user of the app not the app itself - i.e. An Azure version of Kerberos which we currently use for our on-prem applications
Given you have understood how the AAD Authentication works in Azure SQL DB, and you have successfully configured MSI to authenticate with Azure SQL DB, here is what you need to do to authenticate individual user accounts in Azure SQL DB using AAD.
Register an application with your AAD (https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app)
Under API Permissions add one more permission -> Azure SQL Database
Select Delegated Permissions -> User impersonation
Create a new security group in your Azure SQL DB
Grant that security group permissions to your SQL DB instance (https://learn.microsoft.com/en-us/azure/sql-database/sql-database-aad-authentication-configure#create-contained-database-users-in-your-database-mapped-to-azure-ad-identities)
Also add the application to the SQL DB as external user (the same way you add the security group)
When you sign-in your users to your application, request an access token for Azure SQL DB using resource=https://database.windows.net in your authorization request.
Use the access token to access the database in the context of the signed-in user: https://learn.microsoft.com/en-us/azure/sql-database/sql-database-aad-authentication-configure#azure-ad-token
If you successfully completed all the steps you shall be able to sign in to the database using AAD access_token with security context of a signed-in user.
But the question is - do you really want to do that? This only makes sense if you are taking data authorization decisions inside your database. And really configure user accounts within the database.

Adding Applications programmatically in Azure AD using Client Credentials Flow

For use with the Azure API Management, I am trying to add Applications to an Azure Active Directory (AAD) programmatically, in my case by using the Graph API.
My scenario is the following: In order to secure a Web API I want to manage with Azure API Management, I want to leverage AAD's OAuth functionality to do the heavy lifting regarding authentication and issuing JWT Tokens, and then just use the validate-jwt policy to verify everything is okay in Azure API Management. This has the advantage I can more or less omit authentication in my backend service.
This works fine, as long as I have created an application in the Azure AD for the consuming web application, but this has to be done manually from the Azure Portal; Azure APIm does not do it automatically.
Now for what I am trying to do to get the done automatically: I wanted to delegate the subscription to APIs in APIm to some other web app I am writing, and from there I want to leverage the Graph API to create an Application in the Azure AD and grant permissions to the Application of the API.
The first thing I tried to do was to have a third application (my service application) to have full application permissions to the Windows Azure Active Directory application in the Azure AD; this lets my application access AAD using the Graph REST API. I manage to get an Access Token using the client_credentials grant (from login.microsoft.com), but this Token does not let me do a POST on https://graph.windows.net/(my AAD ID)/applications?api-version=1.5:
{
"odata.error": {
"code": "Authorization_RequestDenied",
"message": {
"lang": "en",
"value": "Insufficient privileges to complete the operation."
}
}
}
I found (https://msdn.microsoft.com/Library/Azure/Ad/Graph/howto/azure-ad-graph-api-permission-scopes) that even if I grant the Directory.ReadWrite.All permission, the application (app-only) will not be able to create or update Applications:
Note: Specifically excludes create or update for entities not listed above.
This includes: Application, Oauth2PermissionGrant, AppRoleAssignment, Device,
ServicePrincipal, TenantDetail, domains, etc.
The next thing I tried was the Resource Owner Password Grant (grant_type=password), passing my own credentials additionally, so that I can impersonate myself in the Graph API. Now, my POST to the applications end point succeeds.
My bottom-of-the-line question is: Can I grant sufficient permissions to my application so that I can add applications programmatically using the client credentials flow, and not any flow which acts on behalf of a user? And if so, how is it done?
Sorry Don. We don't currently have any permission scopes for the client credential flow (app-only) that can be used to create applications or service principals or create any oauth2 permission grants (or any of the other entities that you mentioned above through the Directory.ReadWrite.All permission). We are working on additional app-only permissions that will enable you to light up this scenario, but I don't have an ETA that I can give you.
This operation should be possible if you use the app+user (code flow) and grant the app the Directory.AccessAsUser.All permission - as long as there is a user using your app AND that they are a tenant admin. Not sure if this is an acceptable workaround for you (and I guess is similar to what you are using with the password flow - although I would recommend you use the code flow here).
UPDATE: There are a couple of new app only permissions we added for AAD Graph. Application.ReadWrite.OwnedBy (which allows an app to create/own another app - but only update the apps it created - it won't be able to touch any other apps it doesn't own) AND Application.ReadWrite.All (which allows an app to create/manage ALL apps in a tenant). Seems like the first one would be appropriate. You can see these show in the Azure Portal for the AAD Graph resource.