diff --git a/.gitignore b/.gitignore index 975fa663..d570fef6 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,9 @@ /3. WebApp calls several APIS (incremental consent and CA)/.vs /3. WebApp calls several APIS (incremental consent and CA)/bin /3. WebApp calls several APIS (incremental consent and CA)/obj +/1. WebApp signs-in users with Microsoft Identity (OIDC)/1.3. with work and school or personal accounts/.vs/WebApp-OpenIDConnect-DotNet/v15 +/1. WebApp signs-in users with Microsoft Identity (OIDC)/1.3. with work and school or personal accounts/obj/Debug/netcoreapp2.2 +/1. WebApp signs-in users with Microsoft Identity (OIDC)/1.3. with work and school or personal accounts/obj +/2. WebApp calls Microsoft Graph on behalf of signed-in user/2.2/.vs/WebApp-OpenIDConnect-DotNet/v15/Server/sqlite3 +/2. WebApp calls Microsoft Graph on behalf of signed-in user/2.2/WebApp-OpenIDConnect-DotNet-Cache-V2/obj +/2. WebApp calls Microsoft Graph on behalf of signed-in user/2.1. using authorization code flow/AppCreationScripts/Steps.md diff --git a/2. WebApp calls Microsoft Graph on behalf of signed-in user/2.1. using authorization code flow/AppCreationScripts/Cleanup.ps1 b/2. WebApp calls Microsoft Graph on behalf of signed-in user/2.1. using authorization code flow/AppCreationScripts/Cleanup.ps1 index fecc3184..a971c6a3 100644 --- a/2. WebApp calls Microsoft Graph on behalf of signed-in user/2.1. using authorization code flow/AppCreationScripts/Cleanup.ps1 +++ b/2. WebApp calls Microsoft Graph on behalf of signed-in user/2.1. using authorization code flow/AppCreationScripts/Cleanup.ps1 @@ -49,8 +49,8 @@ This function removes the Azure AD applications for the sample. These applicatio # Removes the applications Write-Host "Cleaning-up applications from tenant '$tenantName'" - Write-Host "Removing 'webApp' (WebApp) if needed" - $app=Get-AzureADApplication -Filter "DisplayName eq 'WebApp'" + Write-Host "Removing 'webApp' (WebApp-OpenIDConnect-DotNet-code-v2) if needed" + $app=Get-AzureADApplication -Filter "DisplayName eq 'WebApp-OpenIDConnect-DotNet-code-v2'" if ($app) { diff --git a/2. WebApp calls Microsoft Graph on behalf of signed-in user/2.1. using authorization code flow/AppCreationScripts/Configure.ps1 b/2. WebApp calls Microsoft Graph on behalf of signed-in user/2.1. using authorization code flow/AppCreationScripts/Configure.ps1 index 7c3bb3f0..5a250091 100644 --- a/2. WebApp calls Microsoft Graph on behalf of signed-in user/2.1. using authorization code flow/AppCreationScripts/Configure.ps1 +++ b/2. WebApp calls Microsoft Graph on behalf of signed-in user/2.1. using authorization code flow/AppCreationScripts/Configure.ps1 @@ -178,17 +178,17 @@ Function ConfigureApplications $user = Get-AzureADUser -ObjectId $creds.Account.Id # Create the webApp AAD application - Write-Host "Creating the AAD application (WebApp)" + Write-Host "Creating the AAD application (WebApp-OpenIDConnect-DotNet-code-v2)" # Get a 2 years application key for the webApp Application $pw = ComputePassword $fromDate = [DateTime]::Now; $key = CreateAppKey -fromDate $fromDate -durationInYears 2 -pw $pw $webAppAppKey = $pw - $webAppAadApplication = New-AzureADApplication -DisplayName "WebApp" ` + $webAppAadApplication = New-AzureADApplication -DisplayName "WebApp-OpenIDConnect-DotNet-code-v2" ` -HomePage "https://localhost:44321/" ` -LogoutUrl "https://localhost:44321/signout-oidc" ` -ReplyUrls "https://localhost:44321/", "https://localhost:44321/signin-oidc" ` - -IdentifierUris "https://$tenantName/WebApp" ` + -IdentifierUris "https://$tenantName/WebApp-OpenIDConnect-DotNet-code-v2" ` -AvailableToOtherTenants $True ` -PasswordCredentials $key ` -Oauth2AllowImplicitFlow $true ` @@ -205,19 +205,19 @@ Function ConfigureApplications Write-Host "'$($user.UserPrincipalName)' added as an application owner to app '$($webAppServicePrincipal.DisplayName)'" } - Write-Host "Done creating the webApp application (WebApp)" + Write-Host "Done creating the webApp application (WebApp-OpenIDConnect-DotNet-code-v2)" # URL of the AAD application in the Azure portal # Future? $webAppPortalUrl = "https://portal.azure.com/#@"+$tenantName+"/blade/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/Overview/appId/"+$webAppAadApplication.AppId+"/objectId/"+$webAppAadApplication.ObjectId+"/isMSAApp/" $webAppPortalUrl = "https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/CallAnAPI/appId/"+$webAppAadApplication.AppId+"/objectId/"+$webAppAadApplication.ObjectId+"/isMSAApp/" - Add-Content -Value "webApp$currentAppIdWebApp" -Path createdApps.html + Add-Content -Value "webApp$currentAppIdWebApp-OpenIDConnect-DotNet-code-v2" -Path createdApps.html $requiredResourcesAccess = New-Object System.Collections.Generic.List[Microsoft.Open.AzureAD.Model.RequiredResourceAccess] # Add Required Resources Access (from 'webApp' to 'Microsoft Graph') Write-Host "Getting access from 'webApp' to 'Microsoft Graph'" $requiredPermissions = GetRequiredPermissions -applicationDisplayName "Microsoft Graph" ` - -requiredDelegatedPermissions "User.Read"; + -requiredDelegatedPermissions "User.Read" ` $requiredResourcesAccess.Add($requiredPermissions) @@ -226,9 +226,9 @@ Function ConfigureApplications Write-Host "Granted permissions." # Update config file for 'webApp' - $configFile = $pwd.Path + "\..\active-directory-aspnetcore-webapp-openidconnect-v2\appsettings.json" + $configFile = $pwd.Path + "\..\appsettings.json" Write-Host "Updating the sample code ($configFile)" - $dictionary = @{ "ClientId" = $webAppAadApplication.AppId;"TenantId" = $tenantId;"Domain" = $tenantName;"TenantId" = $webAppAppKey }; + $dictionary = @{ "ClientId" = $webAppAadApplication.AppId;"TenantId" = $tenantId;"Domain" = $tenantName;"ClientSecret" = $webAppAppKey }; UpdateTextFile -configFilePath $configFile -dictionary $dictionary Add-Content -Value "" -Path createdApps.html diff --git a/2. WebApp calls Microsoft Graph on behalf of signed-in user/2.1. using authorization code flow/AppCreationScripts/sample.json b/2. WebApp calls Microsoft Graph on behalf of signed-in user/2.1. using authorization code flow/AppCreationScripts/sample.json index 39cabd69..9d58c481 100644 --- a/2. WebApp calls Microsoft Graph on behalf of signed-in user/2.1. using authorization code flow/AppCreationScripts/sample.json +++ b/2. WebApp calls Microsoft Graph on behalf of signed-in user/2.1. using authorization code flow/AppCreationScripts/sample.json @@ -1,6 +1,6 @@ { "Sample": { - "Title": "An ASP.NET Core 2.x Web App which lets sign-in users with work and school or Microsoft personal accounts (and calls Microsoft Graph)", + "Title": "Using the Microsoft identity platform to call the Microsoft Graph API from an An ASP.NET Core 2.x Web App, on behalf of a user signing-in using their work and school or Microsoft personal account", "Level": 200, "Client": "ASP.NET Core 2.x Web App", "Service": "Microsoft Graph", @@ -14,7 +14,7 @@ "AADApps": [ { "Id": "webApp", - "Name": "WebApp", + "Name": "WebApp-OpenIDConnect-DotNet-code-v2", "Kind": "WebApp", "HomePage": "https://localhost:44321/", "ReplyUrls": "https://localhost:44321/, https://localhost:44321/signin-oidc", @@ -39,7 +39,7 @@ { "App": "webApp", "SettingKind": "JSon", - "SettingFile": "\\..\\active-directory-aspnetcore-webapp-openidconnect-v2\\appsettings.json", + "SettingFile": "\\..\\appsettings.json", "Mappings": [ { "key": "ClientId", @@ -54,7 +54,7 @@ "value": "$tenantName" }, { - "key": "TenantId", + "key": "ClientSecret", "value": ".AppKey" } ] diff --git a/2. WebApp calls Microsoft Graph on behalf of signed-in user/2.1. using authorization code flow/README.md b/2. WebApp calls Microsoft Graph on behalf of signed-in user/2.1. using authorization code flow/README.md index ec76587a..3d7295b5 100644 --- a/2. WebApp calls Microsoft Graph on behalf of signed-in user/2.1. using authorization code flow/README.md +++ b/2. WebApp calls Microsoft Graph on behalf of signed-in user/2.1. using authorization code flow/README.md @@ -7,13 +7,14 @@ client: ASP.NET Core 2.x Web App service: Microsoft Graph endpoint: AAD v2.0 --- -# Using the Microsoft identity platform to call the Microsoft Graph API from a Web App, on behalf of the signed-in user. + +# Using the Microsoft identity platform to call the Microsoft Graph API from an An ASP.NET Core 2.x Web App, on behalf of a user signing-in using their work and school or Microsoft personal account ![Build badge](https://identitydivision.visualstudio.com/_apis/public/build/definitions/a7934fdd-dcde-4492-a406-7fad6ac00e17/514/badge) ## Scenario -Starting from a .NET Core 2.2 MVC Web app that uses OpenID Connect to sign in users, this phase of the tutorial shows how to calls the Microsoft Graph me endpoint on behalf of the signed-in user. It leverages the ASP.NET Core OpenID Connect middleware and Microsoft Authentication Library for .NET (MSAL.NET). Their complexities where encapsultated into the `Microsoft.Identity.Web` reusable library project part of this tutorial. Once again the notion of ASP.NET services injected by dependency injection is heavily used. +Starting from a .NET Core 2.2 MVC Web app that uses OpenID Connect to sign in users, this phase of the tutorial shows how to call Microsoft Graph /me endpoint on behalf of the signed-in user. It leverages the ASP.NET Core OpenID Connect middleware and Microsoft Authentication Library for .NET (MSAL.NET). Their complexities where encapsultated into the `Microsoft.Identity.Web` reusable library project part of this tutorial. Once again the notion of ASP.NET services injected by dependency injection is heavily used. ![Sign in with the Microsoft identity platform for developers (fomerly Azure AD v2.0)](ReadmeFiles/sign-in.png) @@ -27,9 +28,9 @@ To run this sample: ### Step 1: Register the sample with your Azure AD tenant -You first need to have [registered](https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/aspnetcore2-2#step-1-register-the-sample-with-your-azure-ad-tenant) your app as described in [the first tutorial](https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/aspnetcore2-2) +You first need to [register](https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/aspnetcore2-2#step-1-register-the-sample-with-your-azure-ad-tenant) your app as described in [the first tutorial](https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/aspnetcore2-2) -Then here are the extra steps: +Then follow the following extra set of steps: 1. From the **Certificates & secrets** page, for your app registration, in the **Client secrets** section, choose **New client secret**: @@ -76,9 +77,9 @@ Go to the `"2. WebApp calls Microsoft Graph on behalf of signed-in use/2.1. usin ## About The code -Starting from the [previous phase of the tutorial](../../1.%20WebApp%20signs-in%20users%20with%20Microsoft%20Identity%20(OIDC)), the code was incrementally updated by following these steps: +Starting from the [previous phase of the tutorial](../../1.%20WebApp%20signs-in%20users%20with%20Microsoft%20Identity%20(OIDC)), the code was incrementally updated with the following steps: -### Update the `Startup.cs` file to enable TokenAcquisition MSAL.NET based service +### Update the `Startup.cs` file to enable TokenAcquisition by a MSAL.NET based service After the following lines in the ConfigureServices(IServiceCollection services) method, replace `services.AddAzureAdV2Authentication(Configuration);`, by the following lines: @@ -96,12 +97,12 @@ After the following lines in the ConfigureServices(IServiceCollection services) The two new lines of code: -- enable MSAL.NET to hook-up to the OpenID Connect events and redeem the authorization code obtained by the ASP.NET Core middleware and get a token into the token cache, for use by the Controllers. +- enable MSAL.NET to hook-up to the OpenID Connect events and redeem the authorization code obtained by the ASP.NET Core middleware and after obtaining a token, saves it into the token cache, for use by the Controllers. - Decide which token cache implementation to use. In this part of the phase, we'll use a simple in memory token cache, but next steps will show you other implementations you can benefit from, including distributed token caches based on a SQL database, or a Redis cache. ### Add additional files to call Microsoft Graph -Add the `Services\Microsoft-Graph-Rest\*.cs` files. This is an implementation of a custom service which encapsultes the call to the Microsoft Graph me endpoint. Given an access token to access the Microsoft Graph, it's capable of getting the user information and the photo of the user. +Add the `Services\Microsoft-Graph-Rest\*.cs` files. This is an implementation of a custom service which encapsultes the call to the Microsoft Graph /me endpoint. Given an access token for Microsoft Graph, it's capable of getting the user information and the photo of the user. ```CSharp public interface IGraphApiOperations @@ -113,7 +114,7 @@ public interface IGraphApiOperations ### Update the `Startup.cs` file to enable the Microsoft Graph custom service -Still in the `Startup.cs` file, add the following lines just after the following. This lines ensures that the GraphAPIService benefits from the optimized `HttpClient` management by ASP.NET Core +Still in the `Startup.cs` file, add the following lines just after the following. This lines ensures that the GraphAPIService benefits from the optimized `HttpClient` management by ASP.NET Core. ```CSharp // Add Graph @@ -213,5 +214,6 @@ HTML table displaying the properties of the *me* object as returned by Microsoft - 3rd party, or even [your own Web API](../../4.%20WebApp%20calls%20your%20own%20Web%20API), which will enable you to learn about custom scopes ## Learn more + - Learn how [Microsoft.Identity.Web](../../Microsoft.Identity.Web) works, in particular hooks-up to the ASP.NET Core ODIC events - [Use HttpClientFactory to implement resilient HTTP requests](https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests) used by the Graph custom service