From 1444e121710068af970304fa385259ef817b5e1b Mon Sep 17 00:00:00 2001 From: PramodKumarHK89 Date: Thu, 15 Sep 2022 13:12:47 +0530 Subject: [PATCH] UI Modification and guide me window --- IdAceCodeEditor.sln | 2 +- IdAceCodeEditor/Config/appsettings.json | 2689 +++++++++++++------ IdAceCodeEditor/IdAceCodeEditor.csproj | 5 + IdAceCodeEditor/Models/DataSource.cs | 24 +- IdAceCodeEditor/Models/Framework.cs | 1 + IdAceCodeEditor/Models/Sample.cs | 22 +- IdAceCodeEditor/Views/GuideMeWindow.xaml | 78 +- IdAceCodeEditor/Views/GuideMeWindow.xaml.cs | 97 + IdAceCodeEditor/Views/IdAceCodeEditor.xaml | 9 +- IdAceCodeEditor/getsitelogo.ico | Bin 0 -> 4286 bytes IdAceCodeEditor/getsitelogo.png | Bin 0 -> 30565 bytes 11 files changed, 1996 insertions(+), 931 deletions(-) create mode 100644 IdAceCodeEditor/getsitelogo.ico create mode 100644 IdAceCodeEditor/getsitelogo.png diff --git a/IdAceCodeEditor.sln b/IdAceCodeEditor.sln index 2301311..5b54750 100644 --- a/IdAceCodeEditor.sln +++ b/IdAceCodeEditor.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.1.32228.430 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IdAceCodeEditor", "IdAceCodeEditor\IdAceCodeEditor.csproj", "{43C2BF53-26B0-4DF8-ADD3-C42F31DE4044}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IDAceCodeEditor", "IdAceCodeEditor\IDAceCodeEditor.csproj", "{43C2BF53-26B0-4DF8-ADD3-C42F31DE4044}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/IdAceCodeEditor/Config/appsettings.json b/IdAceCodeEditor/Config/appsettings.json index af31fe6..221e122 100644 --- a/IdAceCodeEditor/Config/appsettings.json +++ b/IdAceCodeEditor/Config/appsettings.json @@ -1,19 +1,20 @@ { "Frameworks": [ { - "Name": ".NETCORE", - "DisplayName": "ASP.NET Core", + "Name": "Asp.NetCore", + "DisplayName": "Asp.Net Core", + "Type": "Web", "Samples": [ { "Name": "Sign in users in webapp", - "Type": "ASP.NETCOREWEB", + "PlatformType": "Web", + "Type": "Asp.NetCore", "DisplayName": "An ASP.NET Core Web app signing-in users with the Microsoft identity platform in your organization", "WorkingFolder": "1-WebApp-OIDC\\1-1-MyOrg", "Tags": [ - { "Name": "Web App" }, - { "Name": "Asp.Net Core" }, - { "Name": "Identity.Web" }, - { "Name": "Auth Code Flow" } + { "Name": "SignIn" }, + { "Name": "Microsoft.Identity.Web" }, + { "Name": "HybridFlow" } ], "GitHubRepoSettings": { "ReadMeLink": "https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/master/1-WebApp-OIDC/1-1-MyOrg", @@ -94,13 +95,14 @@ }, { "Name": "Web app caling graph API", - "Type": "ASP.NETCOREWEB", + "PlatformType": "Web", + "Type": "Asp.NetCore", "DisplayName": "Enable your ASP.NET Core web app to sign in users and call Microsoft Graph with the Microsoft identity platform", "WorkingFolder": "2-WebApp-graph-user\\2-1-Call-MSGraph", "Tags": [ - { "Name": "Web App" }, - { "Name": "Asp.Net Core" }, - { "Name": "Identity.Web" }, + { "Name": "SignIn" }, + { "Name": "CallGraph" }, + { "Name": "Microsoft.Identity.Web" }, { "Name": "Auth Code Flow" } ], "GitHubRepoSettings": { @@ -188,15 +190,132 @@ } ] }, + { + "Name": "Web app caling graph API(With Certificate)", + "PlatformType": "Web", + "Type": "Asp.NetCore", + "DisplayName": "Enable your ASP.NET Core web app to sign in users and call Microsoft Graph with the Microsoft identity platform(with Certificate)", + "WorkingFolder": "2-WebApp-graph-user\\2-6-Call-MSGraph - WithCert", + "Tags": [ + { "Name": "SignIn" }, + { "Name": "CallGraph" }, + { "Name": "WithCertificate" }, + { "Name": "Microsoft.Identity.Web" }, + { "Name": "Auth Code Flow" } + ], + "GitHubRepoSettings": { + "ReadMeLink": "https://github.com/idaceappdev/active-directory-aspnetcore-webapp-openidconnect-v2/blob/master/2-WebApp-graph-user/2-6-Call-MSGraph%20-%20WithCert/README.md", + "TutorialLink": "https://github.com/AzureAD/microsoft-identity-web/wiki/Using-certificates", + "ClonePath": "https://github.com/idaceappdev/active-directory-aspnetcore-webapp-openidconnect-v2.git", + "LocalPath": "ASP.NETCORE\\CallMsGraph" + }, + "Projects": [ + { + "Name": "Client Project", + "ProjectPath": "2-WebApp-graph-user\\2-6-Call-MSGraph - WithCert", + "Order": "0", + "PortalSettings": { + "DisplayName": "WebApp-OpenIDConnect-DotNet-graph-v2", + "SignInAudience": "AzureADMyOrg", + "AppType": "Web", + "RedirectUri": "https://localhost:44321/signin-oidc", + "IsHybridFlow": "True", + "IsDeviceCodeFlow": "", + "SecretName": "", + "Certificate": { + "Type": "PemFile", // Values can be PfxFile,StoreWithThumbprint.StoreWithDN + "CertName": "TestCert.crt", + "PemName": "TestCert.pem", + "PfxName": "TestCert.pfx", + "Password": "password!", + "IsAddToStore": false, + "Issuer": "TestIssuer", + "Subject": "TestSubject" + }, + "RequiredResourceAccesss": [ + { + "ResourceAppId": "00000003-0000-0000-c000-000000000000", + "ResourceAccesss": [ + { + "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", + "Type": "Scope" + } + ] + } + ] + }, + "ReplacementFields": [ + { + "Name": "ClientId", + "ReplacementType": "JSON", + "Section": "AzureAd", + "Source": "persistdata:Projects[0].App.AppId", + "Destination": "ClientId", + "FileName": "appsettings.json" + }, + { + "Name": "TenantId", + "ReplacementType": "JSON", + "Section": "AzureAd", + "Format": "", + "Source": "persistdata:Projects[0].TenantId", + "Destination": "TenantId", + "FileName": "appsettings.json" + }, + { + "Name": "Certificate", + "ReplacementType": "JSON", + "Section": "AzureAd", + "Source": "persistdata:Projects[0].Certificate.PfxFile", + "Destination": "ClientCertificates:0:CertificateDiskPath", + "FileName": "appsettings.json" + }, + { + "Name": "password", + "ReplacementType": "JSON", + "Section": "AzureAd", + "Source": "password!", + "Destination": "ClientCertificates:0:CertificatePassword", + "FileName": "appsettings.json" + }, + { + "Name": "Domain", + "ReplacementType": "JSON", + "Section": "AzureAd", + "Format": "", + "Source": "persistdata:Projects[0].Domain", + "Destination": "Domain", + "FileName": "appsettings.json" + } + ] + } + ], + "Prerequisites": [ + { + "Name": "VSCode", + "DownloadLink": "https://code.visualstudio.com/download" + }, + { + "Name": "DotNetCore", + "DownloadLink": "https://dotnet.microsoft.com/en-us/download/dotnet/3.1" + }, + { + "Name": "VisualStudio", + "DownloadLink": "https://visualstudio.microsoft.com/downloads/" + } + ] + }, { "Name": "Webapp calling custom .NET core web API", - "Type": "ASP.NETCOREWEB", + "Type": "Asp.NetCore", + "PlatformType": "Web", "DisplayName": "How to secure an ASP.NET Core Web API with the Microsoft identity platform", "WorkingFolder": "4-WebApp-your-API\\4-1-MyOrg", "Tags": [ - { "Name": "Web App" }, - { "Name": "Asp.Net Core" }, - { "Name": "Identity.Web" }, + { "Name": "SignIn" }, + { "Name": "CallGraph" }, + { "Name": "CallCustomApi" }, + { "Name": "Microsoft.Identity.Web" }, { "Name": "Auth Code Flow" } ], "GitHubRepoSettings": { @@ -366,41 +485,35 @@ "DownloadLink": "https://visualstudio.microsoft.com/downloads/" } ] - } - ] - }, - { - "Name": ".NET Framework", - "DisplayName": "ASP.NET framework", - "Samples": [ + }, { - "Name": "Sign in users in webapp", - "Type": "ASP.NETFRAMEWORK", - "DisplayName": "Sign in a user in an ASP.NET Web App with OpenID Connect and the Microsoft identity platform", - "WorkingFolder": "", + "Name": "Blazor Webapp calling custom ASP.NET core web API", + "Type": "Asp.NetCore", + "PlatformType": "Web", + "DisplayName": "Enable your Blazor Server to sign-in users and call Web API with the Microsoft identity platform", + "WorkingFolder": "WebApp-your-API\\MyOrg", "Tags": [ - { "Name": "Web App" }, - { "Name": "Asp.Net Framework" }, - { "Name": "OWIN" }, + { "Name": "SignIn" }, + { "Name": "CallCustomApi" }, + { "Name": "Microsoft.Identity.Web" }, { "Name": "Auth Code Flow" } ], "GitHubRepoSettings": { - "ReadMeLink": "https://github.com/AzureAdQuickstarts/AppModelv2-WebApp-OpenIDConnect-DotNet", - "TutorialLink": "https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-asp-webapp", - "ClonePath": "https://github.com/AzureADQuickStarts/AppModelv2-WebApp-OpenIDConnect-DotNet.git", - "LocalPath": "ASP.NETFramework\\SignIn" + "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-blazor-server/tree/main/WebApp-your-API/MyOrg", + "TutorialLink": "https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-blazor-server", + "ClonePath": "https://github.com/Azure-Samples/ms-identity-blazor-server.git", + "LocalPath": "BlazorServer\\WebAppToAPI" }, "Projects": [ { - "Name": "Client Project", - "ProjectPath": "AppModelv2-WebApp-OpenIDConnect-DotNet", + "Name": "API Project", + "ProjectPath": "WebApp-your-API\\MyOrg\\Service", "Order": "0", "PortalSettings": { - "DisplayName": "Quickstart-AspNetWebApp", + "DisplayName": "ToDoListService-aspnetcore", "SignInAudience": "AzureADMyOrg", - "AppType": "Web", - "RedirectUri": "https://localhost:44368/", - "IsHybridFlow": "True", + "AppType": "Api", + "IsHybridFlow": "", "IsDeviceCodeFlow": "", "SecretName": "", @@ -409,74 +522,63 @@ "ResourceAppId": "00000003-0000-0000-c000-000000000000", "ResourceAccesss": [ { - "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", //User.Read + "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", "Type": "Scope" } ] } + ], + "PermissionScopes": [ + { + "Value": "access_as_user", + "Type": "User", + "AdminConsentDisplayName": "Access ToDoListService-aspnetcore", + "UserConsentDisplayName": "Access ToDoListService-aspnetcore", + "AdminConsentDescription": "Allows the app to access ToDoListService-aspnetcore as the signed-in user.", + "UserConsentDescription": "Allow the application to access ToDoListService-aspnetcore on your behalf." + } ] }, "ReplacementFields": [ { "Name": "ClientId", - "ReplacementType": "TXT", + "ReplacementType": "JSON", "Section": "AzureAd", "Format": "", "Source": "persistdata:Projects[0].App.AppId", - "Destination": "Enter_the_Application_Id_here", - "FileName": "web.config" + "Destination": "ClientId", + "FileName": "appsettings.json" }, { "Name": "TenantId", - "ReplacementType": "TXT", - "Section": "", + "ReplacementType": "JSON", + "Section": "AzureAd", "Format": "", "Source": "persistdata:Projects[0].TenantId", - "Destination": "common", - "FileName": "web.config" + "Destination": "TenantId", + "FileName": "appsettings.json" + }, + { + "Name": "Domain", + "ReplacementType": "JSON", + "Section": "AzureAd", + "Format": "", + "Source": "persistdata:Projects[0].Domain", + "Destination": "Domain", + "FileName": "appsettings.json" } ] - } - ], - "Prerequisites": [ - { - "Name": "DotNetFramework", - "DownloadLink": "https://docs.microsoft.com/en-us/dotnet/framework/install/guide-for-developers" }, - { - "Name": "VisualStudio", - "DownloadLink": "https://visualstudio.microsoft.com/downloads/" - } - ] - }, - { - "Name": "Web app caling graph API", - "Type": "ASP.NETFRAMEWORK", - "DisplayName": "Use OpenID Connect to sign in users to Microsoft identity platform and execute Microsoft Graph operations using incremental consent", - "WorkingFolder": "", - "Tags": [ - { "Name": "Web App" }, - { "Name": "Asp.Net Framework" }, - { "Name": "OWIN" }, - { "Name": "Auth Code Flow" } - ], - "GitHubRepoSettings": { - "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-aspnet-webapp-openidconnect", - "TutorialLink": "https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-asp-webapp", - "ClonePath": "https://github.com/Azure-Samples/ms-identity-aspnet-webapp-openidconnect.git", - "LocalPath": "ASP.NETFramework\\WebApp-Graph" - }, - "Projects": [ { "Name": "Client Project", - "ProjectPath": "WebApp", - "Order": "0", + "ProjectPath": "WebApp-your-API\\MyOrg\\Client", + "Order": "1", "PortalSettings": { - "DisplayName": "MailApp-openidconnect-v2", - "SignInAudience": "AzureADandPersonalMicrosoftAccount", + "DisplayName": "WebApp-calls-API-blazor-server", + "SignInAudience": "AzureADMyOrg", "AppType": "Web", - "RedirectUri": "https://localhost:44326/", - "IsHybridFlow": "", + "RedirectUri": "https://localhost:44318/signin-oidc", + "IsHybridFlow": "True", "IsDeviceCodeFlow": "", "SecretName": "mySecret", @@ -485,53 +587,928 @@ "ResourceAppId": "00000003-0000-0000-c000-000000000000", "ResourceAccesss": [ { - "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", //User.Read - "Type": "Scope" - }, - { - "Id": "37f7f235-527c-4136-accd-4a02d197296e", //OpenId - "Type": "Scope" - }, - { - "Id": "14dad69e-099b-42c9-810b-d002981feec1", //profile - "Type": "Scope" - }, - { - "Id": "7427e0e9-2fba-42fe-b0c0-848c9e6a8182", //offline_access + "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", "Type": "Scope" - }, + } + ] + + }, + { + "ResourceAppId": "persistdata:Projects[0].App.AppId", + "ResourceAccesss": [ { - "Id": "570282fd-fa5c-430d-a7fd-fc8dc98a9dca", //Mail.Read + "Id": "persistdata:Projects[0].PermissionScopes[0].Id", "Type": "Scope" } ] + } ] }, "ReplacementFields": [ { "Name": "ClientId", - "ReplacementType": "TXT", + "ReplacementType": "JSON", "Section": "AzureAd", - "Source": "persistdata:Projects[0].App.AppId", - "Destination": "[Enter your client ID, as obtained from the app registration portal]", - "FileName": "web.config" + "Source": "persistdata:Projects[1].App.AppId", + "Destination": "ClientId", + "FileName": "appsettings.json" + }, + { + "Name": "TenantId", + "Section": "AzureAd", + "ReplacementType": "JSON", + "Source": "persistdata:Projects[1].TenantId", + "Destination": "TenantId", + "FileName": "appsettings.json" + }, + { + "Name": "Domain", + "Section": "AzureAd", + "ReplacementType": "JSON", + "Source": "persistdata:Projects[1].Domain", + "Destination": "Domain", + "FileName": "appsettings.json" }, { "Name": "ClientSecret", - "ReplacementType": "TXT", - "Section": "", - "Source": "persistdata:Projects[0].SecretText", - "Destination": "[Enter your client secret, as obtained from the app registration portal]", - "FileName": "web.config" - } + "Section": "AzureAd", + "ReplacementType": "JSON", + "Source": "persistdata:Projects[1].SecretText", + "Destination": "ClientSecret", + "FileName": "appsettings.json" + }, + { + "Name": "TodoListScopes", + "Section": "TodoList", + "ReplacementType": "JSON", + "Format": "api://{0}/access_as_user", + "Source": "persistdata:Projects[0].App.AppId", + "Destination": "TodoListScope", + "FileName": "appsettings.json" + } + ] + } + ], + "Prerequisites": [ + { + "Name": "VSCode", + "DownloadLink": "https://code.visualstudio.com/download" + }, + { + "Name": "DotNetCore", + "DownloadLink": "https://dotnet.microsoft.com/en-us/download/dotnet/3.1" + }, + { + "Name": "VisualStudio", + "DownloadLink": "https://visualstudio.microsoft.com/downloads/" + } + ] + }, + { + "Name": "SPA calling .NET core API", + "Type": "Asp.NetCore", + "PlatformType": "Web", + "DisplayName": "Angular single-page application using MSAL Angular to sign-in users with Azure Active Directory and call a .NET Core web API", + "WorkingFolder": "3-Authorization-II\\1-call-api", + "Tags": [ + { "Name": "SignIn" }, + { "Name": "CallCustomApi" }, + { "Name": "Microsoft.Identity.Web" }, + { "Name": "MSAL.Angular" }, + { "Name": "PKCE" } + ], + "GitHubRepoSettings": { + "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-javascript-angular-tutorial/tree/main/3-Authorization-II/1-call-api", + "TutorialLink": "https://docs.microsoft.com/en-us/azure/active-directory/develop/single-page-app-quickstart?pivots=devlang-angular", + "ClonePath": "https://github.com/Azure-Samples/ms-identity-javascript-angular-tutorial.git", + "LocalPath": "Angular\\SpaCallingGraph" + }, + "Projects": [ + { + "Name": "API Project", + "ProjectPath": "3-Authorization-II\\1-call-api", + "Order": "0", + "PortalSettings": { + "DisplayName": "msal-dotnet-api", + "SignInAudience": "AzureADMyOrg", + "AppType": "Api", + "RedirectUri": "", + "IsHybridFlow": "", + "IsDeviceCodeFlow": "", + "SecretName": "", + + "RequiredResourceAccesss": [ + { + "ResourceAppId": "00000003-0000-0000-c000-000000000000", + "ResourceAccesss": [ + { + "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", + "Type": "Scope" + } + ] + } + ], + "PermissionScopes": [ + { + "Value": "access_as_user", + "Type": "User", + "AdminConsentDisplayName": "Access msal-dotnet-api", + "UserConsentDisplayName": "Access msal-dotnet-api", + "AdminConsentDescription": "Allows the app to access msal-dotnet-api as the signed-in user", + "UserConsentDescription": "Allow the application to access msal-dotnet-api on your behalf." + } + ] + }, + "ReplacementFields": [ + { + "Name": "ClientId", + "ReplacementType": "JSON", + "Section": "AzureAd", + "Format": "", + "Source": "persistdata:Projects[0].App.AppId", + "Destination": "ClientId", + "FileName": "API\\TodoListAPI\\appsettings.json" + }, + { + "Name": "TenantId", + "ReplacementType": "JSON", + "Section": "AzureAd", + "Format": "", + "Source": "persistdata:Projects[0].TenantId", + "Destination": "TenantId", + "FileName": "API\\TodoListAPI\\appsettings.json" + }, + { + "Name": "Domain", + "ReplacementType": "JSON", + "Section": "AzureAd", + "Format": "", + "Source": "persistdata:Projects[0].Domain", + "Destination": "Domain", + "FileName": "API\\TodoListAPI\\appsettings.json" + } + ] + }, + { + "Name": "Client Project", + "ProjectPath": "3-Authorization-II\\1-call-api", + "Order": "1", + "PortalSettings": { + "DisplayName": "msal-angular-spa", + "SignInAudience": "AzureADMyOrg", + "AppType": "Spa", + "RedirectUri": "http://localhost:4200/", + "IsHybridFlow": "", + "IsDeviceCodeFlow": "", + "SecretName": "", + + "RequiredResourceAccesss": [ + { + "ResourceAppId": "00000003-0000-0000-c000-000000000000", + "ResourceAccesss": [ + { + "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", + "Type": "Scope" + } + ] + }, + { + "ResourceAppId": "persistdata:Projects[0].App.AppId", + "ResourceAccesss": [ + { + "Id": "persistdata:Projects[0].PermissionScopes[0].Id", + "Type": "Scope" + } + ] + + } + ] + }, + "ReplacementFields": [ + { + "Name": "ClientId", + "ReplacementType": "TXT", + "Format": "", + "Source": "persistdata:Projects[1].App.AppId", + "Destination": "Enter_the_Application_Id_Here", + "FileName": "SPA\\src\\app\\auth-config.ts" + }, + { + "Name": "TenantId", + "ReplacementType": "TXT", + "Format": "", + "Source": "persistdata:Projects[1].TenantId", + "Destination": "Enter_the_Tenant_Info_Here", + "FileName": "SPA\\src\\app\\auth-config.ts" + }, + //{ + // "Name": "redirectURi", + // "ReplacementType": "TXT", + // "Format": "", + // "Source": "'https://localhost:4200/'", + // "Destination": "'/'", + // "FileName": "SPA\\src\\app\\auth-config.ts" + //}, + { + "Name": "ApiScope", + "ReplacementType": "TXT", + "Format": "api://{0}/access_as_user", + "Source": "persistdata:Projects[0].App.AppId", + "Destination": "Enter_the_Web_Api_Scope_here", + "FileName": "SPA\\src\\app\\auth-config.ts" + } + ] + } + ], + "Prerequisites": [ + { + "Name": "VSCode", + "DownloadLink": "https://code.visualstudio.com/download" + }, + { + "Name": "NPM", + "DownloadLink": "https://docs.npmjs.com/downloading-and-installing-node-js-and-npm" + } + ] + }, + { + "Name": "WPF app calling ASP.NET core API", + "Type": "Asp.NetCore", + "PlatformType": "Web", + "DisplayName": "Sign-in a user with the Microsoft Identity Platform in a WPF Desktop application and call an ASP.NET Core Web API", + "WorkingFolder": "1. Desktop app calls Web API", + "Tags": [ + { "Name": "SignIn" }, + { "Name": "CallCustomApi" }, + { "Name": "MSAL.NET" }, + { "Name": "Microsoft.Identity.Web" }, + { "Name": "WAM" }, + { "Name": "System browser" }, + { "Name": "PKCE" } + ], + "GitHubRepoSettings": { + "ReadMeLink": "https://github.com/Azure-Samples/active-directory-dotnet-native-aspnetcore-v2/blob/master/1.%20Desktop%20app%20calls%20Web%20API/README.md", + "TutorialLink": "https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-windows-desktop", + "ClonePath": "https://github.com/Azure-Samples/active-directory-dotnet-native-aspnetcore-v2.git", + "LocalPath": "WPF\\CallCustomAPI" + }, + "Projects": [ + { + "Name": "API Project", + "ProjectPath": "1. Desktop app calls Web API\\TodoListService", + "Order": "0", + "PortalSettings": { + "DisplayName": "TodoListService", + "SignInAudience": "AzureADMyOrg", + "AppType": "Api", + "IsHybridFlow": "", + "IsDeviceCodeFlow": "", + "SecretName": "", + + "RequiredResourceAccesss": [ + { + "ResourceAppId": "00000003-0000-0000-c000-000000000000", + "ResourceAccesss": [ + { + "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", + "Type": "Scope" + } + ] + } + ], + "PermissionScopes": [ + { + "Value": "access_as_user", + "Type": "User", + "AdminConsentDisplayName": "Access TodoListService (active-directory-dotnet-native-aspnetcore-v2)", + "UserConsentDisplayName": "Access TodoListService (active-directory-dotnet-native-aspnetcore-v2)", + "AdminConsentDescription": "Allows the app to access TodoListService (active-directory-dotnet-native-aspnetcore-v2) as the signed-in user.", + "UserConsentDescription": "Allow the application to access TodoListService (active-directory-dotnet-native-aspnetcore-v2) on your behalf." + } + ] + }, + "ReplacementFields": [ + { + "Name": "ClientId", + "ReplacementType": "JSON", + "Section": "AzureAd", + "Format": "", + "Source": "persistdata:Projects[0].App.AppId", + "Destination": "ClientId", + "FileName": "appsettings.json" + }, + { + "Name": "Domain", + "ReplacementType": "JSON", + "Section": "AzureAd", + "Format": "", + "Source": "persistdata:Projects[0].Domain", + "Destination": "Domain", + "FileName": "appsettings.json" + } + ] + }, + { + "Name": "Client Project", + "ProjectPath": "1. Desktop app calls Web API\\TodoListClient", + "Order": "1", + "PortalSettings": { + "DisplayName": "TodoListClient", + "SignInAudience": "AzureADandPersonalMicrosoftAccount", + "AppType": "Desktop", + "RedirectUri": "http://localhost", + "IsHybridFlow": "", + "IsDeviceCodeFlow": "", + "SecretName": "", + + "RequiredResourceAccesss": [ + { + "ResourceAppId": "00000003-0000-0000-c000-000000000000", + "ResourceAccesss": [ + { + "id": "b340eb25-3456-403f-be2f-af7a0d370277", + "Type": "Scope" + } + ] + }, + { + "ResourceAppId": "persistdata:Projects[0].App.AppId", + "ResourceAccesss": [ + { + "Id": "persistdata:Projects[0].PermissionScopes[0].Id", + "Type": "Scope" + } + ] + + } + ] + }, + "ReplacementFields": [ + { + "Name": "ClientId", + "ReplacementType": "TXT", + "Source": "persistdata:Projects[1].App.AppId", + "Destination": "[Enter_client_ID_Of_TodoListClient-v2_from_Azure_Portal,_e.g._784d7a5a-4a49-4d1d-b328-5812070f366f]", + "FileName": "App.config" + }, + { + "Name": "TodoListScopes", + "ReplacementType": "TXT", + "Source": "persistdata:Projects[0].App.AppId", + "Destination": "[Enter_client_ID_Of_TodoListService-v2_from_Azure_Portal,_e.g._2ec40e65-ba09-4853-bcde-bcb60029e596]", + "FileName": "App.config" + } + ] + } + ], + "Prerequisites": [ + { + "Name": "VSCode", + "DownloadLink": "https://code.visualstudio.com/download" + }, + { + "Name": "VisualStudio", + "DownloadLink": "https://visualstudio.microsoft.com/downloads/" + } + ] + } + ] + }, + { + "Name": "Asp.NetFramework", + "Type": "Web", + "DisplayName": "ASP.NET framework", + "Samples": [ + { + "Name": "Sign in users in webapp", + "Type": "Asp.NetFramework", + "PlatformType": "Web", + "DisplayName": "Sign in a user in an ASP.NET Web App with OpenID Connect and the Microsoft identity platform", + "WorkingFolder": "", + "Tags": [ + { "Name": "SignIn" }, + { "Name": "Microsoft.Owin" }, + { "Name": "Hybridflow" } + ], + "GitHubRepoSettings": { + "ReadMeLink": "https://github.com/AzureAdQuickstarts/AppModelv2-WebApp-OpenIDConnect-DotNet", + "TutorialLink": "https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-asp-webapp", + "ClonePath": "https://github.com/AzureADQuickStarts/AppModelv2-WebApp-OpenIDConnect-DotNet.git", + "LocalPath": "ASP.NETFramework\\SignIn" + }, + "Projects": [ + { + "Name": "Client Project", + "ProjectPath": "AppModelv2-WebApp-OpenIDConnect-DotNet", + "Order": "0", + "PortalSettings": { + "DisplayName": "Quickstart-AspNetWebApp", + "SignInAudience": "AzureADMyOrg", + "AppType": "Web", + "RedirectUri": "https://localhost:44368/", + "IsHybridFlow": "True", + "IsDeviceCodeFlow": "", + "SecretName": "", + + "RequiredResourceAccesss": [ + { + "ResourceAppId": "00000003-0000-0000-c000-000000000000", + "ResourceAccesss": [ + { + "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", //User.Read + "Type": "Scope" + } + ] + } + ] + }, + "ReplacementFields": [ + { + "Name": "ClientId", + "ReplacementType": "TXT", + "Section": "AzureAd", + "Format": "", + "Source": "persistdata:Projects[0].App.AppId", + "Destination": "Enter_the_Application_Id_here", + "FileName": "web.config" + }, + { + "Name": "TenantId", + "ReplacementType": "TXT", + "Section": "", + "Format": "", + "Source": "persistdata:Projects[0].TenantId", + "Destination": "common", + "FileName": "web.config" + } + ] + } + ], + "Prerequisites": [ + { + "Name": "DotNetFramework", + "DownloadLink": "https://docs.microsoft.com/en-us/dotnet/framework/install/guide-for-developers" + }, + { + "Name": "VisualStudio", + "DownloadLink": "https://visualstudio.microsoft.com/downloads/" + } + ] + }, + { + "Name": "Web app caling graph API", + "Type": "Asp.NetFramework", + "PlatformType": "Web", + "DisplayName": "Use OpenID Connect to sign in users to Microsoft identity platform and execute Microsoft Graph operations using incremental consent", + "WorkingFolder": "", + "Tags": [ + { "Name": "SignIn" }, + { "Name": "CallGraph" }, + { "Name": "Microsoft.Owin" }, + { "Name": "Auth Code Flow" } + ], + "GitHubRepoSettings": { + "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-aspnet-webapp-openidconnect", + "TutorialLink": "https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-asp-webapp", + "ClonePath": "https://github.com/Azure-Samples/ms-identity-aspnet-webapp-openidconnect.git", + "LocalPath": "ASP.NETFramework\\WebApp-Graph" + }, + "Projects": [ + { + "Name": "Client Project", + "ProjectPath": "WebApp", + "Order": "0", + "PortalSettings": { + "DisplayName": "MailApp-openidconnect-v2", + "SignInAudience": "AzureADandPersonalMicrosoftAccount", + "AppType": "Web", + "RedirectUri": "https://localhost:44326/", + "IsHybridFlow": "", + "IsDeviceCodeFlow": "", + "SecretName": "mySecret", + + "RequiredResourceAccesss": [ + { + "ResourceAppId": "00000003-0000-0000-c000-000000000000", + "ResourceAccesss": [ + { + "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", //User.Read + "Type": "Scope" + }, + { + "Id": "37f7f235-527c-4136-accd-4a02d197296e", //OpenId + "Type": "Scope" + }, + { + "Id": "14dad69e-099b-42c9-810b-d002981feec1", //profile + "Type": "Scope" + }, + { + "Id": "7427e0e9-2fba-42fe-b0c0-848c9e6a8182", //offline_access + "Type": "Scope" + }, + { + "Id": "570282fd-fa5c-430d-a7fd-fc8dc98a9dca", //Mail.Read + "Type": "Scope" + } + ] + } + ] + }, + "ReplacementFields": [ + { + "Name": "ClientId", + "ReplacementType": "TXT", + "Section": "AzureAd", + "Source": "persistdata:Projects[0].App.AppId", + "Destination": "[Enter your client ID, as obtained from the app registration portal]", + "FileName": "web.config" + }, + { + "Name": "ClientSecret", + "ReplacementType": "TXT", + "Section": "", + "Source": "persistdata:Projects[0].SecretText", + "Destination": "[Enter your client secret, as obtained from the app registration portal]", + "FileName": "web.config" + } + ] + } + ], + "Prerequisites": [ + { + "Name": "DotNetFramework", + "DownloadLink": "" + }, + { + "Name": "VisualStudio", + "DownloadLink": "https://visualstudio.microsoft.com/downloads/" + } + ] + } + ] + }, + { + "Name": "BlazorServer", + "Type": "Web", + "DisplayName": "Blazor webapp", + "Samples": [ + { + "Name": "Sign In Users", + "Type": "BlazorServer", + "PlatformType": "Web", + "DisplayName": "Enable your Blazor WebAssembly to sign-in users with the Microsoft identity platform", + "WorkingFolder": "WebApp-OIDC\\MyOrg", + "Tags": [ + { "Name": "SignIn" }, + { "Name": "Microsoft.Identity.Web" }, + { "Name": "HybridFlow" } + ], + "GitHubRepoSettings": { + "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-blazor-server/tree/main/WebApp-OIDC/MyOrg", + "TutorialLink": "https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-blazor-server", + "ClonePath": "https://github.com/Azure-Samples/ms-identity-blazor-server.git", + "LocalPath": "BlazorServer\\SignIn" + }, + "Projects": [ + { + "Name": "Client Project", + "ProjectPath": "WebApp-OIDC\\MyOrg", + "Order": "0", + "PortalSettings": { + "DisplayName": "WebApp-blazor-server", + "SignInAudience": "AzureADMyOrg", + "AppType": "Web", + "RedirectUri": "https://localhost:44318/ https://localhost:44318/signin-oidc", + "IsHybridFlow": "True", + "IsDeviceCodeFlow": "", + "SecretName": "", + + "RequiredResourceAccesss": [ + { + "ResourceAppId": "00000003-0000-0000-c000-000000000000", + "ResourceAccesss": [ + { + "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", //User.Read + "Type": "Scope" + } + ] + } + ] + }, + "ReplacementFields": [ + { + "Name": "ClientId", + "ReplacementType": "JSON", + "Section": "AzureAd", + "Format": "", + "Source": "persistdata:Projects[0].App.AppId", + "Destination": "ClientId", + "FileName": "blazorserver-singleOrg\\appsettings.json" + }, + { + "Name": "Domain", + "ReplacementType": "JSON", + "Section": "AzureAd", + "Source": "persistdata:Projects[0].Domain", + "Destination": "Domain", + "FileName": "blazorserver-singleOrg\\appsettings.json" + }, + { + "Name": "TenantId", + "ReplacementType": "JSON", + "Section": "AzureAd", + "Source": "persistdata:Projects[0].TenantId", + "Destination": "TenantId", + "FileName": "blazorserver-singleOrg\\appsettings.json" + } + ] + } + ], + "Prerequisites": [ + { + "Name": "VSCode", + "DownloadLink": "https://code.visualstudio.com/download" + }, + { + "Name": "DotNetCore", + "DownloadLink": "https://dotnet.microsoft.com/en-us/download/dotnet/3.1" + }, + { + "Name": "VisualStudio", + "DownloadLink": "https://visualstudio.microsoft.com/downloads/" + } + ] + }, + { + "Name": "Call Microsoft Graph", + "Type": "BlazorServer", + "PlatformType": "Web", + "DisplayName": "Call Microsoft Graph on behalf-of the signed-in users in your Blazor Server Application", + "WorkingFolder": "WebApp-graph-user\\Call-MSGraph", + "Tags": [ + { "Name": "SignIn" }, + { "Name": "CallGraph" }, + { "Name": "Microsoft.Identity.Web" }, + { "Name": "Auth Code flow" } + ], + "GitHubRepoSettings": { + "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-blazor-server/tree/main/WebApp-graph-user/Call-MSGraph", + "TutorialLink": "https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-blazor-server", + "ClonePath": "https://github.com/Azure-Samples/ms-identity-blazor-server.git", + "LocalPath": "BlazorServer\\WebAppGraph" + }, + "Projects": [ + { + "Name": "Client Project", + "ProjectPath": "WebApp-graph-user\\Call-MSGraph", + "Order": "0", + "PortalSettings": { + "DisplayName": "WebApp-blazor-server-graph", + "SignInAudience": "AzureADMyOrg", + "AppType": "Web", + "RedirectUri": "https://localhost:44318/ https://localhost:44318/signin-oidc", + "IsHybridFlow": "True", + "IsDeviceCodeFlow": "", + "SecretName": "mySecret", + + "RequiredResourceAccesss": [ + { + "ResourceAppId": "00000003-0000-0000-c000-000000000000", + "ResourceAccesss": [ + { + "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", //User.Read + "Type": "Scope" + } + ] + } + ] + }, + "ReplacementFields": [ + { + "Name": "ClientId", + "ReplacementType": "JSON", + "Section": "AzureAd", + "Format": "", + "Source": "persistdata:Projects[0].App.AppId", + "Destination": "ClientId", + "FileName": "blazorserver-calls-MS-graph\\appsettings.json" + }, + { + "Name": "Domain", + "ReplacementType": "JSON", + "Section": "AzureAd", + "Source": "persistdata:Projects[0].Domain", + "Destination": "Domain", + "FileName": "blazorserver-calls-MS-graph\\appsettings.json" + }, + { + "Name": "TenantId", + "ReplacementType": "JSON", + "Section": "AzureAd", + "Source": "persistdata:Projects[0].TenantId", + "Destination": "TenantId", + "FileName": "blazorserver-calls-MS-graph\\appsettings.json" + }, + { + "Name": "ClientSecret", + "ReplacementType": "JSON", + "Section": "AzureAd", + "Source": "persistdata:Projects[0].SecretText", + "Destination": "ClientSecret", + "FileName": "blazorserver-calls-MS-graph\\appsettings.json" + } + ] + } + ], + "Prerequisites": [ + { + "Name": "VSCode", + "DownloadLink": "https://code.visualstudio.com/download" + }, + { + "Name": "DotNetCore", + "DownloadLink": "https://dotnet.microsoft.com/en-us/download/dotnet/3.1" + }, + { + "Name": "VisualStudio", + "DownloadLink": "https://visualstudio.microsoft.com/downloads/" + } + ] + }, + { + "Name": "Blazor Webapp calling custom ASP.NET core web API", + "Type": "BlazorServer", + "PlatformType": "Web", + "DisplayName": "Enable your Blazor Server to sign-in users and call Web API with the Microsoft identity platform", + "WorkingFolder": "WebApp-your-API\\MyOrg", + "Tags": [ + { "Name": "SignIn" }, + { "Name": "CallCustomApi" }, + { "Name": "Microsoft.Identity.Web" }, + { "Name": "Auth Code Flow" } + ], + "GitHubRepoSettings": { + "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-blazor-server/tree/main/WebApp-your-API/MyOrg", + "TutorialLink": "https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-blazor-server", + "ClonePath": "https://github.com/Azure-Samples/ms-identity-blazor-server.git", + "LocalPath": "BlazorServer\\WebAppToAPI" + }, + "Projects": [ + { + "Name": "API Project", + "ProjectPath": "WebApp-your-API\\MyOrg\\Service", + "Order": "0", + "PortalSettings": { + "DisplayName": "ToDoListService-aspnetcore", + "SignInAudience": "AzureADMyOrg", + "AppType": "Api", + "IsHybridFlow": "", + "IsDeviceCodeFlow": "", + "SecretName": "", + + "RequiredResourceAccesss": [ + { + "ResourceAppId": "00000003-0000-0000-c000-000000000000", + "ResourceAccesss": [ + { + "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", + "Type": "Scope" + } + ] + } + ], + "PermissionScopes": [ + { + "Value": "access_as_user", + "Type": "User", + "AdminConsentDisplayName": "Access ToDoListService-aspnetcore", + "UserConsentDisplayName": "Access ToDoListService-aspnetcore", + "AdminConsentDescription": "Allows the app to access ToDoListService-aspnetcore as the signed-in user.", + "UserConsentDescription": "Allow the application to access ToDoListService-aspnetcore on your behalf." + } + ] + }, + "ReplacementFields": [ + { + "Name": "ClientId", + "ReplacementType": "JSON", + "Section": "AzureAd", + "Format": "", + "Source": "persistdata:Projects[0].App.AppId", + "Destination": "ClientId", + "FileName": "appsettings.json" + }, + { + "Name": "TenantId", + "ReplacementType": "JSON", + "Section": "AzureAd", + "Format": "", + "Source": "persistdata:Projects[0].TenantId", + "Destination": "TenantId", + "FileName": "appsettings.json" + }, + { + "Name": "Domain", + "ReplacementType": "JSON", + "Section": "AzureAd", + "Format": "", + "Source": "persistdata:Projects[0].Domain", + "Destination": "Domain", + "FileName": "appsettings.json" + } + ] + }, + { + "Name": "Client Project", + "ProjectPath": "WebApp-your-API\\MyOrg\\Client", + "Order": "1", + "PortalSettings": { + "DisplayName": "WebApp-calls-API-blazor-server", + "SignInAudience": "AzureADMyOrg", + "AppType": "Web", + "RedirectUri": "https://localhost:44318/signin-oidc", + "IsHybridFlow": "True", + "IsDeviceCodeFlow": "", + "SecretName": "mySecret", + + "RequiredResourceAccesss": [ + { + "ResourceAppId": "00000003-0000-0000-c000-000000000000", + "ResourceAccesss": [ + { + "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", + "Type": "Scope" + } + ] + + }, + { + "ResourceAppId": "persistdata:Projects[0].App.AppId", + "ResourceAccesss": [ + { + "Id": "persistdata:Projects[0].PermissionScopes[0].Id", + "Type": "Scope" + } + ] + + } + ] + }, + "ReplacementFields": [ + { + "Name": "ClientId", + "ReplacementType": "JSON", + "Section": "AzureAd", + "Source": "persistdata:Projects[1].App.AppId", + "Destination": "ClientId", + "FileName": "appsettings.json" + }, + { + "Name": "TenantId", + "Section": "AzureAd", + "ReplacementType": "JSON", + "Source": "persistdata:Projects[1].TenantId", + "Destination": "TenantId", + "FileName": "appsettings.json" + }, + { + "Name": "Domain", + "Section": "AzureAd", + "ReplacementType": "JSON", + "Source": "persistdata:Projects[1].Domain", + "Destination": "Domain", + "FileName": "appsettings.json" + }, + { + "Name": "ClientSecret", + "Section": "AzureAd", + "ReplacementType": "JSON", + "Source": "persistdata:Projects[1].SecretText", + "Destination": "ClientSecret", + "FileName": "appsettings.json" + }, + { + "Name": "TodoListScopes", + "Section": "TodoList", + "ReplacementType": "JSON", + "Format": "api://{0}/access_as_user", + "Source": "persistdata:Projects[0].App.AppId", + "Destination": "TodoListScope", + "FileName": "appsettings.json" + } ] } ], "Prerequisites": [ { - "Name": "DotNetFramework", - "DownloadLink": "" + "Name": "VSCode", + "DownloadLink": "https://code.visualstudio.com/download" + }, + { + "Name": "DotNetCore", + "DownloadLink": "https://dotnet.microsoft.com/en-us/download/dotnet/3.1" }, { "Name": "VisualStudio", @@ -542,17 +1519,18 @@ ] }, { - "Name": "Java Spring", + "Name": "JavaSpring", + "Type": "Web", "DisplayName": "Java Spring", "Samples": [ { "Name": "Sign in users in webapp", - "Type": "Java Spring", + "Type": "JavaSpring", + "PlatformType": "Web", "DisplayName": "Enable your Java Spring Boot web app to sign in users on your Azure Active Directory tenant with the Microsoft identity platform", "WorkingFolder": "4. Spring Framework Web App Tutorial\\1-Authentication\\sign-in", "Tags": [ - { "Name": "Web App" }, - { "Name": "Java Spring" }, + { "Name": "SignIn" }, { "Name": "Spring Boot Starter" }, { "Name": "Auth Code Flow" } ], @@ -630,13 +1608,14 @@ ] }, { - "Name": "Sign in users in webapp", - "Type": "Java Spring", + "Name": "Sign in users in webapp an call Graph API", + "Type": "JavaSpring", + "PlatformType": "Web", "DisplayName": "Enable your Java Spring Boot web app to sign in users and call Microsoft Graph with the Microsoft identity platform", "WorkingFolder": "4. Spring Framework Web App Tutorial\\2-Authorization-I\\call-graph", "Tags": [ - { "Name": "Web App" }, - { "Name": "Java Spring" }, + { "Name": "SignIn" }, + { "Name": "CallGraph" }, { "Name": "Spring Boot Starter" }, { "Name": "Auth Code Flow" } ], @@ -716,46 +1695,223 @@ ] }, { - "Name": "Java Servlets", - "DisplayName": "Java Servlets", + "Name": "JavaServlet", + "Type": "Web", + "DisplayName": "Java Servlets", + "Samples": [ + { + "Name": "Sign in users in webapp", + "Type": "JavaServlet", + "PlatformType": "Web", + "DisplayName": "Enable your Java Servlet web app to sign in users to your Azure Active Directory tenant with the Microsoft identity platform", + "WorkingFolder": "3. Java Servlet Web App Tutorial\\1-Authentication\\sign-in", + "Tags": [ + { "Name": "SignIn" }, + { "Name": "Msal.Java" }, + { "Name": "Auth Code Flow" } + ], + "GitHubRepoSettings": { + "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-msal-java-samples/tree/main/3.%20Java%20Servlet%20Web%20App%20Tutorial/1-Authentication/sign-in/README.md", + "TutorialLink": "https://docs.microsoft.com/en-us/azure/developer/java/spring-framework/configure-spring-boot-starter-java-app-with-azure-active-directory?toc=%2Fazure%2Factive-directory%2Fdevelop%2Ftoc.json&bc=%2Fazure%2Factive-directory%2Fdevelop%2Fbreadcrumb%2Ftoc.json", + "ClonePath": "https://github.com/Azure-Samples/ms-identity-msal-java-samples.git", + "LocalPath": "Servlet\\SignIn" + }, + "Projects": [ + { + "Name": "Client Project", + "ProjectPath": "3. Java Servlet Web App Tutorial\\1-Authentication\\sign-in", + "Order": "0", + "PortalSettings": { + "DisplayName": "java-servlet-webapp-authentication", + "SignInAudience": "AzureADMyOrg", + "AppType": "Web", + "RedirectUri": "http://localhost:8080/msal4j-servlet-auth/auth/redirect", + "IsHybridFlow": "", + "IsDeviceCodeFlow": "", + "SecretName": "appsecret", + + "RequiredResourceAccesss": [ + { + "ResourceAppId": "00000003-0000-0000-c000-000000000000", + "ResourceAccesss": [ + { + "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", //User.Read + "Type": "Scope" + } + ] + } + ] + }, + "ReplacementFields": [ + { + "Name": "ClientId", + "ReplacementType": "TXT", + "Section": "", + "Format": "", + "Source": "persistdata:Projects[0].App.AppId", + "Destination": "{enter-your-client-id-here}", + "FileName": "src/main/resources/authentication.properties" + }, + { + "Name": "TenantId", + "ReplacementType": "TXT", + "Section": "", + "Format": "", + "Source": "persistdata:Projects[0].TenantId", + "Destination": "{enter-your-tenant-id-here}", + "FileName": "src/main/resources/authentication.properties" + }, + { + "Name": "ClientSecret", + "ReplacementType": "TXT", + "Section": "", + "Source": "persistdata:Projects[0].SecretText", + "Destination": "{enter-your-client-secret-here}", + "FileName": "src/main/resources/authentication.properties" + } + ] + } + ], + "Prerequisites": [ + { + "Name": "Java", + "DownloadLink": "https://www.oracle.com/java/technologies/downloads/" + }, + { + "Name": "VSCode", + "DownloadLink": "https://code.visualstudio.com/download" + } + ] + }, + { + "Name": "Sign in users in webapp and call graph", + "Type": "JavaServlet", + "PlatformType": "Web", + "DisplayName": "Enable your Java Servlet web app to sign in users and call Microsoft Graph with the Microsoft identity platform", + "WorkingFolder": "3. Java Servlet Web App Tutorial\\2-Authorization-I\\call-graph", + "Tags": [ + { "Name": "SignIn" }, + { "Name": "CallGraph" }, + { "Name": "Msal.Java" }, + { "Name": "Auth Code Flow" } + ], + "GitHubRepoSettings": { + "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-msal-java-samples/tree/main/3.%20Java%20Servlet%20Web%20App%20Tutorial/2-Authorization-I/call-graph/README.md", + "TutorialLink": "https://docs.microsoft.com/en-us/azure/developer/java/spring-framework/configure-spring-boot-starter-java-app-with-azure-active-directory?toc=%2Fazure%2Factive-directory%2Fdevelop%2Ftoc.json&bc=%2Fazure%2Factive-directory%2Fdevelop%2Fbreadcrumb%2Ftoc.json", + "ClonePath": "https://github.com/Azure-Samples/ms-identity-msal-java-samples.git", + "LocalPath": "Servlet\\CallGraph" + }, + "Projects": [ + { + "Name": "Client Project", + "ProjectPath": "3. Java Servlet Web App Tutorial\\2-Authorization-I\\call-graph", + "Order": "0", + "PortalSettings": { + "DisplayName": "java-servlet-webapp-call-graph", + "SignInAudience": "AzureADMyOrg", + "AppType": "Web", + "RedirectUri": "http://localhost:8080/msal4j-servlet-auth/auth/redirect", + "IsHybridFlow": "", + "IsDeviceCodeFlow": "", + "SecretName": "appsecret", + + "RequiredResourceAccesss": [ + { + "ResourceAppId": "00000003-0000-0000-c000-000000000000", + "ResourceAccesss": [ + { + "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", //User.Read + "Type": "Scope" + } + ] + } + ] + }, + "ReplacementFields": [ + { + "Name": "ClientId", + "ReplacementType": "TXT", + "Section": "", + "Format": "", + "Source": "persistdata:Projects[0].App.AppId", + "Destination": "{enter-your-client-id-here}", + "FileName": "src/main/resources/authentication.properties" + }, + { + "Name": "TenantId", + "ReplacementType": "TXT", + "Section": "", + "Format": "", + "Source": "persistdata:Projects[0].TenantId", + "Destination": "{enter-your-tenant-id-here}", + "FileName": "src/main/resources/authentication.properties" + }, + { + "Name": "ClientSecret", + "ReplacementType": "TXT", + "Section": "", + "Source": "persistdata:Projects[0].SecretText", + "Destination": "{enter-your-client-secret-here}", + "FileName": "src/main/resources/authentication.properties" + } + ] + } + ], + "Prerequisites": [ + { + "Name": "Java", + "DownloadLink": "https://www.oracle.com/java/technologies/downloads/" + }, + { + "Name": "VSCode", + "DownloadLink": "https://code.visualstudio.com/download" + } + ] + } + ] + }, + { + "Name": "PythonFlask", + "Type": "Web", + "DisplayName": "Python", "Samples": [ { - "Name": "Sign in users in webapp", - "Type": "Java Servlets", - "DisplayName": "Enable your Java Servlet web app to sign in users to your Azure Active Directory tenant with the Microsoft identity platform", - "WorkingFolder": "3. Java Servlet Web App Tutorial\\1-Authentication\\sign-in", + "Name": "Sign in users in python flask web app", + "Type": "PythonFlask", + "PlatformType": "Web", + "DisplayName": "Enable your Python Flask webapp to sign in users to your Azure Active Directory tenant with the Microsoft identity platform", + "WorkingFolder": "", "Tags": [ - { "Name": "Web App" }, - { "Name": "Java Servlets" }, - { "Name": "Msal Java" }, + { "Name": "SignIn" }, + { "Name": "MSAL.Python" }, { "Name": "Auth Code Flow" } ], "GitHubRepoSettings": { - "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-msal-java-samples/tree/main/3.%20Java%20Servlet%20Web%20App%20Tutorial/1-Authentication/sign-in/README.md", - "TutorialLink": "https://docs.microsoft.com/en-us/azure/developer/java/spring-framework/configure-spring-boot-starter-java-app-with-azure-active-directory?toc=%2Fazure%2Factive-directory%2Fdevelop%2Ftoc.json&bc=%2Fazure%2Factive-directory%2Fdevelop%2Fbreadcrumb%2Ftoc.json", - "ClonePath": "https://github.com/Azure-Samples/ms-identity-msal-java-samples.git", - "LocalPath": "Servlet\\SignIn" + "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-python-flask-webapp-authentication", + "TutorialLink": "https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-python-token-cache-serialization", + "ClonePath": "https://github.com/Azure-Samples/ms-identity-python-flask-webapp-authentication.git", + "LocalPath": "PythonFlask\\SignIn" }, "Projects": [ { "Name": "Client Project", - "ProjectPath": "3. Java Servlet Web App Tutorial\\1-Authentication\\sign-in", + "ProjectPath": "", "Order": "0", "PortalSettings": { - "DisplayName": "java-servlet-webapp-authentication", + "DisplayName": "python-flask-webapp-auth-my-tenant", "SignInAudience": "AzureADMyOrg", "AppType": "Web", - "RedirectUri": "http://localhost:8080/msal4j-servlet-auth/auth/redirect", + "RedirectUri": "https://127.0.0.1:5000/auth/redirect", "IsHybridFlow": "", "IsDeviceCodeFlow": "", - "SecretName": "appsecret", + "SecretName": "mysecret", "RequiredResourceAccesss": [ { "ResourceAppId": "00000003-0000-0000-c000-000000000000", "ResourceAccesss": [ { - "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", //User.Read + "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", "Type": "Scope" } ] @@ -765,71 +1921,72 @@ "ReplacementFields": [ { "Name": "ClientId", - "ReplacementType": "TXT", - "Section": "", - "Format": "", + "ReplacementType": "JSON", + "Section": "client", "Source": "persistdata:Projects[0].App.AppId", - "Destination": "{enter-your-client-id-here}", - "FileName": "src/main/resources/authentication.properties" + "Destination": "client_id", + "FileName": "aad.config.json" }, { "Name": "TenantId", - "ReplacementType": "TXT", - "Section": "", - "Format": "", + "ReplacementType": "JSON", + "Section": "client", + "Format": "https://login.microsoftonline.com/{0}", "Source": "persistdata:Projects[0].TenantId", - "Destination": "{enter-your-tenant-id-here}", - "FileName": "src/main/resources/authentication.properties" + "Destination": "authority", + "FileName": "aad.config.json" }, { "Name": "ClientSecret", - "ReplacementType": "TXT", - "Section": "", + "ReplacementType": "JSON", + "Section": "client", + "Format": "", "Source": "persistdata:Projects[0].SecretText", - "Destination": "{enter-your-client-secret-here}", - "FileName": "src/main/resources/authentication.properties" + "Destination": "client_credential", + "FileName": "aad.config.json" } ] } ], "Prerequisites": [ - { - "Name": "Java", - "DownloadLink": "https://www.oracle.com/java/technologies/downloads/" - }, { "Name": "VSCode", "DownloadLink": "https://code.visualstudio.com/download" + }, + { + "Name": "Python", + "DownloadLink": "https://www.python.org/downloads/release/python-380/" } ] }, { - "Name": "Sign in users in webapp and call graph", - "Type": "Java Servlets", - "DisplayName": "Enable your Java Servlet web app to sign in users and call Microsoft Graph with the Microsoft identity platform", - "WorkingFolder": "3. Java Servlet Web App Tutorial\\2-Authorization-I\\call-graph", + "Name": "Python flask web app calling graph API", + "Type": "PythonFlask", + "PlatformType": "Web", + "DisplayName": "This sample demonstrates a Python web application calling a Microsoft Graph that is secured using Azure Active Directory.", + "WorkingFolder": "", "Tags": [ - { "Name": "Web App" }, - { "Name": "Java Servlets" }, - { "Name": "Msal Java" }, + { "Name": "SignIn" }, + { "Name": "CallGraph" }, + { "Name": "MSAL Python" }, { "Name": "Auth Code Flow" } ], "GitHubRepoSettings": { - "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-msal-java-samples/tree/main/3.%20Java%20Servlet%20Web%20App%20Tutorial/2-Authorization-I/call-graph/README.md", - "TutorialLink": "https://docs.microsoft.com/en-us/azure/developer/java/spring-framework/configure-spring-boot-starter-java-app-with-azure-active-directory?toc=%2Fazure%2Factive-directory%2Fdevelop%2Ftoc.json&bc=%2Fazure%2Factive-directory%2Fdevelop%2Fbreadcrumb%2Ftoc.json", - "ClonePath": "https://github.com/Azure-Samples/ms-identity-msal-java-samples.git", - "LocalPath": "Servlet\\CallGraph" + "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-python-webapp", + "TutorialLink": "https://docs.microsoft.com/en-us/samples/azure-samples/ms-identity-python-webapp/ms-identity-python-webapp/", + "ClonePath": "https://github.com/Azure-Samples/ms-identity-python-webapp.git", + "LocalPath": "PythonFlask\\CallGraphAPI" }, "Projects": [ { "Name": "Client Project", - "ProjectPath": "3. Java Servlet Web App Tutorial\\2-Authorization-I\\call-graph", + "ProjectPath": "", "Order": "0", "PortalSettings": { - "DisplayName": "java-servlet-webapp-call-graph", - "SignInAudience": "AzureADMyOrg", + "DisplayName": "python-webapp", + "SignInAudience": "AzureADandPersonalMicrosoftAccount", "AppType": "Web", - "RedirectUri": "http://localhost:8080/msal4j-servlet-auth/auth/redirect", + "RedirectUri": "http://localhost:5000/getAToken", "IsHybridFlow": "", "IsDeviceCodeFlow": "", "SecretName": "appsecret", @@ -839,7 +1996,7 @@ "ResourceAppId": "00000003-0000-0000-c000-000000000000", "ResourceAccesss": [ { - "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", //User.Read + "id": "b340eb25-3456-403f-be2f-af7a0d370277", "Type": "Scope" } ] @@ -850,86 +2007,78 @@ { "Name": "ClientId", "ReplacementType": "TXT", - "Section": "", - "Format": "", + "Section": "client", "Source": "persistdata:Projects[0].App.AppId", - "Destination": "{enter-your-client-id-here}", - "FileName": "src/main/resources/authentication.properties" - }, - { - "Name": "TenantId", - "ReplacementType": "TXT", - "Section": "", - "Format": "", - "Source": "persistdata:Projects[0].TenantId", - "Destination": "{enter-your-tenant-id-here}", - "FileName": "src/main/resources/authentication.properties" + "Destination": "Enter_the_Application_Id_here", + "FileName": "app_config.py" }, { "Name": "ClientSecret", "ReplacementType": "TXT", - "Section": "", + "Section": "client", + "Format": "", "Source": "persistdata:Projects[0].SecretText", - "Destination": "{enter-your-client-secret-here}", - "FileName": "src/main/resources/authentication.properties" + "Destination": "Enter_the_Client_Secret_Here", + "FileName": "app_config.py" } ] } ], "Prerequisites": [ - { - "Name": "Java", - "DownloadLink": "https://www.oracle.com/java/technologies/downloads/" - }, { "Name": "VSCode", "DownloadLink": "https://code.visualstudio.com/download" + }, + { + "Name": "Python", + "DownloadLink": "https://www.python.org/downloads/release/python-380/" } ] } ] }, { - "Name": "Blazor WASM", - "DisplayName": "Blazor Web Assemblies", + "Name": "NodeJs", + "Type": "Web", + "DisplayName": "Node.js", "Samples": [ { "Name": "Sign In Users", - "Type": "BlazorWASM", - "DisplayName": "Enable your Blazor WebAssembly to sign-in users with the Microsoft identity platform", - "WorkingFolder": "WebApp-OIDC\\MyOrg", + "Type": "NodeJs", + "PlatformType": "Web", + "DisplayName": "A Node.js & Express web app authenticating users against Azure AD with MSAL Nod", + "WorkingFolder": "1-Authentication\\1-sign-in", "Tags": [ - { "Name": "SPA" }, - { "Name": "Blazor WASM" }, - { "Name": "MSAL JS" }, - { "Name": "PKCE" } + { "Name": "SignIn" }, + { "Name": "Msal.NodeJs" }, + { "Name": "Auth Code Flow" } ], "GitHubRepoSettings": { - "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-blazor-wasm/blob/main/WebApp-OIDC/MyOrg/README.md", - "TutorialLink": "https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-blazor-webassembly", - "ClonePath": "https://github.com/Azure-Samples/ms-identity-blazor-wasm.git", - "LocalPath": "BlazorWASM\\SignIn" + "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-javascript-nodejs-tutorial/blob/main/1-Authentication/1-sign-in/README.md", + "TutorialLink": "https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-nodejs-webapp-msal", + "ClonePath": "https://github.com/Azure-Samples/ms-identity-javascript-nodejs-tutorial.git", + "LocalPath": "NodeJS\\SignIn" }, "Projects": [ { "Name": "Client Project", - "ProjectPath": "WebApp-OIDC\\MyOrg", + "ProjectPath": "1-Authentication\\1-sign-in", "Order": "0", "PortalSettings": { - "DisplayName": "WebApp-blazor-wasm", + "DisplayName": "msal-node-webapp", "SignInAudience": "AzureADMyOrg", "AppType": "Web", - "RedirectUri": "https://localhost:44314/authentication/login-callback", - "IsHybridFlow": "True", + "RedirectUri": "http://localhost:4000/redirect", + "IsHybridFlow": "", "IsDeviceCodeFlow": "", - "SecretName": "", + "SecretName": "appsecret", "RequiredResourceAccesss": [ { "ResourceAppId": "00000003-0000-0000-c000-000000000000", "ResourceAccesss": [ { - "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", //User.Read + "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", "Type": "Scope" } ] @@ -939,21 +2088,35 @@ "ReplacementFields": [ { "Name": "ClientId", - "ReplacementType": "JSON", - "Section": "AzureAd", + "ReplacementType": "TXT", "Format": "", "Source": "persistdata:Projects[0].App.AppId", - "Destination": "ClientId", - "FileName": "blazorwasm-singleOrg\\wwwroot\\appsettings.json" + "Destination": "Enter_the_Application_Id_Here", + "FileName": "App\\appSettings.js" }, { - "Name": "Authority", - "ReplacementType": "JSON", - "Section": "AzureAd", + "Name": "TenantId", + "ReplacementType": "TXT", + "Format": "", "Source": "persistdata:Projects[0].TenantId", - "Format": "https://login.microsoftonline.com/{0}", - "Destination": "Authority", - "FileName": "blazorwasm-singleOrg\\wwwroot\\appsettings.json" + "Destination": "Enter_the_Tenant_Info_Here", + "FileName": "App\\appSettings.js" + }, + { + "Name": "ClientSecret", + "ReplacementType": "TXT", + "Format": "", + "Source": "persistdata:Projects[0].SecretText", + "Destination": "Enter_the_Client_Secret_Here", + "FileName": "App\\appSettings.js" + }, + { + "Name": "ClientSecret", + "ReplacementType": "TXT", + "Format": "", + "Source": "persistdata:Projects[0].SecretText", + "Destination": "ENTER_YOUR_SECRET_HERE", + "FileName": "App\\app.js" } ] } @@ -964,75 +2127,96 @@ "DownloadLink": "https://code.visualstudio.com/download" }, { - "Name": "DotNetCore", - "DownloadLink": "https://dotnet.microsoft.com/en-us/download/dotnet/3.1" - }, - { - "Name": "VisualStudio", - "DownloadLink": "https://visualstudio.microsoft.com/downloads/" + "Name": "NPM", + "DownloadLink": "https://docs.npmjs.com/downloading-and-installing-node-js-and-npm" } ] }, { - "Name": "Call Microsoft Graph", - "Type": "BlazorWasm", - "DisplayName": "Enable your Blazor WebAssembly to authorize users for calling Microsoft Graph", - "WorkingFolder": "", + "Name": "Call MS Graph", + "Type": "NodeJs", + "PlatformType": "Web", + "DisplayName": "A Node.js & Express web app calling Microsoft Graph using MSAL Node", + "WorkingFolder": "2-Authorization\\1-call-graph", "Tags": [ - { "Name": "SPA" }, - { "Name": "Blazor WASM" }, - { "Name": "MSAL JS" }, - { "Name": "PKCE" } + { "Name": "SignIn" }, + { "Name": "CallGraph" }, + { "Name": "MSAL.NodeJs" }, + { "Name": "Auth Code Flow" } ], "GitHubRepoSettings": { - "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-blazor-wasm/blob/main/WebApp-graph-user/Call-MSGraph/README.md", - "TutorialLink": "https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-blazor-webassembly", - "ClonePath": "https://github.com/Azure-Samples/ms-identity-blazor-wasm.git", - "LocalPath": "BlazorWASM\\GraphAPI" + "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-javascript-nodejs-tutorial/blob/main/2-Authorization/1-call-graph/README.md", + "TutorialLink": "https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-nodejs-webapp-msal", + "ClonePath": "https://github.com/Azure-Samples/ms-identity-javascript-nodejs-tutorial.git", + "LocalPath": "NodeJS\\CallGraph" }, "Projects": [ { "Name": "Client Project", - "ProjectPath": "WebApp-graph-user\\Call-MSGraph", + "ProjectPath": "2-Authorization\\1-call-graph", "Order": "0", "PortalSettings": { - "DisplayName": "WebApp-blazor-wasm-graph", + "DisplayName": "msal-node-webapp", "SignInAudience": "AzureADMyOrg", "AppType": "Web", - "RedirectUri": "https://localhost:44314/authentication/login-callback", - "IsHybridFlow": "True", + "RedirectUri": "http://localhost:4000/redirect", + "IsHybridFlow": "", "IsDeviceCodeFlow": "", - "SecretName": "", + "SecretName": "appsecret", "RequiredResourceAccesss": [ { "ResourceAppId": "00000003-0000-0000-c000-000000000000", "ResourceAccesss": [ { - "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", //User.Read + "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", "Type": "Scope" } ] + }, + { + "resourceAppId": "797f4846-ba00-4fd7-ba43-dac1f8f63013", + "resourceAccess": [ + { + "id": "41094075-9dad-400e-a0bd-54e686782033", + "type": "Scope" + } + ] } ] }, "ReplacementFields": [ { "Name": "ClientId", - "ReplacementType": "JSON", - "Section": "AzureAd", + "ReplacementType": "TXT", + "Format": "", "Source": "persistdata:Projects[0].App.AppId", - "Destination": "ClientId", - "FileName": "blazorwasm-calls-MS-graph\\wwwroot\\appsettings.json" + "Destination": "Enter_the_Application_Id_Here", + "FileName": "App\\appSettings.js" }, { - "Name": "Authority", - "ReplacementType": "JSON", - "Section": "AzureAd", - "Format": "https://login.microsoftonline.com/{0}", + "Name": "TenantId", + "ReplacementType": "TXT", + "Format": "", "Source": "persistdata:Projects[0].TenantId", - "Destination": "Authority", - "FileName": "blazorwasm-calls-MS-graph\\wwwroot\\appsettings.json" + "Destination": "Enter_the_Tenant_Info_Here", + "FileName": "App\\appSettings.js" + }, + { + "Name": "ClientSecret", + "ReplacementType": "TXT", + "Format": "", + "Source": "persistdata:Projects[0].SecretText", + "Destination": "Enter_the_Client_Secret_Here", + "FileName": "App\\appSettings.js" + }, + { + "Name": "ClientSecret", + "ReplacementType": "TXT", + "Format": "", + "Source": "persistdata:Projects[0].SecretText", + "Destination": "ENTER_YOUR_SECRET_HERE", + "FileName": "App\\app.js" } ] } @@ -1043,49 +2227,41 @@ "DownloadLink": "https://code.visualstudio.com/download" }, { - "Name": "DotNetCore", - "DownloadLink": "https://dotnet.microsoft.com/en-us/download/dotnet/3.1" - }, - { - "Name": "VisualStudio", - "DownloadLink": "https://visualstudio.microsoft.com/downloads/" + "Name": "NPM", + "DownloadLink": "https://docs.npmjs.com/downloading-and-installing-node-js-and-npm" } ] - } - ] - }, - { - "Name": "Blazor Server", - "DisplayName": "Blazor webapp", - "Samples": [ + }, { - "Name": "Sign In Users", - "Type": "BlazorServer", - "DisplayName": "Enable your Blazor WebAssembly to sign-in users with the Microsoft identity platform", - "WorkingFolder": "WebApp-OIDC\\MyOrg", + "Name": "React(SPA) calling NodeJS API", + "Type": "NodeJs", + "PlatformType": "Web", + "DisplayName": "A React single-page application using MSAL React to authorize users for calling a protected web API on Azure Active Directory", + "WorkingFolder": "3-Authorization-II\\1-call-api", "Tags": [ - { "Name": "Web App" }, - { "Name": "Blazor Server" }, - { "Name": "MSAL.Net" }, - { "Name": "Auth Code flow" } + { "Name": "SignIn" }, + { "Name": "CallCustomApi" }, + { "Name": "MSAL.React" }, + { "Name": "MSAL.Node" }, + { "Name": "PKCE" } ], "GitHubRepoSettings": { - "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-blazor-server/tree/main/WebApp-OIDC/MyOrg", - "TutorialLink": "https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-blazor-server", - "ClonePath": "https://github.com/Azure-Samples/ms-identity-blazor-server.git", - "LocalPath": "BlazorServer\\SignIn" + "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-javascript-react-tutorial/tree/main/3-Authorization-II/1-call-api", + "TutorialLink": "https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-react", + "ClonePath": "https://github.com/Azure-Samples/ms-identity-javascript-react-tutorial.git", + "LocalPath": "React\\SpaCallinApi" }, "Projects": [ { - "Name": "Client Project", - "ProjectPath": "WebApp-OIDC\\MyOrg", + "Name": "API Project", + "ProjectPath": "3-Authorization-II\\1-call-api\\API", "Order": "0", "PortalSettings": { - "DisplayName": "WebApp-blazor-server", + "DisplayName": "msal-react-api", "SignInAudience": "AzureADMyOrg", - "AppType": "Web", - "RedirectUri": "https://localhost:44318/ https://localhost:44318/signin-oidc", - "IsHybridFlow": "True", + "AppType": "Api", + "RedirectUri": "", + "IsHybridFlow": "", "IsDeviceCodeFlow": "", "SecretName": "", @@ -1094,133 +2270,103 @@ "ResourceAppId": "00000003-0000-0000-c000-000000000000", "ResourceAccesss": [ { - "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", //User.Read + "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", "Type": "Scope" } ] } + ], + "PermissionScopes": [ + { + "Value": "access_as_user", + "Type": "User", + "AdminConsentDisplayName": "Access msal-react-api", + "UserConsentDisplayName": "Access msal-react-api", + "AdminConsentDescription": "Allows the app to access msal-react-api as the signed-in user", + "UserConsentDescription": "Allow the application to access msal-react-api on your behalf." + } ] }, "ReplacementFields": [ { "Name": "ClientId", "ReplacementType": "JSON", - "Section": "AzureAd", + "Section": "credentials", "Format": "", "Source": "persistdata:Projects[0].App.AppId", - "Destination": "ClientId", - "FileName": "blazorserver-singleOrg\\appsettings.json" - }, - { - "Name": "Domain", - "ReplacementType": "JSON", - "Section": "AzureAd", - "Source": "persistdata:Projects[0].Domain", - "Destination": "Domain", - "FileName": "blazorserver-singleOrg\\appsettings.json" + "Destination": "clientID", + "FileName": "config.json" }, { "Name": "TenantId", "ReplacementType": "JSON", - "Section": "AzureAd", + "Section": "credentials", + "Format": "", "Source": "persistdata:Projects[0].TenantId", - "Destination": "TenantId", - "FileName": "blazorserver-singleOrg\\appsettings.json" + "Destination": "tenantID", + "FileName": "config.json" } ] - } - ], - "Prerequisites": [ - { - "Name": "VSCode", - "DownloadLink": "https://code.visualstudio.com/download" - }, - { - "Name": "DotNetCore", - "DownloadLink": "https://dotnet.microsoft.com/en-us/download/dotnet/3.1" }, - { - "Name": "VisualStudio", - "DownloadLink": "https://visualstudio.microsoft.com/downloads/" - } - ] - }, - { - "Name": "Call Microsoft Graph", - "Type": "BlazorServer", - "DisplayName": "Call Microsoft Graph on behalf-of the signed-in users in your Blazor Server Application", - "WorkingFolder": "WebApp-graph-user\\Call-MSGraph", - "Tags": [ - { "Name": "Web App" }, - { "Name": "Blazor Server" }, - { "Name": "MSAL.Net" }, - { "Name": "Auth Code flow" } - ], - "GitHubRepoSettings": { - "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-blazor-server/tree/main/WebApp-graph-user/Call-MSGraph", - "TutorialLink": "https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-blazor-server", - "ClonePath": "https://github.com/Azure-Samples/ms-identity-blazor-server.git", - "LocalPath": "BlazorServer\\WebAppGraph" - }, - "Projects": [ { "Name": "Client Project", - "ProjectPath": "WebApp-graph-user\\Call-MSGraph", - "Order": "0", + "ProjectPath": "3-Authorization-II\\1-call-api\\SPA", + "Order": "1", "PortalSettings": { - "DisplayName": "WebApp-blazor-server-graph", + "DisplayName": "msal-react-spa", "SignInAudience": "AzureADMyOrg", - "AppType": "Web", - "RedirectUri": "https://localhost:44318/ https://localhost:44318/signin-oidc", - "IsHybridFlow": "True", + "AppType": "Spa", + "RedirectUri": "http://localhost:3000/", + "IsHybridFlow": "", "IsDeviceCodeFlow": "", - "SecretName": "mySecret", + "SecretName": "", "RequiredResourceAccesss": [ { "ResourceAppId": "00000003-0000-0000-c000-000000000000", "ResourceAccesss": [ { - "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", //User.Read + "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", + "Type": "Scope" + } + ] + }, + { + "ResourceAppId": "persistdata:Projects[0].App.AppId", + "ResourceAccesss": [ + { + "Id": "persistdata:Projects[0].PermissionScopes[0].Id", "Type": "Scope" } ] + } ] }, "ReplacementFields": [ { "Name": "ClientId", - "ReplacementType": "JSON", - "Section": "AzureAd", + "ReplacementType": "TXT", "Format": "", - "Source": "persistdata:Projects[0].App.AppId", - "Destination": "ClientId", - "FileName": "blazorserver-calls-MS-graph\\appsettings.json" - }, - { - "Name": "Domain", - "ReplacementType": "JSON", - "Section": "AzureAd", - "Source": "persistdata:Projects[0].Domain", - "Destination": "Domain", - "FileName": "blazorserver-calls-MS-graph\\appsettings.json" + "Source": "persistdata:Projects[1].App.AppId", + "Destination": "Enter_the_Application_Id_Here", + "FileName": "src\\authConfig.js" }, { "Name": "TenantId", - "ReplacementType": "JSON", - "Section": "AzureAd", - "Source": "persistdata:Projects[0].TenantId", - "Destination": "TenantId", - "FileName": "blazorserver-calls-MS-graph\\appsettings.json" + "ReplacementType": "TXT", + "Format": "", + "Source": "persistdata:Projects[1].TenantId", + "Destination": "Enter_the_Tenant_Info_Here", + "FileName": "src\\authConfig.js" }, { - "Name": "ClientSecret", - "ReplacementType": "JSON", - "Section": "AzureAd", - "Source": "persistdata:Projects[0].SecretText", - "Destination": "ClientSecret", - "FileName": "blazorserver-calls-MS-graph\\appsettings.json" + "Name": "ApiScope", + "ReplacementType": "TXT", + "Format": "api://{0}/access_as_user", + "Source": "persistdata:Projects[0].App.AppId", + "Destination": "Enter_the_Web_Api_Scope_Here", + "FileName": "src\\authConfig.js" } ] } @@ -1231,42 +2377,46 @@ "DownloadLink": "https://code.visualstudio.com/download" }, { - "Name": "DotNetCore", - "DownloadLink": "https://dotnet.microsoft.com/en-us/download/dotnet/3.1" - }, - { - "Name": "VisualStudio", - "DownloadLink": "https://visualstudio.microsoft.com/downloads/" + "Name": "NPM", + "DownloadLink": "https://docs.npmjs.com/downloading-and-installing-node-js-and-npm" } ] - }, + } + ] + }, + { + "Name": "BlasorWasm", + "Type": "Spa", + "DisplayName": "Blazor Web Assemblies", + "Samples": [ { - "Name": "Blazor Webapp calling custom ASP.NET core web API", - "Type": "BlazorServer", - "DisplayName": "Enable your Blazor Server to sign-in users and call Web API with the Microsoft identity platform", - "WorkingFolder": "WebApp-your-API\\MyOrg", + "Name": "Sign In Users", + "Type": "BlasorWasm", + "PlatformType": "Spa", + "DisplayName": "Enable your Blazor WebAssembly to sign-in users with the Microsoft identity platform", + "WorkingFolder": "WebApp-OIDC\\MyOrg", "Tags": [ - { "Name": "Blazor Sever" }, - { "Name": "Asp.Net Core" }, - { "Name": "Identity.Web" }, - { "Name": "Auth Code Flow" } + { "Name": "SignIn" }, + { "Name": "Microsoft.Authentication.WebAssembly.Msal" }, + { "Name": "PKCE" } ], "GitHubRepoSettings": { - "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-blazor-server/tree/main/WebApp-your-API/MyOrg", - "TutorialLink": "https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-blazor-server", - "ClonePath": "https://github.com/Azure-Samples/ms-identity-blazor-server.git", - "LocalPath": "BlazorServer\\WebAppToAPI" + "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-blazor-wasm/blob/main/WebApp-OIDC/MyOrg/README.md", + "TutorialLink": "https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-blazor-webassembly", + "ClonePath": "https://github.com/Azure-Samples/ms-identity-blazor-wasm.git", + "LocalPath": "BlazorWASM\\SignIn" }, "Projects": [ { - "Name": "API Project", - "ProjectPath": "WebApp-your-API\\MyOrg\\Service", + "Name": "Client Project", + "ProjectPath": "WebApp-OIDC\\MyOrg", "Order": "0", "PortalSettings": { - "DisplayName": "ToDoListService-aspnetcore", + "DisplayName": "WebApp-blazor-wasm", "SignInAudience": "AzureADMyOrg", - "AppType": "Api", - "IsHybridFlow": "", + "AppType": "Web", + "RedirectUri": "https://localhost:44314/authentication/login-callback", + "IsHybridFlow": "True", "IsDeviceCodeFlow": "", "SecretName": "", @@ -1275,21 +2425,11 @@ "ResourceAppId": "00000003-0000-0000-c000-000000000000", "ResourceAccesss": [ { - "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", + "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", //User.Read "Type": "Scope" } ] } - ], - "PermissionScopes": [ - { - "Value": "access_as_user", - "Type": "User", - "AdminConsentDisplayName": "Access ToDoListService-aspnetcore", - "UserConsentDisplayName": "Access ToDoListService-aspnetcore", - "AdminConsentDescription": "Allows the app to access ToDoListService-aspnetcore as the signed-in user.", - "UserConsentDescription": "Allow the application to access ToDoListService-aspnetcore on your behalf." - } ] }, "ReplacementFields": [ @@ -1300,61 +2440,76 @@ "Format": "", "Source": "persistdata:Projects[0].App.AppId", "Destination": "ClientId", - "FileName": "appsettings.json" + "FileName": "blazorwasm-singleOrg\\wwwroot\\appsettings.json" }, { - "Name": "TenantId", + "Name": "Authority", "ReplacementType": "JSON", "Section": "AzureAd", - "Format": "", "Source": "persistdata:Projects[0].TenantId", - "Destination": "TenantId", - "FileName": "appsettings.json" - }, - { - "Name": "Domain", - "ReplacementType": "JSON", - "Section": "AzureAd", - "Format": "", - "Source": "persistdata:Projects[0].Domain", - "Destination": "Domain", - "FileName": "appsettings.json" + "Format": "https://login.microsoftonline.com/{0}", + "Destination": "Authority", + "FileName": "blazorwasm-singleOrg\\wwwroot\\appsettings.json" } ] + } + ], + "Prerequisites": [ + { + "Name": "VSCode", + "DownloadLink": "https://code.visualstudio.com/download" + }, + { + "Name": "DotNetCore", + "DownloadLink": "https://dotnet.microsoft.com/en-us/download/dotnet/3.1" }, + { + "Name": "VisualStudio", + "DownloadLink": "https://visualstudio.microsoft.com/downloads/" + } + ] + }, + { + "Name": "Call Microsoft Graph", + "Type": "BlazorWasm", + "PlatformType": "Spa", + "DisplayName": "Enable your Blazor WebAssembly to authorize users for calling Microsoft Graph", + "WorkingFolder": "", + "Tags": [ + { "Name": "SignIn" }, + { "Name": "CallGraph" }, + { "Name": "Microsoft.Authentication.WebAssembly.Msal" }, + { "Name": "PKCE" } + ], + "GitHubRepoSettings": { + "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-blazor-wasm/blob/main/WebApp-graph-user/Call-MSGraph/README.md", + "TutorialLink": "https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-blazor-webassembly", + "ClonePath": "https://github.com/Azure-Samples/ms-identity-blazor-wasm.git", + "LocalPath": "BlazorWASM\\GraphAPI" + }, + "Projects": [ { "Name": "Client Project", - "ProjectPath": "WebApp-your-API\\MyOrg\\Client", - "Order": "1", + "ProjectPath": "WebApp-graph-user\\Call-MSGraph", + "Order": "0", "PortalSettings": { - "DisplayName": "WebApp-calls-API-blazor-server", + "DisplayName": "WebApp-blazor-wasm-graph", "SignInAudience": "AzureADMyOrg", "AppType": "Web", - "RedirectUri": "https://localhost:44318/signin-oidc", + "RedirectUri": "https://localhost:44314/authentication/login-callback", "IsHybridFlow": "True", "IsDeviceCodeFlow": "", - "SecretName": "mySecret", + "SecretName": "", "RequiredResourceAccesss": [ { "ResourceAppId": "00000003-0000-0000-c000-000000000000", "ResourceAccesss": [ { - "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", - "Type": "Scope" - } - ] - - }, - { - "ResourceAppId": "persistdata:Projects[0].App.AppId", - "ResourceAccesss": [ - { - "Id": "persistdata:Projects[0].PermissionScopes[0].Id", + "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", //User.Read "Type": "Scope" } ] - } ] }, @@ -1363,42 +2518,18 @@ "Name": "ClientId", "ReplacementType": "JSON", "Section": "AzureAd", - "Source": "persistdata:Projects[1].App.AppId", + "Source": "persistdata:Projects[0].App.AppId", "Destination": "ClientId", - "FileName": "appsettings.json" - }, - { - "Name": "TenantId", - "Section": "AzureAd", - "ReplacementType": "JSON", - "Source": "persistdata:Projects[1].TenantId", - "Destination": "TenantId", - "FileName": "appsettings.json" + "FileName": "blazorwasm-calls-MS-graph\\wwwroot\\appsettings.json" }, { - "Name": "Domain", - "Section": "AzureAd", + "Name": "Authority", "ReplacementType": "JSON", - "Source": "persistdata:Projects[1].Domain", - "Destination": "Domain", - "FileName": "appsettings.json" - }, - { - "Name": "ClientSecret", "Section": "AzureAd", - "ReplacementType": "JSON", - "Source": "persistdata:Projects[1].SecretText", - "Destination": "ClientSecret", - "FileName": "appsettings.json" - }, - { - "Name": "TodoListScopes", - "Section": "TodoList", - "ReplacementType": "JSON", - "Format": "api://{0}/access_as_user", - "Source": "persistdata:Projects[0].App.AppId", - "Destination": "TodoListScope", - "FileName": "appsettings.json" + "Format": "https://login.microsoftonline.com/{0}", + "Source": "persistdata:Projects[0].TenantId", + "Destination": "Authority", + "FileName": "blazorwasm-calls-MS-graph\\wwwroot\\appsettings.json" } ] } @@ -1421,17 +2552,20 @@ ] }, { + "Name": "Angular", + "Type": "Spa", "DisplayName": "Angular", "Samples": [ { "Name": "Sign In Users", "Type": "Angular", + "PlatformType": "Spa", "DisplayName": "Angular single-page application using MSAL Angular to sign-in users with Azure Active Directory", "WorkingFolder": "1-Authentication\\1-sign-in\\SPA", "Tags": [ - { "Name": "Spa" }, - { "Name": "MSAL Angular" }, + { "Name": "SignIn" }, + { "Name": "MSAL.Angular" }, { "Name": "PKCE" } ], "GitHubRepoSettings": { @@ -1505,11 +2639,13 @@ { "Name": "SPA calling Graph API", "Type": "Angular", + "PlatformType": "Spa", "DisplayName": "Angular single-page application using MSAL Angular to sign-in users with Azure Active Directory and call the Microsoft Graph API", "WorkingFolder": "2-Authorization-I\\1-call-graph\\SPA", "Tags": [ - { "Name": "Spa" }, - { "Name": "MSAL Angular" }, + { "Name": "SignIn" }, + { "Name": "CallGraph" }, + { "Name": "MSAL.Angular" }, { "Name": "PKCE" } ], "GitHubRepoSettings": { @@ -1595,11 +2731,14 @@ { "Name": "SPA calling .NET core API", "Type": "Angular", + "PlatformType": "Spa", "DisplayName": "Angular single-page application using MSAL Angular to sign-in users with Azure Active Directory and call a .NET Core web API", "WorkingFolder": "3-Authorization-II\\1-call-api", "Tags": [ - { "Name": "Spa" }, - { "Name": "MSAL Angular" }, + { "Name": "SignIn" }, + { "Name": "SignIn" }, + { "Name": "CallCustomApi" }, + { "Name": "MSAL.Angular" }, { "Name": "PKCE" } ], "GitHubRepoSettings": { @@ -1759,11 +2898,15 @@ { "Name": "SPA calling .NET core API Which calls Graph(OBO)", "Type": "Angular", + "PlatformType": "Spa", "DisplayName": "Angular single-page application authorizing .NET Core web API to call Microsoft Graph using on-behalf-of flow", "WorkingFolder": "7-AdvancedScenarios\\1-call-api-obo", "Tags": [ - { "Name": "Spa" }, - { "Name": "MSAL Angular" }, + { "Name": "SignIn" }, + { "Name": "CallGraph" }, + { "Name": "CallCustomApi" }, + { "Name": "MSAL.Angular" }, + { "Name": "Microsoft.Identity.Web" }, { "Name": "PKCE" }, { "Name": "OBO" } ], @@ -1940,16 +3083,18 @@ }, { "Name": "React", + "Type": "Spa", "DisplayName": "React", "Samples": [ { "Name": "Sign In Users", "Type": "React", + "PlatformType": "Spa", "DisplayName": "React single-page application using MSAL React to sign-in users against Azure Active Directory", "WorkingFolder": "1-Authentication\\1-sign-in\\SPA", "Tags": [ - { "Name": "Spa" }, - { "Name": "MSAL React" }, + { "Name": "SignIn" }, + { "Name": "MSAL.React" }, { "Name": "PKCE" } ], "GitHubRepoSettings": { @@ -2026,11 +3171,13 @@ { "Name": "SPA calling Graph API", "Type": "React", + "PlatformType": "Spa", "DisplayName": "React single-page application using MSAL React to sign-in users and call Graph API against Azure Active Directory", "WorkingFolder": "2-Authorization-I\\1-call-graph\\SPA", "Tags": [ - { "Name": "Spa" }, - { "Name": "MSAL React" }, + { "Name": "SignIn" }, + { "Name": "Callgraph" }, + { "Name": "MSAL.React" }, { "Name": "PKCE" } ], "GitHubRepoSettings": { @@ -2120,11 +3267,14 @@ { "Name": "SPA calling NodeJS API", "Type": "React", + "PlatformType": "Spa", "DisplayName": "A React single-page application using MSAL React to authorize users for calling a protected web API on Azure Active Directory", "WorkingFolder": "3-Authorization-II\\1-call-api", "Tags": [ - { "Name": "Spa" }, - { "Name": "MSAL React" }, + { "Name": "SignIn" }, + { "Name": "CallCustomApi" }, + { "Name": "MSAL.React" }, + { "Name": "MSAL.Node" }, { "Name": "PKCE" } ], "GitHubRepoSettings": { @@ -2268,16 +3418,18 @@ }, { "Name": "Javascript", + "Type": "Spa", "DisplayName": "Javascript", "Samples": [ { "Name": "Sign In Users", - "Type": "JS", + "Type": "Javascript", + "PlatformType": "Spa", "DisplayName": "React single-page application using MSAL React to sign-in users against Azure Active Directory", "WorkingFolder": "1-Authentication\\1-sign-in", "Tags": [ - { "Name": "Spa" }, - { "Name": "MSAL JS" }, + { "Name": "SignIn" }, + { "Name": "MSAL.JS" }, { "Name": "PKCE" } ], "GitHubRepoSettings": { @@ -2295,178 +3447,10 @@ "DisplayName": "ms-identity-javascript-tutorial-c1s1", "SignInAudience": "AzureADMyOrg", "AppType": "Spa", - "RedirectUri": "http://localhost:3000/", - "IsHybridFlow": "", - "IsDeviceCodeFlow": "", - "SecretName": "", - - "RequiredResourceAccesss": [ - { - "ResourceAppId": "00000003-0000-0000-c000-000000000000", - "ResourceAccesss": [ - { - "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", - "Type": "Scope" - } - ] - } - ] - }, - "ReplacementFields": [ - { - "Name": "ClientId", - "ReplacementType": "TXT", - "Format": "", - "Source": "persistdata:Projects[0].App.AppId", - "Destination": "Enter_the_Application_Id_Here", - "FileName": "App\\authConfig.js" - }, - { - "Name": "Authority", - "ReplacementType": "TXT", - "Format": "", - "Source": "persistdata:Projects[0].TenantId", - "Destination": "Enter_the_Tenant_Info_Here", - "FileName": "App\\authConfig.js" - }, - { - "Name": "redirectURi", - "ReplacementType": "TXT", - "Format": "", - "Source": "http://localhost:3000/", - "Destination": "Enter_the_Redirect_Uri_Here", - "FileName": "App\\authConfig.js" - } - ] - } - ], - "Prerequisites": [ - { - "Name": "VSCode", - "DownloadLink": "https://code.visualstudio.com/download" - }, - { - "Name": "NPM", - "DownloadLink": "https://docs.npmjs.com/downloading-and-installing-node-js-and-npm" - } - ] - }, - { - "Name": "Call Microsoft Graph", - "Type": "JS", - "DisplayName": "Vanilla JavaScript single-page application using MSAL.js to authorize users for calling Microsoft Graph", - "WorkingFolder": "2-Authorization-I\\1-call-graph", - "Tags": [ - { "Name": "Spa" }, - { "Name": "MSAL JS" }, - { "Name": "PKCE" } - ], - "GitHubRepoSettings": { - "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-javascript-tutorial/blob/main/2-Authorization-I/1-call-graph/README.md", - "TutorialLink": "https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-javascript-auth-code", - "ClonePath": "https://github.com/Azure-Samples/ms-identity-javascript-tutorial.git", - "LocalPath": "JS\\CallGraph" - }, - "Projects": [ - { - "Name": "Client Project", - "ProjectPath": "2-Authorization-I\\1-call-graph", - "Order": "0", - "PortalSettings": { - "DisplayName": "ms-identity-javascript-tutorial-c2s1", - "SignInAudience": "AzureADMyOrg", - "AppType": "Spa", - "RedirectUri": "http://localhost:3000/", - "IsHybridFlow": "", - "IsDeviceCodeFlow": "", - "SecretName": "", - - "RequiredResourceAccesss": [ - { - "ResourceAppId": "00000003-0000-0000-c000-000000000000", - "ResourceAccesss": [ - { - "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", - "Type": "Scope" - } - ] - } - ] - }, - "ReplacementFields": [ - { - "Name": "ClientId", - "ReplacementType": "TXT", - "Format": "", - "Source": "persistdata:Projects[0].App.AppId", - "Destination": "Enter_the_Application_Id_Here", - "FileName": "App\\authConfig.js" - }, - { - "Name": "Authority", - "ReplacementType": "TXT", - "Format": "", - "Source": "persistdata:Projects[0].TenantId", - "Destination": "Enter_the_Tenant_Info_Here", - "FileName": "App\\authConfig.js" - }, - { - "Name": "redirectURi", - "ReplacementType": "TXT", - "Format": "", - "Source": "http://localhost:3000/", - "Destination": "Enter_the_Redirect_Uri_Here", - "FileName": "App\\authConfig.js" - } - ] - } - ], - "Prerequisites": [ - { - "Name": "VSCode", - "DownloadLink": "https://code.visualstudio.com/download" - }, - { - "Name": "NPM", - "DownloadLink": "https://docs.npmjs.com/downloading-and-installing-node-js-and-npm" - } - ] - } - ] - }, - { - "Name": "Node", - "DisplayName": "Node.js", - "Samples": [ - { - "Name": "Sign In Users", - "Type": "NodeJS", - "DisplayName": "A Node.js & Express web app authenticating users against Azure AD with MSAL Nod", - "WorkingFolder": "1-Authentication\\1-sign-in", - "Tags": [ - { "Name": "Node" }, - { "Name": "MSAL JS" }, - { "Name": "Auth Code Flow" } - ], - "GitHubRepoSettings": { - "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-javascript-nodejs-tutorial/blob/main/1-Authentication/1-sign-in/README.md", - "TutorialLink": "https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-nodejs-webapp-msal", - "ClonePath": "https://github.com/Azure-Samples/ms-identity-javascript-nodejs-tutorial.git", - "LocalPath": "NodeJS\\SignIn" - }, - "Projects": [ - { - "Name": "Client Project", - "ProjectPath": "1-Authentication\\1-sign-in", - "Order": "0", - "PortalSettings": { - "DisplayName": "msal-node-webapp", - "SignInAudience": "AzureADMyOrg", - "AppType": "Web", - "RedirectUri": "http://localhost:4000/redirect", - "IsHybridFlow": "True", + "RedirectUri": "http://localhost:3000/", + "IsHybridFlow": "", "IsDeviceCodeFlow": "", - "SecretName": "appsecret", + "SecretName": "", "RequiredResourceAccesss": [ { @@ -2487,31 +3471,23 @@ "Format": "", "Source": "persistdata:Projects[0].App.AppId", "Destination": "Enter_the_Application_Id_Here", - "FileName": "App\\appSettings.js" + "FileName": "App\\authConfig.js" }, { - "Name": "TenantId", + "Name": "Authority", "ReplacementType": "TXT", "Format": "", "Source": "persistdata:Projects[0].TenantId", "Destination": "Enter_the_Tenant_Info_Here", - "FileName": "App\\appSettings.js" - }, - { - "Name": "ClientSecret", - "ReplacementType": "TXT", - "Format": "", - "Source": "persistdata:Projects[0].SecretText", - "Destination": "Enter_the_Client_Secret_Here", - "FileName": "App\\appSettings.js" + "FileName": "App\\authConfig.js" }, { - "Name": "ClientSecret", + "Name": "redirectURi", "ReplacementType": "TXT", "Format": "", - "Source": "persistdata:Projects[0].SecretText", - "Destination": "ENTER_YOUR_SECRET_HERE", - "FileName": "App\\app.js" + "Source": "http://localhost:3000/", + "Destination": "Enter_the_Redirect_Uri_Here", + "FileName": "App\\authConfig.js" } ] } @@ -2528,34 +3504,35 @@ ] }, { - "Name": "Call MS Graph", - "Type": "NodeJS", - "DisplayName": "A Node.js & Express web app calling Microsoft Graph using MSAL Node", - "WorkingFolder": "2-Authorization\\1-call-graph", + "Name": "Call Microsoft Graph", + "Type": "Javascript", + "PlatformType": "Spa", + "DisplayName": "Vanilla JavaScript single-page application using MSAL.js to authorize users for calling Microsoft Graph", + "WorkingFolder": "2-Authorization-I\\1-call-graph", "Tags": [ - { "Name": "Node" }, - { "Name": "MSAL JS" }, - { "Name": "Auth Code Flow" } + { "Name": "SignIn" }, + { "Name": "CallGraph" }, + { "Name": "PKCE" } ], "GitHubRepoSettings": { - "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-javascript-nodejs-tutorial/blob/main/2-Authorization/1-call-graph/README.md", - "TutorialLink": "https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-nodejs-webapp-msal", - "ClonePath": "https://github.com/Azure-Samples/ms-identity-javascript-nodejs-tutorial.git", - "LocalPath": "NodeJS\\CallGraph" + "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-javascript-tutorial/blob/main/2-Authorization-I/1-call-graph/README.md", + "TutorialLink": "https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-javascript-auth-code", + "ClonePath": "https://github.com/Azure-Samples/ms-identity-javascript-tutorial.git", + "LocalPath": "JS\\CallGraph" }, "Projects": [ { "Name": "Client Project", - "ProjectPath": "2-Authorization\\1-call-graph", + "ProjectPath": "2-Authorization-I\\1-call-graph", "Order": "0", "PortalSettings": { - "DisplayName": "msal-node-webapp", + "DisplayName": "ms-identity-javascript-tutorial-c2s1", "SignInAudience": "AzureADMyOrg", - "AppType": "Web", - "RedirectUri": "http://localhost:4000/redirect", - "IsHybridFlow": "True", + "AppType": "Spa", + "RedirectUri": "http://localhost:3000/", + "IsHybridFlow": "", "IsDeviceCodeFlow": "", - "SecretName": "appsecret", + "SecretName": "", "RequiredResourceAccesss": [ { @@ -2566,15 +3543,6 @@ "Type": "Scope" } ] - }, - { - "resourceAppId": "797f4846-ba00-4fd7-ba43-dac1f8f63013", - "resourceAccess": [ - { - "id": "41094075-9dad-400e-a0bd-54e686782033", - "type": "Scope" - } - ] } ] }, @@ -2585,31 +3553,23 @@ "Format": "", "Source": "persistdata:Projects[0].App.AppId", "Destination": "Enter_the_Application_Id_Here", - "FileName": "App\\appSettings.js" + "FileName": "App\\authConfig.js" }, { - "Name": "TenantId", + "Name": "Authority", "ReplacementType": "TXT", "Format": "", "Source": "persistdata:Projects[0].TenantId", "Destination": "Enter_the_Tenant_Info_Here", - "FileName": "App\\appSettings.js" - }, - { - "Name": "ClientSecret", - "ReplacementType": "TXT", - "Format": "", - "Source": "persistdata:Projects[0].SecretText", - "Destination": "Enter_the_Client_Secret_Here", - "FileName": "App\\appSettings.js" + "FileName": "App\\authConfig.js" }, { - "Name": "ClientSecret", + "Name": "redirectURi", "ReplacementType": "TXT", "Format": "", - "Source": "persistdata:Projects[0].SecretText", - "Destination": "ENTER_YOUR_SECRET_HERE", - "FileName": "App\\app.js" + "Source": "http://localhost:3000/", + "Destination": "Enter_the_Redirect_Uri_Here", + "FileName": "App\\authConfig.js" } ] } @@ -2628,21 +3588,23 @@ ] }, { - "Name": "WPF", + "Name": "Wpf", "DisplayName": "WPF", + "Type": "PublicClient", "Samples": [ { "Name": "WPF app calling Graph", - "Type": "WPFMSAL", + "Type": "Wpf", + "PlatformType": "PublicClient", "DisplayName": "WPF application signing in users with Microsoft and calling the Microsoft Graph", "WorkingFolder": "", "Tags": [ - { "Name": "Desktop" }, - { "Name": "WPF" }, + { "Name": "SignIn" }, + { "Name": "CallGraph" }, { "Name": "MSAL.NET" }, { "Name": "WAM" }, - { "Name": "System browser" }, - { "Name": "PKCE Flow" } + { "Name": "Desktop" }, + { "Name": "PKCE" } ], "GitHubRepoSettings": { "ReadMeLink": "https://github.com/Azure-Samples/active-directory-dotnet-desktop-msgraph-v2/blob/master/README.md", @@ -2702,16 +3664,18 @@ }, { "Name": "WPF app calling ASP.NET core API", - "Type": "WPFMSAL", + "Type": "Wpf", + "PlatformType": "PublicClient", "DisplayName": "Sign-in a user with the Microsoft Identity Platform in a WPF Desktop application and call an ASP.NET Core Web API", "WorkingFolder": "1. Desktop app calls Web API", "Tags": [ - { "Name": "Desktop" }, - { "Name": "WPF" }, + { "Name": "SignIn" }, + { "Name": "CallCustomApi" }, { "Name": "MSAL.NET" }, + { "Name": "Microsoft.Identity.Web" }, { "Name": "WAM" }, { "Name": "System browser" }, - { "Name": "PKCE Flow" } + { "Name": "PKCE" } ], "GitHubRepoSettings": { "ReadMeLink": "https://github.com/Azure-Samples/active-directory-dotnet-native-aspnetcore-v2/blob/master/1.%20Desktop%20app%20calls%20Web%20API/README.md", @@ -2843,21 +3807,24 @@ }, { "Name": "XAMARIN", + "Type": "PublicClient", "DisplayName": "XAMARIN", "Samples": [ { - "Name": "Sign in users in XAMARIN", + "Name": "Sign in users", "Type": "XAMARIN", + "PlatformType": "PublicClient", "DisplayName": "Integrate Microsoft identity and the Microsoft Graph into a Xamarin forms app using MSAL", "WorkingFolder": "1-Basic", "Tags": [ + { "Name": "SignIn" }, { "Name": "Mobile" }, - { "Name": "UWP" }, { "Name": "ANDROID/IOS" }, { "Name": "XAMARIN" }, - { "Name": "MSAL Net" }, + { "Name": "MSAL.Net" }, { "Name": "Broker" }, - { "Name": "PKCE Flow" } + { "Name": "Wam" }, + { "Name": "PKCE" } ], "GitHubRepoSettings": { "ReadMeLink": "https://github.com/Azure-Samples/active-directory-xamarin-native-v2/blob/main/1-Basic/README.md", @@ -2948,24 +3915,25 @@ } ] } - + ] }, { "Name": "Android", + "Type": "PublicClient", "DisplayName": "Android", "Samples": [ { "Name": "Sign in users and call Microsoft Graph(Java Android)", "Type": "JavaAndroid", + "PlatformType": "PublicClient", "DisplayName": "Use MSAL in an Android app to sign-in users and call Microsoft Graph", "WorkingFolder": "", "Tags": [ - { "Name": "Mobile" }, - { "Name": "Android Kotlin" }, - { "Name": "MSAL Android" }, + { "Name": "SignIn" }, + { "Name": "MSAL.Android" }, { "Name": "Broker" }, - { "Name": "PKCE Flow" } + { "Name": "PKCE" } ], "GitHubRepoSettings": { "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-android-java/blob/master/README.md", @@ -3041,15 +4009,15 @@ }, { "Name": "Sign in users and call Microsoft Graph(Java Kotlin)", - "Type": "JavaKotlin", + "Type": "JavaKotlinAndroid", + "PlatformType": "PublicClient", "DisplayName": "Use MSAL in an Android app to sign-in users and call Microsoft Graph", "WorkingFolder": "", "Tags": [ - { "Name": "Mobile" }, - { "Name": "Android Kotlin" }, - { "Name": "MSAL Android" }, + { "Name": "SignIn" }, + { "Name": "MSAL.Android" }, { "Name": "Broker" }, - { "Name": "PKCE Flow" } + { "Name": "PKCE" } ], "GitHubRepoSettings": { "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-android-kotlin/blob/master/README.md", @@ -3123,181 +4091,108 @@ } ] } + //{ + // "Name": "Sign in users and display profile pic(Java Kotlin)", + // "Type": "JavaKotlinAndroid", + // "PlatformType": "PublicClient", + // "DisplayName": "Use MSAL in an Android app to sign-in users and call Microsoft Graph", + // "WorkingFolder": "", + // "Tags": [ + // { "Name": "SignIn" }, + // { "Name": "MSAL.Android" }, + // { "Name": "Broker" }, + // { "Name": "PKCE" } + // ], + // "GitHubRepoSettings": { + // "ReadMeLink": "https://github.com/idaceappdev/ms-identity-android-kotlin/blob/master/README.md", + // "TutorialLink": "https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-android", + // "ClonePath": "https://github.com/idaceappdev/ms-identity-android-kotlin.git", + // "LocalPath": "AndroidKotlin\\CallGraph" + // }, + // "Projects": [ + // { + // "Name": "Client Project", + // "ProjectPath": "", + // "Order": "0", + // "PortalSettings": { + // "DisplayName": "AndroidKotlinApp", + // "SignInAudience": "AzureADandPersonalMicrosoftAccount", + // "AppType": "Desktop", + // "RedirectUri": "msauth://com.azuresamples.msalandroidkotlinapp/1wIqXSqBj7w%2Bh11ZifsnqwgyKrY%3D", + // "IsHybridFlow": "", + // "IsDeviceCodeFlow": "", + // "SecretName": "", + + // "RequiredResourceAccesss": [ + // { + // "ResourceAppId": "00000003-0000-0000-c000-000000000000", + // "ResourceAccesss": [ + // { + // "id": "b340eb25-3456-403f-be2f-af7a0d370277", + // "Type": "Scope" + // } + // ] + // } + // ] + // }, + // "ReplacementFields": [ + // { + // "Name": "ClientId", + // "ReplacementType": "JSON", + // "Section": "", + // "Source": "persistdata:Projects[0].App.AppId", + // "Destination": "client_id", + // "FileName": "app\\src\\main\\res\\raw\\auth_config_single_account.json" + // }, + // { + // "Name": "ClientId", + // "ReplacementType": "JSON", + // "Section": "", + // "Source": "persistdata:Projects[0].App.AppId", + // "Destination": "client_id", + // "FileName": "app\\src\\main\\res\\raw\\auth_config_multiple_account.json" + // } + // //{ + // // "Name": "Authority", + // // "ReplacementType": "JSON", + // // "Section": "", + // // "Format": "https://login.microsoftonline.com/{0}", + // // "Source": "persistdata:Projects[0].TenantId", + // // "Destination": "authorities:0:authority_url", + // // "FileName": "app\\src\\main\\res\\raw\\auth_config_single_account.json" + // //} + // ] + // } + // ], + // "Prerequisites": [ + // { + // "Name": "Java", + // "DownloadLink": "https://code.visualstudio.com/download" + // }, + // { + // "Name": "Android Studio", + // "DownloadLink": "https://visualstudio.microsoft.com/downloads/" + // } + // ] + //} ] }, { - "Name": "Python", + "Name": "PythonHeadlessConsole", + "Type": "Daemon", "DisplayName": "Python", "Samples": [ - { - "Name": "Sign in users in python flask web app", - "Type": "PythonFlask", - "DisplayName": "Enable your Python Flask webapp to sign in users to your Azure Active Directory tenant with the Microsoft identity platform", - "WorkingFolder": "", - "Tags": [ - { "Name": "Web App" }, - { "Name": "Python Flask" }, - { "Name": "MSAL Python" }, - { "Name": "Auth Code Flow" } - ], - "GitHubRepoSettings": { - "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-python-flask-webapp-authentication", - "TutorialLink": "https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-python-token-cache-serialization", - "ClonePath": "https://github.com/Azure-Samples/ms-identity-python-flask-webapp-authentication.git", - "LocalPath": "PythonFlask\\SignIn" - }, - "Projects": [ - { - "Name": "Client Project", - "ProjectPath": "", - "Order": "0", - "PortalSettings": { - "DisplayName": "python-flask-webapp-auth-my-tenant", - "SignInAudience": "AzureADMyOrg", - "AppType": "Web", - "RedirectUri": "https://127.0.0.1:5000/auth/redirect", - "IsHybridFlow": "", - "IsDeviceCodeFlow": "", - "SecretName": "mysecret", - - "RequiredResourceAccesss": [ - { - "ResourceAppId": "00000003-0000-0000-c000-000000000000", - "ResourceAccesss": [ - { - "Id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", - "Type": "Scope" - } - ] - } - ] - }, - "ReplacementFields": [ - { - "Name": "ClientId", - "ReplacementType": "JSON", - "Section": "client", - "Source": "persistdata:Projects[0].App.AppId", - "Destination": "client_id", - "FileName": "aad.config.json" - }, - { - "Name": "TenantId", - "ReplacementType": "JSON", - "Section": "client", - "Format": "https://login.microsoftonline.com/{0}", - "Source": "persistdata:Projects[0].TenantId", - "Destination": "authority", - "FileName": "aad.config.json" - }, - { - "Name": "ClientSecret", - "ReplacementType": "JSON", - "Section": "client", - "Format": "", - "Source": "persistdata:Projects[0].SecretText", - "Destination": "client_credential", - "FileName": "aad.config.json" - } - ] - } - ], - "Prerequisites": [ - { - "Name": "VSCode", - "DownloadLink": "https://code.visualstudio.com/download" - }, - { - "Name": "Python", - "DownloadLink": "https://www.python.org/downloads/release/python-380/" - } - ] - }, - { - "Name": "Python flask web app calling graph API", - "Type": "PythonFlask", - "DisplayName": "This sample demonstrates a Python web application calling a Microsoft Graph that is secured using Azure Active Directory.", - "WorkingFolder": "", - "Tags": [ - { "Name": "Web App" }, - { "Name": "Python Flask" }, - { "Name": "MSAL Python" }, - { "Name": "Auth Code Flow" } - ], - "GitHubRepoSettings": { - "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-python-webapp", - "TutorialLink": "https://docs.microsoft.com/en-us/samples/azure-samples/ms-identity-python-webapp/ms-identity-python-webapp/", - "ClonePath": "https://github.com/Azure-Samples/ms-identity-python-webapp.git", - "LocalPath": "PythonFlask\\CallGraphAPI" - }, - "Projects": [ - { - "Name": "Client Project", - "ProjectPath": "", - "Order": "0", - "PortalSettings": { - "DisplayName": "python-webapp", - "SignInAudience": "AzureADandPersonalMicrosoftAccount", - "AppType": "Web", - "RedirectUri": "http://localhost:5000/getAToken", - "IsHybridFlow": "", - "IsDeviceCodeFlow": "", - "SecretName": "appsecret", - - "RequiredResourceAccesss": [ - { - "ResourceAppId": "00000003-0000-0000-c000-000000000000", - "ResourceAccesss": [ - { - "id": "b340eb25-3456-403f-be2f-af7a0d370277", - "Type": "Scope" - } - ] - } - ] - }, - "ReplacementFields": [ - { - "Name": "ClientId", - "ReplacementType": "TXT", - "Section": "client", - "Source": "persistdata:Projects[0].App.AppId", - "Destination": "Enter_the_Application_Id_here", - "FileName": "app_config.py" - }, - { - "Name": "ClientSecret", - "ReplacementType": "TXT", - "Section": "client", - "Format": "", - "Source": "persistdata:Projects[0].SecretText", - "Destination": "Enter_the_Client_Secret_Here", - "FileName": "app_config.py" - } - ] - } - ], - "Prerequisites": [ - { - "Name": "VSCode", - "DownloadLink": "https://code.visualstudio.com/download" - }, - { - "Name": "Python", - "DownloadLink": "https://www.python.org/downloads/release/python-380/" - } - ] - }, { "Name": "Daemon - Call Microsoft Graph with secret", - "Type": "Python", + "Type": "PythonHeadlessConsole", + "PlatformType": "Daemon", "DisplayName": "A simple Python daemon console application calling Microsoft Graph with its own identity (client secret variation)", "WorkingFolder": "1-Call-MsGraph-WithSecret", "Tags": [ { "Name": "Daemon" }, { "Name": "Python" }, - { "Name": "MSAL Python" }, - { "Name": "Client credential flow" } + { "Name": "MSAL.Python" }, + { "Name": "Client Credential Flow" } ], "GitHubRepoSettings": { "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-python-daemon/tree/master/1-Call-MsGraph-WithSecret", @@ -3377,14 +4272,16 @@ }, { "Name": "Daemon - Call Microsoft Graph with Certificate", - "Type": "Python", + "Type": "PythonHeadlessConsole", + "PlatformType": "Daemon", "DisplayName": "A simple Python daemon console application calling Microsoft Graph with its own identity (client certificate variation)", "WorkingFolder": "2-Call-MsGraph-WithCertificate", "Tags": [ { "Name": "Daemon" }, { "Name": "Python" }, - { "Name": "MSAL Python" }, - { "Name": "Client credential flow" } + { "Name": "WithCertificate" }, + { "Name": "MSAL.Python" }, + { "Name": "Client Credential Flow" } ], "GitHubRepoSettings": { "ReadMeLink": "https://github.com/Azure-Samples/ms-identity-python-daemon/blob/master/2-Call-MsGraph-WithCertificate/README.md", diff --git a/IdAceCodeEditor/IdAceCodeEditor.csproj b/IdAceCodeEditor/IdAceCodeEditor.csproj index 655d009..5697c3e 100644 --- a/IdAceCodeEditor/IdAceCodeEditor.csproj +++ b/IdAceCodeEditor/IdAceCodeEditor.csproj @@ -5,6 +5,7 @@ netcoreapp3.1 true bin + getsitelogo.ico @@ -13,6 +14,10 @@ + + + + diff --git a/IdAceCodeEditor/Models/DataSource.cs b/IdAceCodeEditor/Models/DataSource.cs index 89c715a..81c86a9 100644 --- a/IdAceCodeEditor/Models/DataSource.cs +++ b/IdAceCodeEditor/Models/DataSource.cs @@ -2,15 +2,35 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Runtime.CompilerServices; using System.Text; using System.Windows; using System.Windows.Input; namespace IdAceCodeEditor { - public class DataSource + public class DataSource : INotifyPropertyChanged { - public ObservableCollection Frameworks{ get; set; } + public event PropertyChangedEventHandler PropertyChanged; + protected void OnPropertyChanged([CallerMemberName] string name = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); + } + public ObservableCollection Frameworks{ get; set; } + + Framework _SelectedFramework; + public Framework SelectedFramework + { + get { return _SelectedFramework; } + set + { + _SelectedFramework = value; + // Call OnPropertyChanged whenever the property is updated + OnPropertyChanged(); + } + } + public ObservableCollection Samples { get; set; } private ICommand _guideMeCommand; diff --git a/IdAceCodeEditor/Models/Framework.cs b/IdAceCodeEditor/Models/Framework.cs index ee95e17..5091d0d 100644 --- a/IdAceCodeEditor/Models/Framework.cs +++ b/IdAceCodeEditor/Models/Framework.cs @@ -11,6 +11,7 @@ public class Framework { public string Name { get; set; } public string DisplayName { get; set; } + public string Type { get; set; } public ObservableCollection Samples { get; set; } } diff --git a/IdAceCodeEditor/Models/Sample.cs b/IdAceCodeEditor/Models/Sample.cs index 911c586..692a0ac 100644 --- a/IdAceCodeEditor/Models/Sample.cs +++ b/IdAceCodeEditor/Models/Sample.cs @@ -2,18 +2,36 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Runtime.CompilerServices; using System.Text; using System.Windows; using System.Windows.Input; namespace IdAceCodeEditor { - public class Sample + public class Sample : INotifyPropertyChanged { + public event PropertyChangedEventHandler PropertyChanged; + protected void OnPropertyChanged([CallerMemberName] string name = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); + } + bool _IsSelected; + public bool IsSelected + { + get { return _IsSelected; } + set + { + _IsSelected = value; + // Call OnPropertyChanged whenever the property is updated + OnPropertyChanged(); + } + } public string Name { get; set; } public string DisplayName { get; set; } public string Type { get; set; } - + public string PlatformType { get; set; } public string WorkingFolder { get; set; } public GitHubRepo GitHubRepoSettings{ get; set; } public ObservableCollection Projects { get; set; } diff --git a/IdAceCodeEditor/Views/GuideMeWindow.xaml b/IdAceCodeEditor/Views/GuideMeWindow.xaml index a5f5b07..819cb6e 100644 --- a/IdAceCodeEditor/Views/GuideMeWindow.xaml +++ b/IdAceCodeEditor/Views/GuideMeWindow.xaml @@ -5,45 +5,71 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:IdAceCodeEditor.Views" mc:Ignorable="d" - Title="GuideMeWindow" Height="650" Width="420" WindowStartupLocation="CenterOwner"> + Title="GuideMeWindow" Height="655" Width="700" Closing="Window_Closing" WindowStartupLocation="CenterOwner"> - - - - + + + + - - - Select the aplication platform - - + + + + + + + + Web Application + SPA - Single page application + + + Public Client - Mobile/Desktop + Daemon - No user involved + + - + - If the application interactive and user is involved, then please select this option - If the application daemon and operates without UI, then please select this option + Select your aplication framework + - - - Application implements sign-in feature to the users - Application implements sign-in feature to the users and then calls graph resources - Application implements sign-in feature to the users and then calls custom API - + + + + + + + + User should Sign In to app + App Calls Graph Api + App calls custom Api + + + Usage of certificate over secret + Integration with Azure KeyVault + CAE enabled client + + - + - Usage of certificate - Store Certificate in Azure KeyVault - CAE + + Based on your creteria, below samples are most relavent in the order of sequence. Select one and click submit button + + - + - - + + diff --git a/IdAceCodeEditor/Views/GuideMeWindow.xaml.cs b/IdAceCodeEditor/Views/GuideMeWindow.xaml.cs index ba8a55c..5513cf7 100644 --- a/IdAceCodeEditor/Views/GuideMeWindow.xaml.cs +++ b/IdAceCodeEditor/Views/GuideMeWindow.xaml.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; @@ -9,6 +11,7 @@ using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; +using Windows.Devices.Lights; namespace IdAceCodeEditor.Views { @@ -20,6 +23,100 @@ public partial class GuideMeWindow : Window public GuideMeWindow(DataSource framework) { InitializeComponent(); + ObservableCollection allSamples = new ObservableCollection(); + foreach (var frame in framework.Frameworks) + { + foreach (var samp in frame.Samples) + { + allSamples.Add(samp); + } + } + framework.Samples = allSamples; + this.DataContext = framework; + } + + private void RadioButton_Checked(object sender, RoutedEventArgs e) + { + var radioButton = sender as RadioButton; + var framworks = cmbFramework.ItemsSource; + + CollectionView itemsViewOriginal = (CollectionView)CollectionViewSource.GetDefaultView(cmbFramework.Items); + itemsViewOriginal.Filter = ((o) => + { + return ((Framework)o).Type.Equals(radioButton.Tag); + }); + itemsViewOriginal.Refresh(); + + CollectionView itemsViewOriginal2 = (CollectionView)CollectionViewSource.GetDefaultView(lstScenario.Items); + itemsViewOriginal2.Filter = ((o) => + { + return ((Sample)o).PlatformType.Equals(radioButton.Tag); + }); + itemsViewOriginal2.Refresh(); + } + + private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) + { + CollectionView itemsViewOriginal = (CollectionView)CollectionViewSource.GetDefaultView(cmbFramework.Items); + itemsViewOriginal.Filter = ((o) => + { + return true; + }); + itemsViewOriginal.Refresh(); + } + private void cmbFramework_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + var comboBox = sender as ComboBox; + Framework framework= comboBox.SelectedItem as Framework; + + if (framework != null && comboBox!=null) + { + CollectionView itemsViewOriginal2 = (CollectionView)CollectionViewSource.GetDefaultView(lstScenario.Items); + itemsViewOriginal2.Filter = ((o) => + { + return ((Sample)o).Type.Contains(framework.Name) || + framework.Name.Contains(((Sample)o).Type); + }); + itemsViewOriginal2.Refresh(); + } + } + + private void Submit_Click(object sender, RoutedEventArgs e) + { + Framework framework= cmbFramework.SelectedItem as Framework; + Sample sample = lstScenario.SelectedItem as Sample; + + if (sample != null && framework.Samples != null) + { + foreach (var item in framework.Samples) + { + if (item.Name.Equals(sample.Name)) + item.IsSelected = true; + } + } + this.Close(); + } + + private void Cancel_Click(object sender, RoutedEventArgs e) + { + this.Close(); + } + + private void CheckBox_Checked(object sender, RoutedEventArgs e) + { + Framework framework = cmbFramework.SelectedItem as Framework; + + if (framework != null ) + { + CollectionView itemsViewOriginal2 = (CollectionView)CollectionViewSource.GetDefaultView( + lstScenario.Items); + itemsViewOriginal2.Filter = ((o) => + { + return ((Sample)o).Tags.Any(o=> o.Name.Equals("WithCertificate")); + }); + itemsViewOriginal2.Refresh(); + } } } } + diff --git a/IdAceCodeEditor/Views/IdAceCodeEditor.xaml b/IdAceCodeEditor/Views/IdAceCodeEditor.xaml index 100fc73..2445de5 100644 --- a/IdAceCodeEditor/Views/IdAceCodeEditor.xaml +++ b/IdAceCodeEditor/Views/IdAceCodeEditor.xaml @@ -6,7 +6,7 @@ xmlns:local="clr-namespace:IdAceCodeEditor" mc:Ignorable="d" Loaded="Window_Loaded" - Title="IdAceCodeEditor" Height="500" Width="800"> + Title="IDAceCodeEditor" Height="500" Width="800"> - + @@ -71,7 +71,7 @@ @@ -163,7 +163,8 @@ - diff --git a/IdAceCodeEditor/getsitelogo.ico b/IdAceCodeEditor/getsitelogo.ico new file mode 100644 index 0000000000000000000000000000000000000000..f9f6821ca18de917256d402e54a7301b04985a0e GIT binary patch literal 4286 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 o