From bea14cc80a3099d7355b50d6d4b79586f66b218a Mon Sep 17 00:00:00 2001 From: DamianEdwards Date: Thu, 1 Jul 2021 16:05:50 -0700 Subject: [PATCH 01/12] Update webapp template to use top-level statements & minimal hosting API Contributes to #33947 #33944 --- .../content/RazorPagesWeb-CSharp/Program.cs | 145 ++++++++++++++-- .../content/RazorPagesWeb-CSharp/Startup.cs | 157 ------------------ 2 files changed, 130 insertions(+), 172 deletions(-) delete mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Startup.cs diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Program.cs index 549d0b8bb8a1..75e799f25ec6 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Program.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Program.cs @@ -2,25 +2,140 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +#if (OrganizationalAuth || IndividualB2CAuth) +using Microsoft.AspNetCore.Authentication; +using Microsoft.Identity.Web; +using Microsoft.Identity.Web.UI; +using Microsoft.AspNetCore.Authentication.OpenIdConnect; +using Microsoft.AspNetCore.Authorization; +#endif +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; +#if (RequiresHttps) +using Microsoft.AspNetCore.HttpsPolicy; +#endif +#if (IndividualLocalAuth) +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Identity.UI; +#endif +#if (OrganizationalAuth) +using Microsoft.AspNetCore.Mvc.Authorization; +#endif +#if (IndividualLocalAuth) +using Microsoft.EntityFrameworkCore; +#endif using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; +#if(MultiOrgAuth) +using Microsoft.IdentityModel.Tokens; +#endif +#if (GenerateGraph) +using Microsoft.Graph; +#endif +#if (IndividualLocalAuth) +using Company.WebApplication1.Data; +#endif -namespace Company.WebApplication1 +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. +#if (IndividualLocalAuth) +builder.Services.AddDbContext(options => +#if (UseLocalDB) + options.UseSqlServer( + builder.Configuration.GetConnectionString("DefaultConnection"))); +#else + options.UseSqlite( + builder.Configuration.GetConnectionString("DefaultConnection"))); +#endif +builder.Services.AddDatabaseDeveloperPageExceptionFilter(); +builder.Services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true) + .AddEntityFrameworkStores(); +#elif (OrganizationalAuth) +#if (GenerateApiOrGraph) +var initialScopes = builder.Configuration.GetValue("DownstreamApi:Scopes")?.Split(' '); + +#endif +builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) +#if (GenerateApiOrGraph) + .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd")) + .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) +#if (GenerateApi) + .AddDownstreamWebApi("DownstreamApi", builder.Configuration.GetSection("DownstreamApi")) +#endif +#if (GenerateGraph) + .AddMicrosoftGraph(builder.Configuration.GetSection("DownstreamApi")) +#endif + .AddInMemoryTokenCaches(); +#else + .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd")); +#endif +#elif (IndividualB2CAuth) +#if (GenerateApi) +var initialScopes = builder.Configuration.GetValue("DownstreamApi:Scopes")?.Split(' '); + +#endif +builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) +#if (GenerateApi) + .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAdB2C")) + .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) + .AddDownstreamWebApi("DownstreamApi", builder.Configuration.GetSection("DownstreamApi")) + .AddInMemoryTokenCaches(); +#else + .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAdB2C")); +#endif +#endif +#if (OrganizationalAuth) + +builder.Services.AddAuthorization(options => +{ + // By default, all incoming requests will be authorized according to the default policy. + options.FallbackPolicy = options.DefaultPolicy; +}); +builder.Services.AddRazorPages() + .AddMvcOptions(options => {}) + .AddMicrosoftIdentityUI(); +#elif (IndividualB2CAuth) +builder.Services.AddRazorPages() + .AddMicrosoftIdentityUI(); +#else +builder.Services.AddRazorPages(); +#endif + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) { - public class Program - { - public static void Main(string[] args) - { - CreateHostBuilder(args).Build().Run(); - } - - public static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - }); - } + app.UseDeveloperExceptionPage(); +#if (IndividualLocalAuth) + app.UseMigrationsEndPoint(); +#endif } +else +{ + app.UseExceptionHandler("/Error"); +#if (RequiresHttps) + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseHsts(); +} + +app.UseHttpsRedirection(); +#else +} +#endif +app.UseStaticFiles(); + +#if (OrganizationalAuth || IndividualAuth) +app.UseAuthentication(); +#endif +app.UseAuthorization(); + +app.MapRazorPages(); +#if (IndividualB2CAuth || OrganizationalAuth) +app.MapControllers(); +#endif + +app.Run(); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Startup.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Startup.cs deleted file mode 100644 index 36409d8e2642..000000000000 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Startup.cs +++ /dev/null @@ -1,157 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -#if (OrganizationalAuth || IndividualB2CAuth) -using Microsoft.AspNetCore.Authentication; -using Microsoft.Identity.Web; -using Microsoft.Identity.Web.UI; -using Microsoft.AspNetCore.Authentication.OpenIdConnect; -using Microsoft.AspNetCore.Authorization; -#endif -using Microsoft.AspNetCore.Builder; -#if (IndividualLocalAuth) -using Microsoft.AspNetCore.Identity; -using Microsoft.AspNetCore.Identity.UI; -#endif -using Microsoft.AspNetCore.Hosting; -#if (RequiresHttps) -using Microsoft.AspNetCore.HttpsPolicy; -#endif -#if (OrganizationalAuth) -using Microsoft.AspNetCore.Mvc.Authorization; -#endif -#if (IndividualLocalAuth) -using Microsoft.EntityFrameworkCore; -using Company.WebApplication1.Data; -#endif -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -#if(MultiOrgAuth) -using Microsoft.IdentityModel.Tokens; -#endif -#if (GenerateGraph) -using Microsoft.Graph; -#endif - -namespace Company.WebApplication1 -{ - public class Startup - { - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } - - public IConfiguration Configuration { get; } - - // This method gets called by the runtime. Use this method to add services to the container. - public void ConfigureServices(IServiceCollection services) - { -#if (IndividualLocalAuth) - services.AddDbContext(options => -#if (UseLocalDB) - options.UseSqlServer( - Configuration.GetConnectionString("DefaultConnection"))); -#else - options.UseSqlite( - Configuration.GetConnectionString("DefaultConnection"))); -#endif - services.AddDatabaseDeveloperPageExceptionFilter(); - services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true) - .AddEntityFrameworkStores(); -#elif (OrganizationalAuth) -#if (GenerateApiOrGraph) - var initialScopes = Configuration.GetValue("DownstreamApi:Scopes")?.Split(' '); - -#endif - services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) -#if (GenerateApiOrGraph) - .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd")) - .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) -#if (GenerateApi) - .AddDownstreamWebApi("DownstreamApi", Configuration.GetSection("DownstreamApi")) -#endif -#if (GenerateGraph) - .AddMicrosoftGraph(Configuration.GetSection("DownstreamApi")) -#endif - .AddInMemoryTokenCaches(); -#else - .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd")); -#endif -#elif (IndividualB2CAuth) -#if (GenerateApi) - var initialScopes = Configuration.GetValue("DownstreamApi:Scopes")?.Split(' '); - -#endif - services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) -#if (GenerateApi) - .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAdB2C")) - .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) - .AddDownstreamWebApi("DownstreamApi", Configuration.GetSection("DownstreamApi")) - .AddInMemoryTokenCaches(); -#else - .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAdB2C")); -#endif -#endif -#if (OrganizationalAuth) - - services.AddAuthorization(options => - { - // By default, all incoming requests will be authorized according to the default policy - options.FallbackPolicy = options.DefaultPolicy; - }); - services.AddRazorPages() - .AddMvcOptions(options => {}) - .AddMicrosoftIdentityUI(); -#elif (IndividualB2CAuth) - services.AddRazorPages() - .AddMicrosoftIdentityUI(); -#else - services.AddRazorPages(); -#endif - } - - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); -#if (IndividualLocalAuth) - app.UseMigrationsEndPoint(); -#endif - } - else - { - app.UseExceptionHandler("/Error"); -#if (RequiresHttps) - // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. - app.UseHsts(); - } - - app.UseHttpsRedirection(); -#else - } - -#endif - app.UseStaticFiles(); - - app.UseRouting(); - -#if (OrganizationalAuth || IndividualAuth) - app.UseAuthentication(); -#endif - app.UseAuthorization(); - - app.UseEndpoints(endpoints => - { - endpoints.MapRazorPages(); -#if (IndividualB2CAuth || OrganizationalAuth) - endpoints.MapControllers(); -#endif - }); - } - } -} From 1f0820373fbfe234d43c186822aec12bb43dbda2 Mon Sep 17 00:00:00 2001 From: DamianEdwards Date: Fri, 2 Jul 2021 12:36:56 -0700 Subject: [PATCH 02/12] Remove unused usings from WebApp template --- .../content/RazorPagesWeb-CSharp/Program.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Program.cs index 75e799f25ec6..f0d7347c4e67 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Program.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Program.cs @@ -11,12 +11,8 @@ #endif using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; -#if (RequiresHttps) -using Microsoft.AspNetCore.HttpsPolicy; -#endif #if (IndividualLocalAuth) using Microsoft.AspNetCore.Identity; -using Microsoft.AspNetCore.Identity.UI; #endif #if (OrganizationalAuth) using Microsoft.AspNetCore.Mvc.Authorization; @@ -28,7 +24,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; -#if(MultiOrgAuth) +#if (MultiOrgAuth) using Microsoft.IdentityModel.Tokens; #endif #if (GenerateGraph) From 14ced02225ab66a477ab2be34e0208d9f53b8970 Mon Sep 17 00:00:00 2001 From: DamianEdwards Date: Fri, 2 Jul 2021 13:03:56 -0700 Subject: [PATCH 03/12] Updated StarterWeb template: - Using minimal hosting APIs - Using top-level statements --- .../content/RazorPagesWeb-CSharp/Program.cs | 1 + .../content/StarterWeb-CSharp/Program.cs | 144 ++++++++++++++-- .../content/StarterWeb-CSharp/Startup.cs | 158 ------------------ 3 files changed, 130 insertions(+), 173 deletions(-) delete mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Startup.cs diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Program.cs index f0d7347c4e67..276988c393ac 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Program.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Program.cs @@ -47,6 +47,7 @@ builder.Configuration.GetConnectionString("DefaultConnection"))); #endif builder.Services.AddDatabaseDeveloperPageExceptionFilter(); + builder.Services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores(); #elif (OrganizationalAuth) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Program.cs index 549d0b8bb8a1..fa22b07c2215 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Program.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Program.cs @@ -2,25 +2,139 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +#if (OrganizationalAuth || IndividualB2CAuth) +using Microsoft.AspNetCore.Authentication; +using Microsoft.Identity.Web; +using Microsoft.Identity.Web.UI; +using Microsoft.AspNetCore.Authentication.OpenIdConnect; +using Microsoft.AspNetCore.Authorization; +#endif +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; +#if (IndividualLocalAuth) +using Microsoft.AspNetCore.Identity; +#endif +#if (OrganizationalAuth) +using Microsoft.AspNetCore.Mvc.Authorization; +#endif +#if (IndividualLocalAuth) +using Microsoft.EntityFrameworkCore; +#endif using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; +#if (MultiOrgAuth) +using Microsoft.IdentityModel.Tokens; +#endif +#if (GenerateGraph) +using Microsoft.Graph; +#endif +#if (IndividualLocalAuth) +using Company.WebApplication1.Data; +#endif -namespace Company.WebApplication1 +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. +#if (IndividualLocalAuth) +builder.Services.AddDbContext(options => +#if (UseLocalDB) + options.UseSqlServer( + builder.Configuration.GetConnectionString("DefaultConnection"))); +#else + options.UseSqlite( + builder.Configuration.GetConnectionString("DefaultConnection"))); +#endif +builder.Services.AddDatabaseDeveloperPageExceptionFilter(); + +builder.Services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true) + .AddEntityFrameworkStores(); +#elif (OrganizationalAuth) +#if (GenerateApiOrGraph) +var initialScopes = builder.Configuration.GetValue("DownstreamApi:Scopes")?.Split(' '); + +#endif +builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) +#if (GenerateApiOrGraph) + .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd")) + .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) +#if (GenerateApi) + .AddDownstreamWebApi("DownstreamApi", builder.Configuration.GetSection("DownstreamApi")) +#endif +#if (GenerateGraph) + .AddMicrosoftGraph(builder.Configuration.GetSection("DownstreamApi")) +#endif + .AddInMemoryTokenCaches(); +#else + .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd")); +#endif +#elif (IndividualB2CAuth) +#if (GenerateApi) +var initialScopes = builder.Configuration.GetValue("DownstreamApi:Scopes")?.Split(' '); + +#endif +builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) +#if (GenerateApi) + .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAdB2C")) + .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) + .AddDownstreamWebApi("DownstreamApi", builder.Configuration.GetSection("DownstreamApi")) + .AddInMemoryTokenCaches(); +#else + .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAdB2C")); +#endif +#endif +#if (OrganizationalAuth) + +builder.Services.AddControllersWithViews(options => +{ + var policy = new AuthorizationPolicyBuilder() + .RequireAuthenticatedUser() + .Build(); + options.Filters.Add(new AuthorizeFilter(policy)); +}); +#else +builder.Services.AddControllersWithViews(); +#endif +#if (OrganizationalAuth || IndividualB2CAuth) +builder.Services.AddRazorPages() + .AddMicrosoftIdentityUI(); +#endif + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) { - public class Program - { - public static void Main(string[] args) - { - CreateHostBuilder(args).Build().Run(); - } - - public static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - }); - } + app.UseDeveloperExceptionPage(); +#if (IndividualLocalAuth) + app.UseMigrationsEndPoint(); +#endif } +else +{ + app.UseExceptionHandler("/Home/Error"); +#if (RequiresHttps) + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseHsts(); +} + +app.UseHttpsRedirection(); +#else +} +#endif +app.UseStaticFiles(); + +#if (OrganizationalAuth || IndividualAuth) +app.UseAuthentication(); +#endif +app.UseAuthorization(); + +app.MapControllerRoute( + name: "default", + pattern: "{controller=Home}/{action=Index}/{id?}"); +#if (OrganizationalAuth || IndividualAuth) +app.MapRazorPages(); +#endif + +app.Run(); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Startup.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Startup.cs deleted file mode 100644 index f9b4447b64c9..000000000000 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Startup.cs +++ /dev/null @@ -1,158 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -#if (OrganizationalAuth || IndividualB2CAuth) -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Authentication.OpenIdConnect; -using Microsoft.AspNetCore.Authorization; -using Microsoft.Identity.Web; -using Microsoft.Identity.Web.UI; -#endif -using Microsoft.AspNetCore.Builder; -#if (IndividualLocalAuth) -using Microsoft.AspNetCore.Identity; -using Microsoft.AspNetCore.Identity.UI; -#endif -using Microsoft.AspNetCore.Hosting; -#if (RequiresHttps) -using Microsoft.AspNetCore.HttpsPolicy; -#endif -#if (OrganizationalAuth) -using Microsoft.AspNetCore.Mvc.Authorization; -#endif -#if (IndividualLocalAuth) -using Microsoft.EntityFrameworkCore; -using Company.WebApplication1.Data; -#endif -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -#if(MultiOrgAuth) -using Microsoft.IdentityModel.Tokens; -#endif -#if (GenerateGraph) -using Microsoft.Graph; -#endif - -namespace Company.WebApplication1 -{ - public class Startup - { - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } - - public IConfiguration Configuration { get; } - - // This method gets called by the runtime. Use this method to add services to the container. - public void ConfigureServices(IServiceCollection services) - { -#if (IndividualLocalAuth) - services.AddDbContext(options => -#if (UseLocalDB) - options.UseSqlServer( - Configuration.GetConnectionString("DefaultConnection"))); -#else - options.UseSqlite( - Configuration.GetConnectionString("DefaultConnection"))); -#endif - services.AddDatabaseDeveloperPageExceptionFilter(); - - services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true) - .AddEntityFrameworkStores(); -#elif (OrganizationalAuth) -#if (GenerateApiOrGraph) - var initialScopes = Configuration.GetValue("DownstreamApi:Scopes")?.Split(' '); - -#endif - services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) -#if (GenerateApiOrGraph) - .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd")) - .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) -#if (GenerateApi) - .AddDownstreamWebApi("DownstreamApi", Configuration.GetSection("DownstreamApi")) -#endif -#if (GenerateGraph) - .AddMicrosoftGraph(Configuration.GetSection("DownstreamApi")) -#endif - .AddInMemoryTokenCaches(); -#else - .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd")); -#endif -#elif (IndividualB2CAuth) -#if (GenerateApi) - var initialScopes = Configuration.GetValue("DownstreamApi:Scopes")?.Split(' '); - -#endif - services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) -#if (GenerateApi) - .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAdB2C")) - .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) - .AddDownstreamWebApi("DownstreamApi", Configuration.GetSection("DownstreamApi")) - .AddInMemoryTokenCaches(); -#else - .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAdB2C")); -#endif -#endif -#if (OrganizationalAuth) - - services.AddControllersWithViews(options => - { - var policy = new AuthorizationPolicyBuilder() - .RequireAuthenticatedUser() - .Build(); - options.Filters.Add(new AuthorizeFilter(policy)); - }); -#else - services.AddControllersWithViews(); -#endif -#if (OrganizationalAuth || IndividualB2CAuth) - services.AddRazorPages() - .AddMicrosoftIdentityUI(); -#endif - } - - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); -#if (IndividualLocalAuth) - app.UseMigrationsEndPoint(); -#endif - } - else - { - app.UseExceptionHandler("/Home/Error"); -#if (RequiresHttps) - // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. - app.UseHsts(); - } - app.UseHttpsRedirection(); -#else - } -#endif - app.UseStaticFiles(); - - app.UseRouting(); - -#if (OrganizationalAuth || IndividualAuth) - app.UseAuthentication(); -#endif - app.UseAuthorization(); - - app.UseEndpoints(endpoints => - { - endpoints.MapControllerRoute( - name: "default", - pattern: "{controller=Home}/{action=Index}/{id?}"); -#if (OrganizationalAuth || IndividualAuth) - endpoints.MapRazorPages(); -#endif - }); - } - } -} From edbb92013dcd1ba889d96f48880c0222211096d0 Mon Sep 17 00:00:00 2001 From: DamianEdwards Date: Fri, 2 Jul 2021 13:44:16 -0700 Subject: [PATCH 04/12] Updated gRPC template: - using minimal hosting APIs - using top-level statements --- .../content/GrpcService-CSharp/Program.cs | 38 +++++++++------- .../content/GrpcService-CSharp/Startup.cs | 44 ------------------- 2 files changed, 21 insertions(+), 61 deletions(-) delete mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/Startup.cs diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/Program.cs index d1f9df7226d6..0036b6b5b0dc 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/Program.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/Program.cs @@ -3,25 +3,29 @@ using System.IO; using System.Linq; using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using GrpcService_CSharp.Services; -namespace GrpcService_CSharp -{ - public class Program - { - public static void Main(string[] args) - { - CreateHostBuilder(args).Build().Run(); - } +var builder = WebApplication.CreateBuilder(args); + +// Additional configuration is required to successfully run gRPC on macOS. +// For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682 + +// Add services to the container. +builder.Services.AddGrpc(); + +var app = builder.Build(); - // Additional configuration is required to successfully run gRPC on macOS. - // For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682 - public static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - }); - } +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseDeveloperExceptionPage(); } + +app.MapGrpcService(); +app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909"); + +app.Run(); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/Startup.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/Startup.cs deleted file mode 100644 index 5d3cc781c178..000000000000 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/Startup.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using GrpcService_CSharp.Services; - -namespace GrpcService_CSharp -{ - public class Startup - { - // This method gets called by the runtime. Use this method to add services to the container. - // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 - public void ConfigureServices(IServiceCollection services) - { - services.AddGrpc(); - } - - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - - app.UseRouting(); - - app.UseEndpoints(endpoints => - { - endpoints.MapGrpcService(); - - endpoints.MapGet("/", async context => - { - await context.Response.WriteAsync("Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909"); - }); - }); - } - } -} From 09338ccdbdc757ad8ccbaf22400809d08b1de317 Mon Sep 17 00:00:00 2001 From: DamianEdwards Date: Fri, 2 Jul 2021 14:00:58 -0700 Subject: [PATCH 05/12] Updated WebApi template: - uses minimal hosting APIs - uses top-level statements --- .../content/WebApi-CSharp/Program.cs | 91 ++++++++++++--- .../content/WebApi-CSharp/Startup.cs | 106 ------------------ 2 files changed, 73 insertions(+), 124 deletions(-) delete mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Startup.cs diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Program.cs index 549d0b8bb8a1..d00a5033eefb 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Program.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Program.cs @@ -1,26 +1,81 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; +#if (OrganizationalAuth || IndividualB2CAuth) +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.Identity.Web; +#endif using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; +#if (GenerateGraph) +using Microsoft.Graph; +#endif +#if (EnableOpenAPI) +using Microsoft.OpenApi.Models; +#endif -namespace Company.WebApplication1 +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. +#if (OrganizationalAuth) +builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) +#if (GenerateApiOrGraph) + .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd")) + .EnableTokenAcquisitionToCallDownstreamApi() +#if (GenerateApi) + .AddDownstreamWebApi("DownstreamApi", builder.Configuration.GetSection("DownstreamApi")) +#endif +#if (GenerateGraph) + .AddMicrosoftGraph(builder.Configuration.GetSection("DownstreamApi")) +#endif + .AddInMemoryTokenCaches(); +#else + .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd")); +#endif +#elif (IndividualB2CAuth) +builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) +#if (GenerateApi) + .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAdB2C")) + .EnableTokenAcquisitionToCallDownstreamApi() + .AddDownstreamWebApi("DownstreamApi", builder.Configuration.GetSection("DownstreamApi")) + .AddInMemoryTokenCaches(); +#else + .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAdB2C")); +#endif +#endif + +builder.Services.AddControllers(); +#if (EnableOpenAPI) +builder.Services.AddSwaggerGen(c => +{ + c.SwaggerDoc("v1", new() { Title = "Company.WebApplication1", Version = "v1" }); +}); +#endif + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (builder.Environment.IsDevelopment()) { - public class Program - { - public static void Main(string[] args) - { - CreateHostBuilder(args).Build().Run(); - } - - public static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - }); - } + app.UseDeveloperExceptionPage(); + #if (EnableOpenAPI) + app.UseSwagger(); + app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Company.WebApplication1 v1")); + #endif } +#if (RequiresHttps) + +app.UseHttpsRedirection(); +#endif + +#if (OrganizationalAuth || IndividualAuth) +app.UseAuthentication(); +#endif +app.UseAuthorization(); + +app.MapControllers(); + +app.Run(); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Startup.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Startup.cs deleted file mode 100644 index e1fedd249a8d..000000000000 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Startup.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -#if (RequiresHttps) -using Microsoft.AspNetCore.HttpsPolicy; -#endif -using Microsoft.AspNetCore.Mvc; -#if (OrganizationalAuth || IndividualB2CAuth) -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.Identity.Web; -#endif -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; -#if (GenerateGraph) -using Microsoft.Graph; -#endif -#if (EnableOpenAPI) -using Microsoft.OpenApi.Models; -#endif - -namespace Company.WebApplication1 -{ - public class Startup - { - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } - - public IConfiguration Configuration { get; } - - // This method gets called by the runtime. Use this method to add services to the container. - public void ConfigureServices(IServiceCollection services) - { -#if (OrganizationalAuth) - services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) -#if (GenerateApiOrGraph) - .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd")) - .EnableTokenAcquisitionToCallDownstreamApi() -#if (GenerateApi) - .AddDownstreamWebApi("DownstreamApi", Configuration.GetSection("DownstreamApi")) -#endif -#if (GenerateGraph) - .AddMicrosoftGraph(Configuration.GetSection("DownstreamApi")) -#endif - .AddInMemoryTokenCaches(); -#else - .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd")); -#endif -#elif (IndividualB2CAuth) - services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) -#if (GenerateApi) - .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAdB2C")) - .EnableTokenAcquisitionToCallDownstreamApi() - .AddDownstreamWebApi("DownstreamApi", Configuration.GetSection("DownstreamApi")) - .AddInMemoryTokenCaches(); -#else - .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAdB2C")); -#endif -#endif - - services.AddControllers(); -#if (EnableOpenAPI) - services.AddSwaggerGen(c => - { - c.SwaggerDoc("v1", new OpenApiInfo { Title = "Company.WebApplication1", Version = "v1" }); - }); -#endif - } - - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - #if (EnableOpenAPI) - app.UseSwagger(); - app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Company.WebApplication1 v1")); - #endif - } -#if (RequiresHttps) - - app.UseHttpsRedirection(); -#endif - - app.UseRouting(); - -#if (OrganizationalAuth || IndividualAuth) - app.UseAuthentication(); -#endif - app.UseAuthorization(); - - app.UseEndpoints(endpoints => - { - endpoints.MapControllers(); - }); - } - } -} From 095b114de098bdbf9666895e760148d075c09fe3 Mon Sep 17 00:00:00 2001 From: DamianEdwards Date: Fri, 2 Jul 2021 14:15:56 -0700 Subject: [PATCH 06/12] Updated BlazorServer project template: - uses minimal hosting APIs - uses top-level statements --- .../content/BlazorServerWeb-CSharp/App.razor | 4 +- .../content/BlazorServerWeb-CSharp/Program.cs | 161 ++++++++++++++-- .../content/BlazorServerWeb-CSharp/Startup.cs | 175 ------------------ 3 files changed, 147 insertions(+), 193 deletions(-) delete mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Startup.cs diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/App.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/App.razor index 53c9369c94cb..8bb35f5770ed 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/App.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/App.razor @@ -1,5 +1,5 @@ @*#if (NoAuth) - + @@ -12,7 +12,7 @@ #else - + diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Program.cs index 0132c0538aa3..da5b22da791c 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Program.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Program.cs @@ -2,25 +2,154 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +#if (OrganizationalAuth || IndividualB2CAuth) +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authentication.OpenIdConnect; +using Microsoft.Identity.Web; +using Microsoft.Identity.Web.UI; +#endif +#if (OrganizationalAuth) +#if (MultiOrgAuth) +using Microsoft.AspNetCore.Authentication.OpenIdConnect; +#endif +using Microsoft.AspNetCore.Authorization; +#endif +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Components; +#if (IndividualLocalAuth) +using Microsoft.AspNetCore.Components.Authorization; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Identity.UI; +#endif using Microsoft.AspNetCore.Hosting; +#if (OrganizationalAuth) +using Microsoft.AspNetCore.Mvc.Authorization; +#endif +#if (IndividualLocalAuth) +using Microsoft.EntityFrameworkCore; +#endif using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; +#if (GenerateGraph) +using Microsoft.Graph; +#endif +#if(MultiOrgAuth) +using Microsoft.IdentityModel.Tokens; +#endif +#if (IndividualLocalAuth) +using BlazorServerWeb_CSharp.Areas.Identity; +#endif +using BlazorServerWeb_CSharp.Data; -namespace BlazorServerWeb_CSharp +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. +#if (IndividualLocalAuth) +builder.Services.AddDbContext(options => +#if (UseLocalDB) + options.UseSqlServer( + builder.Configuration.GetConnectionString("DefaultConnection"))); +#else + options.UseSqlite( + builder.Configuration.GetConnectionString("DefaultConnection"))); +#endif +builder.Services.AddDatabaseDeveloperPageExceptionFilter(); +builder.Services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true) + .AddEntityFrameworkStores(); +#elif (OrganizationalAuth) +#if (GenerateApiOrGraph) +var initialScopes = builder.Configuration.GetValue("DownstreamApi:Scopes")?.Split(' '); + +#endif +builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) +#if (GenerateApiOrGraph) + .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd")) + .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) +#if (GenerateApi) + .AddDownstreamWebApi("DownstreamApi", builder.Configuration.GetSection("DownstreamApi")) +#endif +#if (GenerateGraph) + .AddMicrosoftGraph(builder.Configuration.GetSection("DownstreamApi")) +#endif + .AddInMemoryTokenCaches(); +#else + .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd")); +#endif +#elif (IndividualB2CAuth) +#if (GenerateApi) +var initialScopes = builder.Configuration.GetValue("DownstreamApi:Scopes")?.Split(' '); + +#endif +builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) +#if (GenerateApi) + .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAdB2C")) + .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) + .AddDownstreamWebApi("DownstreamApi", builder.Configuration.GetSection("DownstreamApi")) + .AddInMemoryTokenCaches(); +#else + .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAdB2C")); +#endif +#endif +#if (OrganizationalAuth || IndividualB2CAuth) +builder.Services.AddControllersWithViews() + .AddMicrosoftIdentityUI(); + +builder.Services.AddAuthorization(options => +{ + // By default, all incoming requests will be authorized according to the default policy + options.FallbackPolicy = options.DefaultPolicy; +}); + +#endif +builder.Services.AddRazorPages(); +#if (OrganizationalAuth || IndividualB2CAuth) +builder.Services.AddServerSideBlazor() + .AddMicrosoftIdentityConsentHandler(); +#else +builder.Services.AddServerSideBlazor(); +#endif +#if (IndividualLocalAuth) +builder.Services.AddScoped>(); +#endif +builder.Services.AddSingleton(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseDeveloperExceptionPage(); +#if (IndividualLocalAuth) + app.UseMigrationsEndPoint(); +#endif +} +else { - public class Program - { - public static void Main(string[] args) - { - CreateHostBuilder(args).Build().Run(); - } - - public static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - }); - } + app.UseExceptionHandler("/Error"); +#if (RequiresHttps) + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseHsts(); +} + +app.UseHttpsRedirection(); +#else } + +#endif + +app.UseStaticFiles(); + +#if (OrganizationalAuth || IndividualAuth) +app.UseAuthentication(); +app.UseAuthorization(); + +#endif + +#if (OrganizationalAuth || IndividualAuth) +app.MapControllers(); +#endif +app.MapBlazorHub(); +app.MapFallbackToPage("/_Host"); + +app.Run(); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Startup.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Startup.cs deleted file mode 100644 index c3c6fb832ce7..000000000000 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Startup.cs +++ /dev/null @@ -1,175 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -#if (OrganizationalAuth || IndividualB2CAuth) -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Authentication.OpenIdConnect; -using Microsoft.Identity.Web; -using Microsoft.Identity.Web.UI; -#endif -#if (OrganizationalAuth) -#if (MultiOrgAuth) -using Microsoft.AspNetCore.Authentication.OpenIdConnect; -#endif -using Microsoft.AspNetCore.Authorization; -#endif -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Components; -#if (IndividualLocalAuth) -using Microsoft.AspNetCore.Components.Authorization; -using Microsoft.AspNetCore.Identity; -using Microsoft.AspNetCore.Identity.UI; -#endif -using Microsoft.AspNetCore.Hosting; -#if (RequiresHttps) -using Microsoft.AspNetCore.HttpsPolicy; -#endif -#if (OrganizationalAuth) -using Microsoft.AspNetCore.Mvc.Authorization; -#endif -#if (IndividualLocalAuth) -using Microsoft.EntityFrameworkCore; -#endif -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -#if(MultiOrgAuth) -using Microsoft.IdentityModel.Tokens; -#endif -#if (IndividualLocalAuth) -using BlazorServerWeb_CSharp.Areas.Identity; -#endif -using BlazorServerWeb_CSharp.Data; -#if (GenerateGraph) -using Microsoft.Graph; -#endif - -namespace BlazorServerWeb_CSharp -{ - public class Startup - { - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } - - public IConfiguration Configuration { get; } - - // This method gets called by the runtime. Use this method to add services to the container. - // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 - public void ConfigureServices(IServiceCollection services) - { -#if (IndividualLocalAuth) - services.AddDbContext(options => -#if (UseLocalDB) - options.UseSqlServer( - Configuration.GetConnectionString("DefaultConnection"))); -#else - options.UseSqlite( - Configuration.GetConnectionString("DefaultConnection"))); -#endif - services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true) - .AddEntityFrameworkStores(); -#elif (OrganizationalAuth) -#if (GenerateApiOrGraph) - var initialScopes = Configuration.GetValue("DownstreamApi:Scopes")?.Split(' '); - -#endif - services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) -#if (GenerateApiOrGraph) - .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd")) - .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) -#if (GenerateApi) - .AddDownstreamWebApi("DownstreamApi", Configuration.GetSection("DownstreamApi")) -#endif -#if (GenerateGraph) - .AddMicrosoftGraph(Configuration.GetSection("DownstreamApi")) -#endif - .AddInMemoryTokenCaches(); -#else - .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd")); -#endif -#elif (IndividualB2CAuth) -#if (GenerateApi) - var initialScopes = Configuration.GetValue("DownstreamApi:Scopes")?.Split(' '); - -#endif - services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) -#if (GenerateApi) - .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAdB2C")) - .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) - .AddDownstreamWebApi("DownstreamApi", Configuration.GetSection("DownstreamApi")) - .AddInMemoryTokenCaches(); -#else - .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAdB2C")); -#endif -#endif -#if (OrganizationalAuth || IndividualB2CAuth) - services.AddControllersWithViews() - .AddMicrosoftIdentityUI(); - - services.AddAuthorization(options => - { - // By default, all incoming requests will be authorized according to the default policy - options.FallbackPolicy = options.DefaultPolicy; - }); - -#endif - services.AddRazorPages(); -#if (OrganizationalAuth || IndividualB2CAuth) - services.AddServerSideBlazor() - .AddMicrosoftIdentityConsentHandler(); -#else - services.AddServerSideBlazor(); -#endif -#if (IndividualLocalAuth) - services.AddScoped>(); - services.AddDatabaseDeveloperPageExceptionFilter(); -#endif - services.AddSingleton(); - } - - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); -#if (IndividualLocalAuth) - app.UseMigrationsEndPoint(); -#endif - } - else - { - app.UseExceptionHandler("/Error"); -#if (RequiresHttps) - // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. - app.UseHsts(); - } - - app.UseHttpsRedirection(); -#else - } - -#endif - app.UseStaticFiles(); - - app.UseRouting(); - -#if (OrganizationalAuth || IndividualAuth) - app.UseAuthentication(); - app.UseAuthorization(); - -#endif - app.UseEndpoints(endpoints => - { -#if (OrganizationalAuth || IndividualAuth) - endpoints.MapControllers(); -#endif - endpoints.MapBlazorHub(); - endpoints.MapFallbackToPage("/_Host"); - }); - } - } -} From 02f975528f500e1367546a43d6cfe9410ded57e0 Mon Sep 17 00:00:00 2001 From: DamianEdwards Date: Fri, 2 Jul 2021 15:56:45 -0700 Subject: [PATCH 07/12] Update BlazorWasm template - Uses minimal hosting APIs - Uses top-level statements - Fixed template testing scripts to support BlazorWasm template properly - Fixed nullable issues --- .../Client/App.razor | 6 +- .../Client/Pages/Authentication.razor | 2 +- .../Client/Program.cs | 72 ++++----- .../Server/Program.cs | 138 ++++++++++++++--- .../Server/Startup.cs | 143 ------------------ .../scripts/Run-Angular-Locally.ps1 | 2 +- .../scripts/Run-BlazorWasm-Locally.ps1 | 2 +- .../scripts/Run-React-Locally.ps1 | 2 +- .../scripts/Run-ReactRedux-Locally.ps1 | 2 +- .../scripts/Test-Template.ps1 | 59 ++++++-- 10 files changed, 206 insertions(+), 222 deletions(-) delete mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Startup.cs diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Client/App.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Client/App.razor index 1a014b0dbf74..db4035900ad0 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Client/App.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Client/App.razor @@ -1,5 +1,5 @@ @*#if (NoAuth) - + @@ -12,11 +12,11 @@ #else - + - @if (!context.User.Identity.IsAuthenticated) + @if (context.User.Identity?.IsAuthenticated != true) { } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Client/Pages/Authentication.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Client/Pages/Authentication.razor index e237cea55512..6c74356731ab 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Client/Pages/Authentication.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Client/Pages/Authentication.razor @@ -3,5 +3,5 @@ @code{ - [Parameter] public string Action { get; set; } + [Parameter] public string? Action { get; set; } } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Client/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Client/Program.cs index 8d71e2bf47f9..a756324094d3 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Client/Program.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Client/Program.cs @@ -1,8 +1,8 @@ using System; -using System.Net.Http; using System.Collections.Generic; -using System.Threading.Tasks; +using System.Net.Http; using System.Text; +using System.Threading.Tasks; #if (!NoAuth && Hosted) using Microsoft.AspNetCore.Components.WebAssembly.Authentication; #endif @@ -10,66 +10,58 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; - #if (Hosted) -namespace ComponentsWebAssembly_CSharp.Client +using ComponentsWebAssembly_CSharp.Client; #else -namespace ComponentsWebAssembly_CSharp +using ComponentsWebAssembly_CSharp; #endif -{ - public class Program - { - public static async Task Main(string[] args) - { - var builder = WebAssemblyHostBuilder.CreateDefault(args); - builder.RootComponents.Add("#app"); + +var builder = WebAssemblyHostBuilder.CreateDefault(args); +builder.RootComponents.Add("#app"); #if (!Hosted || NoAuth) - builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); +builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); #else - builder.Services.AddHttpClient("ComponentsWebAssembly_CSharp.ServerAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)) - .AddHttpMessageHandler(); +builder.Services.AddHttpClient("ComponentsWebAssembly_CSharp.ServerAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)) + .AddHttpMessageHandler(); - // Supply HttpClient instances that include access tokens when making requests to the server project - builder.Services.AddScoped(sp => sp.GetRequiredService().CreateClient("ComponentsWebAssembly_CSharp.ServerAPI")); +// Supply HttpClient instances that include access tokens when making requests to the server project +builder.Services.AddScoped(sp => sp.GetRequiredService().CreateClient("ComponentsWebAssembly_CSharp.ServerAPI")); #endif #if(!NoAuth) #endif #if (IndividualLocalAuth) #if (Hosted) - builder.Services.AddApiAuthorization(); +builder.Services.AddApiAuthorization(); #else - builder.Services.AddOidcAuthentication(options => - { - #if(MissingAuthority) - // Configure your authentication provider options here. - // For more information, see https://aka.ms/blazor-standalone-auth - #endif - builder.Configuration.Bind("Local", options.ProviderOptions); - }); +builder.Services.AddOidcAuthentication(options => +{ + #if(MissingAuthority) + // Configure your authentication provider options here. + // For more information, see https://aka.ms/blazor-standalone-auth + #endif + builder.Configuration.Bind("Local", options.ProviderOptions); +}); #endif #endif #if (IndividualB2CAuth) - builder.Services.AddMsalAuthentication(options => - { - builder.Configuration.Bind("AzureAdB2C", options.ProviderOptions.Authentication); +builder.Services.AddMsalAuthentication(options => +{ + builder.Configuration.Bind("AzureAdB2C", options.ProviderOptions.Authentication); #if (Hosted) - options.ProviderOptions.DefaultAccessTokenScopes.Add("https://qualified.domain.name/api.id.uri/api-scope"); + options.ProviderOptions.DefaultAccessTokenScopes.Add("https://qualified.domain.name/api.id.uri/api-scope"); #endif - }); +}); #endif #if(OrganizationalAuth) - builder.Services.AddMsalAuthentication(options => - { - builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication); +builder.Services.AddMsalAuthentication(options => +{ + builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication); #if (Hosted) - options.ProviderOptions.DefaultAccessTokenScopes.Add("api://api.id.uri/api-scope"); + options.ProviderOptions.DefaultAccessTokenScopes.Add("api://api.id.uri/api-scope"); #endif - }); +}); #endif - await builder.Build().RunAsync(); - } - } -} +await builder.Build().RunAsync(); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Program.cs index 0f0c06165788..6e900333898b 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Program.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Program.cs @@ -1,26 +1,124 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; +using System.Linq; +#if (OrganizationalAuth || IndividualB2CAuth || IndividualLocalAuth) +using Microsoft.AspNetCore.Authentication; +#endif +#if (OrganizationalAuth || IndividualB2CAuth) +using Microsoft.AspNetCore.Authentication.JwtBearer; +#endif +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.ResponseCompression; +#if (IndividualLocalAuth) +using Microsoft.EntityFrameworkCore; +#endif using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; +#if (GenerateGraph) +using Microsoft.Graph; +#endif +#if (OrganizationalAuth || IndividualB2CAuth) +using Microsoft.Identity.Web; +#endif +#if (IndividualLocalAuth) +using ComponentsWebAssembly_CSharp.Server.Data; +using ComponentsWebAssembly_CSharp.Server.Models; +#endif -namespace ComponentsWebAssembly_CSharp.Server +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. +#if (IndividualLocalAuth) +builder.Services.AddDbContext(options => +#if (UseLocalDB) + options.UseSqlServer( + builder.Configuration.GetConnectionString("DefaultConnection"))); +#else + options.UseSqlite( + builder.Configuration.GetConnectionString("DefaultConnection"))); +#endif +builder.Services.AddDatabaseDeveloperPageExceptionFilter(); + +builder.Services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true) + .AddEntityFrameworkStores(); + +builder.Services.AddIdentityServer() + .AddApiAuthorization(); + +builder.Services.AddAuthentication() + .AddIdentityServerJwt(); +#endif +#if (OrganizationalAuth) +builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) +#if (GenerateApiOrGraph) + .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd")) + .EnableTokenAcquisitionToCallDownstreamApi() +#if (GenerateApi) + .AddDownstreamWebApi("DownstreamApi", builder.Configuration.GetSection("DownstreamApi")) +#endif +#if (GenerateGraph) + .AddMicrosoftGraph(builder.Configuration.GetSection("DownstreamApi")) +#endif + .AddInMemoryTokenCaches(); +#else + .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd")); +#endif +#elif (IndividualB2CAuth) +builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) +#if (GenerateApi) + .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAdB2C")) + .EnableTokenAcquisitionToCallDownstreamApi() + .AddDownstreamWebApi("DownstreamApi", builder.Configuration.GetSection("DownstreamApi")) + .AddInMemoryTokenCaches(); +#else + .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAdB2C")); +#endif +#endif + +builder.Services.AddControllersWithViews(); +builder.Services.AddRazorPages(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseDeveloperExceptionPage(); +#if (IndividualLocalAuth) + app.UseMigrationsEndPoint(); +#endif + app.UseWebAssemblyDebugging(); +} +else { - public class Program - { - public static void Main(string[] args) - { - CreateHostBuilder(args).Build().Run(); - } - - public static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - }); - } + app.UseExceptionHandler("/Error"); +#if (RequiresHttps) + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseHsts(); } + +app.UseHttpsRedirection(); +#else +} + +#endif + +app.UseBlazorFrameworkFiles(); +app.UseStaticFiles(); + +#if (IndividualLocalAuth) +app.UseIdentityServer(); +#endif +#if (OrganizationalAuth || IndividualAuth) +app.UseAuthentication(); +#endif +#if (!NoAuth) +app.UseAuthorization(); + +#endif + +app.MapRazorPages(); +app.MapControllers(); +app.MapFallbackToFile("index.html"); + +app.Run(); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Startup.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Startup.cs deleted file mode 100644 index 00aef16c8017..000000000000 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Startup.cs +++ /dev/null @@ -1,143 +0,0 @@ -#if (OrganizationalAuth || IndividualB2CAuth || IndividualLocalAuth) -using Microsoft.AspNetCore.Authentication; -#endif -using Microsoft.AspNetCore.Builder; -#if (OrganizationalAuth || IndividualB2CAuth) -using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.Identity.Web; -#endif -#if (RequiresHttps) -using Microsoft.AspNetCore.HttpsPolicy; -#endif -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.ResponseCompression; -#if (IndividualLocalAuth) -using Microsoft.EntityFrameworkCore; -#endif -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using System.Linq; -#if (IndividualLocalAuth) -using ComponentsWebAssembly_CSharp.Server.Data; -using ComponentsWebAssembly_CSharp.Server.Models; -#endif -#if (GenerateGraph) -using Microsoft.Graph; -#endif - -namespace ComponentsWebAssembly_CSharp.Server -{ - public class Startup - { - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } - - public IConfiguration Configuration { get; } - - // This method gets called by the runtime. Use this method to add services to the container. - // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 - public void ConfigureServices(IServiceCollection services) - { -#if (IndividualLocalAuth) - services.AddDbContext(options => -#if (UseLocalDB) - options.UseSqlServer( - Configuration.GetConnectionString("DefaultConnection"))); -#else - options.UseSqlite( - Configuration.GetConnectionString("DefaultConnection"))); -#endif - - services.AddDatabaseDeveloperPageExceptionFilter(); - - services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true) - .AddEntityFrameworkStores(); - - services.AddIdentityServer() - .AddApiAuthorization(); - - services.AddAuthentication() - .AddIdentityServerJwt(); -#endif -#if (OrganizationalAuth) - services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) -#if (GenerateApiOrGraph) - .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd")) - .EnableTokenAcquisitionToCallDownstreamApi() -#if (GenerateApi) - .AddDownstreamWebApi("DownstreamApi", Configuration.GetSection("DownstreamApi")) -#endif -#if (GenerateGraph) - .AddMicrosoftGraph(Configuration.GetSection("DownstreamApi")) -#endif - .AddInMemoryTokenCaches(); -#else - .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd")); -#endif -#elif (IndividualB2CAuth) - services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) -#if (GenerateApi) - .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAdB2C")) - .EnableTokenAcquisitionToCallDownstreamApi() - .AddDownstreamWebApi("DownstreamApi", Configuration.GetSection("DownstreamApi")) - .AddInMemoryTokenCaches(); -#else - .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAdB2C")); -#endif -#endif - - services.AddControllersWithViews(); - services.AddRazorPages(); - } - - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); -#if (IndividualLocalAuth) - app.UseMigrationsEndPoint(); -#endif - app.UseWebAssemblyDebugging(); - } - else - { - app.UseExceptionHandler("/Error"); -#if (RequiresHttps) - // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. - app.UseHsts(); - } - - app.UseHttpsRedirection(); -#else - } - -#endif - app.UseBlazorFrameworkFiles(); - app.UseStaticFiles(); - - app.UseRouting(); - -#if (IndividualLocalAuth) - app.UseIdentityServer(); -#endif -#if (OrganizationalAuth || IndividualAuth) - app.UseAuthentication(); -#endif -#if (!NoAuth) - app.UseAuthorization(); - -#endif - app.UseEndpoints(endpoints => - { - endpoints.MapRazorPages(); - endpoints.MapControllers(); - endpoints.MapFallbackToFile("index.html"); - }); - } - } -} diff --git a/src/ProjectTemplates/scripts/Run-Angular-Locally.ps1 b/src/ProjectTemplates/scripts/Run-Angular-Locally.ps1 index 3724496d4097..95de6568eab1 100644 --- a/src/ProjectTemplates/scripts/Run-Angular-Locally.ps1 +++ b/src/ProjectTemplates/scripts/Run-Angular-Locally.ps1 @@ -9,4 +9,4 @@ $ErrorActionPreference = 'Stop' . $PSScriptRoot\Test-Template.ps1 -Test-Template "angular" "angular" "Microsoft.DotNet.Web.Spa.ProjectTemplates.6.0.6.0.0-dev.nupkg" $true +Test-Template "angular" "angular" "Microsoft.DotNet.Web.Spa.ProjectTemplates.6.0.6.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Run-BlazorWasm-Locally.ps1 b/src/ProjectTemplates/scripts/Run-BlazorWasm-Locally.ps1 index dbb25f7316de..50f70bb1b04d 100644 --- a/src/ProjectTemplates/scripts/Run-BlazorWasm-Locally.ps1 +++ b/src/ProjectTemplates/scripts/Run-BlazorWasm-Locally.ps1 @@ -10,4 +10,4 @@ $ErrorActionPreference = 'Stop' . $PSScriptRoot\Test-Template.ps1 -Test-Template "blazorwasm" "blazorwasm" "Microsoft.AspnetCore.Blazor.Templates.3.1.0-dev.nupkg" $false +Test-Template "blazorwasm" "blazorwasm --hosted --auth Individual" "Microsoft.DotNet.Web.ProjectTemplates.6.0.6.0.0-dev.nupkg" $true diff --git a/src/ProjectTemplates/scripts/Run-React-Locally.ps1 b/src/ProjectTemplates/scripts/Run-React-Locally.ps1 index f69f07a20d24..a4baf0c40568 100644 --- a/src/ProjectTemplates/scripts/Run-React-Locally.ps1 +++ b/src/ProjectTemplates/scripts/Run-React-Locally.ps1 @@ -9,4 +9,4 @@ $ErrorActionPreference = 'Stop' . $PSScriptRoot\Test-Template.ps1 -Test-Template "react" "react" "Microsoft.DotNet.Web.Spa.ProjectTemplates.6.0.6.0.0-dev.nupkg" $true +Test-Template "react" "react" "Microsoft.DotNet.Web.Spa.ProjectTemplates.6.0.6.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Run-ReactRedux-Locally.ps1 b/src/ProjectTemplates/scripts/Run-ReactRedux-Locally.ps1 index 0eda170ab13e..aedd8ec88acb 100644 --- a/src/ProjectTemplates/scripts/Run-ReactRedux-Locally.ps1 +++ b/src/ProjectTemplates/scripts/Run-ReactRedux-Locally.ps1 @@ -9,4 +9,4 @@ $ErrorActionPreference = 'Stop' . $PSScriptRoot\Test-Template.ps1 -Test-Template "reactredux" "reactredux" "Microsoft.DotNet.Web.Spa.ProjectTemplates.6.0.6.0.0-dev.nupkg" $true +Test-Template "reactredux" "reactredux" "Microsoft.DotNet.Web.Spa.ProjectTemplates.6.0.6.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Test-Template.ps1 b/src/ProjectTemplates/scripts/Test-Template.ps1 index 8cc65f90e2c8..349174ad3d06 100644 --- a/src/ProjectTemplates/scripts/Test-Template.ps1 +++ b/src/ProjectTemplates/scripts/Test-Template.ps1 @@ -4,7 +4,13 @@ Set-StrictMode -Version 2 $ErrorActionPreference = 'Stop' -function Test-Template($templateName, $templateArgs, $templateNupkg, $isSPA) { +function Test-Template($templateName, $templateArgs, $templateNupkg, $isBlazorWasm) { + if ($isBlazorWasm -and $templateArgs.Contains("hosted")) { + $isBlazorWasmHosted = $true + } + else { + $isBlazorWasmHosted = $false + } $tmpDir = "$PSScriptRoot/$templateName" Remove-Item -Path $tmpDir -Recurse -ErrorAction Ignore Push-Location .. @@ -29,22 +35,53 @@ function Test-Template($templateName, $templateArgs, $templateNupkg, $isSPA) { $extension = "csproj" } - $proj = "$tmpDir/$templateName.$extension" - $projContent = Get-Content -Path $proj -Raw - $projContent = $projContent -replace ('', " - - - - true - ") - $projContent | Set-Content $proj + if ($isBlazorWasmHosted) { + $proj = @("$tmpDir/Server/$templateName.Server.$extension", + "$tmpDir/Client/$templateName.Client.$extension", + "$tmpDir/Shared/$templateName.Shared.$extension") + } + else { + $proj = @("$tmpDir/$templateName.$extension") + } + + foreach ($projPath in $proj) { + $projContent = Get-Content -Path $projPath -Raw + if ($isBlazorWasmHosted) { + $importPath = "$PSScriptRoot/../test/bin/Debug/net6.0/TestTemplates" + } + else { + $importPath = "$PSScriptRoot/../test/bin/Debug/net6.0/TestTemplates" + } + $projContent = $projContent -replace ('(?:)', (' + + + + true + ')) + $projContent | Set-Content $projPath + } + + if ($isBlazorWasmHosted) { + Push-Location Server + } dotnet.exe ef migrations add mvc dotnet.exe publish --configuration Release Set-Location .\bin\Release\net6.0\publish - Invoke-Expression "./$templateName.exe" + if ($isBlazorWasm -eq $false) { + Invoke-Expression "./$templateName.exe" + } + if ($isBlazorWasmHosted) { + # Identity Server only runs in Development by default due to key signing requirements + $env:ASPNETCORE_ENVIRONMENT="Development" + Invoke-Expression "./$templateName.Server.exe" + $env:ASPNETCORE_ENVIRONMENT="" + } } finally { Pop-Location + if ($isBlazorWasmHosted) { + Pop-Location + } } } From 36486edb54d2ec87b0bf7785a3ec0690062faad0 Mon Sep 17 00:00:00 2001 From: DamianEdwards Date: Fri, 2 Jul 2021 17:41:51 -0700 Subject: [PATCH 08/12] Alias Microsoft.Graph namespace to fix type conflict --- .../Web.ProjectTemplates/content/StarterWeb-CSharp/Program.cs | 2 +- .../Web.ProjectTemplates/content/WebApi-CSharp/Program.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Program.cs index fa22b07c2215..3324fd6ba774 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Program.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Program.cs @@ -28,7 +28,7 @@ using Microsoft.IdentityModel.Tokens; #endif #if (GenerateGraph) -using Microsoft.Graph; +using Graph = Microsoft.Graph; #endif #if (IndividualLocalAuth) using Company.WebApplication1.Data; diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Program.cs index d00a5033eefb..21f4f7dfdd27 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Program.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/Program.cs @@ -11,7 +11,7 @@ using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; #if (GenerateGraph) -using Microsoft.Graph; +using Graph = Microsoft.Graph; #endif #if (EnableOpenAPI) using Microsoft.OpenApi.Models; From 7d0df6ae2d36376f7d214ebdc5ecf6fbcd4d0d82 Mon Sep 17 00:00:00 2001 From: DamianEdwards Date: Tue, 6 Jul 2021 11:01:55 -0700 Subject: [PATCH 09/12] Address feedback --- .../content/RazorPagesWeb-CSharp/Program.cs | 1 - .../Web.ProjectTemplates/content/StarterWeb-CSharp/Program.cs | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Program.cs index 276988c393ac..62bd44082fdc 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Program.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Program.cs @@ -92,7 +92,6 @@ options.FallbackPolicy = options.DefaultPolicy; }); builder.Services.AddRazorPages() - .AddMvcOptions(options => {}) .AddMicrosoftIdentityUI(); #elif (IndividualB2CAuth) builder.Services.AddRazorPages() diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Program.cs index 3324fd6ba774..530f68552356 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Program.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Program.cs @@ -52,7 +52,7 @@ .AddEntityFrameworkStores(); #elif (OrganizationalAuth) #if (GenerateApiOrGraph) -var initialScopes = builder.Configuration.GetValue("DownstreamApi:Scopes")?.Split(' '); +var initialScopes = builder.Configuration["DownstreamApi:Scopes"]?.Split(' '); #endif builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) @@ -71,7 +71,7 @@ #endif #elif (IndividualB2CAuth) #if (GenerateApi) -var initialScopes = builder.Configuration.GetValue("DownstreamApi:Scopes")?.Split(' '); +var initialScopes = builder.Configuration["DownstreamApi:Scopes"]?.Split(' '); #endif builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) From 18964b01ae5dd4116603d427b1fab13abc9979a7 Mon Sep 17 00:00:00 2001 From: DamianEdwards Date: Tue, 6 Jul 2021 11:37:11 -0700 Subject: [PATCH 10/12] Remove LangVersion=preview --- .../Web.ProjectTemplates/EmptyWeb-CSharp.csproj.in | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/EmptyWeb-CSharp.csproj.in b/src/ProjectTemplates/Web.ProjectTemplates/EmptyWeb-CSharp.csproj.in index d6194302d3ea..2fe8beb7c7a5 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/EmptyWeb-CSharp.csproj.in +++ b/src/ProjectTemplates/Web.ProjectTemplates/EmptyWeb-CSharp.csproj.in @@ -5,7 +5,6 @@ enable True Company.WebApplication1 - preview From be3fefd4968082e24290cf520f03d0a96adbaede Mon Sep 17 00:00:00 2001 From: DamianEdwards Date: Tue, 6 Jul 2021 11:50:36 -0700 Subject: [PATCH 11/12] Feedback --- .../content/BlazorServerWeb-CSharp/Program.cs | 4 ++-- .../content/RazorPagesWeb-CSharp/Program.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Program.cs index da5b22da791c..2bc91a83fc32 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Program.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Program.cs @@ -59,7 +59,7 @@ .AddEntityFrameworkStores(); #elif (OrganizationalAuth) #if (GenerateApiOrGraph) -var initialScopes = builder.Configuration.GetValue("DownstreamApi:Scopes")?.Split(' '); +var initialScopes = builder.Configuration["DownstreamApi:Scopes"]?.Split(' '); #endif builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) @@ -78,7 +78,7 @@ #endif #elif (IndividualB2CAuth) #if (GenerateApi) -var initialScopes = builder.Configuration.GetValue("DownstreamApi:Scopes")?.Split(' '); +var initialScopes = builder.Configuration["DownstreamApi:Scopes"]?.Split(' '); #endif builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Program.cs index 62bd44082fdc..419f74cd794c 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Program.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Program.cs @@ -52,7 +52,7 @@ .AddEntityFrameworkStores(); #elif (OrganizationalAuth) #if (GenerateApiOrGraph) -var initialScopes = builder.Configuration.GetValue("DownstreamApi:Scopes")?.Split(' '); +var initialScopes = builder.Configuration["DownstreamApi:Scopes"]?.Split(' '); #endif builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) @@ -71,7 +71,7 @@ #endif #elif (IndividualB2CAuth) #if (GenerateApi) -var initialScopes = builder.Configuration.GetValue("DownstreamApi:Scopes")?.Split(' '); +var initialScopes = builder.Configuration["DownstreamApi:Scopes"]?.Split(' '); #endif builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) From 5a458ba3b765b83acbfc1ca02f2fd14a2d92d771 Mon Sep 17 00:00:00 2001 From: DamianEdwards Date: Tue, 6 Jul 2021 16:09:37 -0700 Subject: [PATCH 12/12] Address feedback - put connection string in its own variable - add explicit call to UseRouting() to avoid issue with middleware that re-runs the pipeline with a different path (e.g. UseExceptionHandler) --- .../content/BlazorServerWeb-CSharp/Program.cs | 9 +++++---- .../ComponentsWebAssembly-CSharp/Server/Program.cs | 9 +++++---- .../content/RazorPagesWeb-CSharp/Program.cs | 9 +++++---- .../content/StarterWeb-CSharp/Program.cs | 9 +++++---- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Program.cs index 2bc91a83fc32..7560314201a3 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Program.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/Program.cs @@ -46,13 +46,12 @@ // Add services to the container. #if (IndividualLocalAuth) +var connectionString = builder.Configuration.GetConnectionString("DefaultConnection"); builder.Services.AddDbContext(options => #if (UseLocalDB) - options.UseSqlServer( - builder.Configuration.GetConnectionString("DefaultConnection"))); + options.UseSqlServer(connectionString)); #else - options.UseSqlite( - builder.Configuration.GetConnectionString("DefaultConnection"))); + options.UseSqlite(connectionString)); #endif builder.Services.AddDatabaseDeveloperPageExceptionFilter(); builder.Services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true) @@ -140,6 +139,8 @@ app.UseStaticFiles(); +app.UseRouting(); + #if (OrganizationalAuth || IndividualAuth) app.UseAuthentication(); app.UseAuthorization(); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Program.cs index 6e900333898b..0c98ca375207 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Program.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Program.cs @@ -29,13 +29,12 @@ // Add services to the container. #if (IndividualLocalAuth) +var connectionString = builder.Configuration.GetConnectionString("DefaultConnection"); builder.Services.AddDbContext(options => #if (UseLocalDB) - options.UseSqlServer( - builder.Configuration.GetConnectionString("DefaultConnection"))); + options.UseSqlServer(connectionString)); #else - options.UseSqlite( - builder.Configuration.GetConnectionString("DefaultConnection"))); + options.UseSqlite(connectionString)); #endif builder.Services.AddDatabaseDeveloperPageExceptionFilter(); @@ -106,6 +105,8 @@ app.UseBlazorFrameworkFiles(); app.UseStaticFiles(); +app.UseRouting(); + #if (IndividualLocalAuth) app.UseIdentityServer(); #endif diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Program.cs index 419f74cd794c..f4753edc53bc 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Program.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Program.cs @@ -38,13 +38,12 @@ // Add services to the container. #if (IndividualLocalAuth) +var connectionString = builder.Configuration.GetConnectionString("DefaultConnection"); builder.Services.AddDbContext(options => #if (UseLocalDB) - options.UseSqlServer( - builder.Configuration.GetConnectionString("DefaultConnection"))); + options.UseSqlServer(connectionString)); #else - options.UseSqlite( - builder.Configuration.GetConnectionString("DefaultConnection"))); + options.UseSqlite(connectionString)); #endif builder.Services.AddDatabaseDeveloperPageExceptionFilter(); @@ -124,6 +123,8 @@ #endif app.UseStaticFiles(); +app.UseRouting(); + #if (OrganizationalAuth || IndividualAuth) app.UseAuthentication(); #endif diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Program.cs index 530f68552356..bb593301421c 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Program.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Program.cs @@ -38,13 +38,12 @@ // Add services to the container. #if (IndividualLocalAuth) +var connectionString = builder.Configuration.GetConnectionString("DefaultConnection"); builder.Services.AddDbContext(options => #if (UseLocalDB) - options.UseSqlServer( - builder.Configuration.GetConnectionString("DefaultConnection"))); + options.UseSqlServer(connectionString)); #else - options.UseSqlite( - builder.Configuration.GetConnectionString("DefaultConnection"))); + options.UseSqlite(connectionString)); #endif builder.Services.AddDatabaseDeveloperPageExceptionFilter(); @@ -125,6 +124,8 @@ #endif app.UseStaticFiles(); +app.UseRouting(); + #if (OrganizationalAuth || IndividualAuth) app.UseAuthentication(); #endif