diff --git a/MyApp/Configure.AppHost.cs b/MyApp/Configure.AppHost.cs index 545f561..2259806 100644 --- a/MyApp/Configure.AppHost.cs +++ b/MyApp/Configure.AppHost.cs @@ -2,138 +2,24 @@ using MyApp.Data; using MyApp.Models; using MyApp.Services; -using Microsoft.AspNetCore.HttpOverrides; -using Microsoft.AspNetCore.Identity; -using Microsoft.AspNetCore.Server.IISIntegration; -using Microsoft.EntityFrameworkCore; using MyApp.ServiceInterface; using ServiceStack; using ServiceStack.Auth; using ServiceStack.Configuration; +using Microsoft.EntityFrameworkCore; +using Microsoft.AspNetCore.Identity; [assembly: HostingStartup(typeof(MyApp.AppHost))] namespace MyApp; -/// -/// To create Identity SQL Server database, change "ConnectionStrings" in appsettings.json -/// $ dotnet ef migrations add CreateMyAppIdentitySchema -/// $ dotnet ef database update -/// public class AppHost : AppHostBase, IHostingStartup { public void Configure(IWebHostBuilder builder) => builder .ConfigureServices((context,services) => { - var config = context.Configuration; -#if DEBUG - services.AddMvc(options => options.EnableEndpointRouting = false).AddRazorRuntimeCompilation(); -#else - services.AddMvc(options => options.EnableEndpointRouting = false); -#endif - - services.Configure(options => - { - // This lambda determines whether user consent for non-essential cookies is needed for a given request. - options.CheckConsentNeeded = context => true; - options.MinimumSameSitePolicy = SameSiteMode.None; - }); - - services.AddDbContext(options => - options.UseSqlServer(config.GetConnectionString("DefaultConnection"))); - - services.AddIdentity(options => { - options.User.AllowedUserNameCharacters = null; - }) - .AddEntityFrameworkStores() - .AddDefaultTokenProviders(); - - services.AddAuthentication(IISDefaults.AuthenticationScheme) - .AddTwitter(options => { /* Create Twitter App at: https://dev.twitter.com/apps */ - options.ConsumerKey = config["oauth.twitter.ConsumerKey"]; - options.ConsumerSecret = config["oauth.twitter.ConsumerSecret"]; - options.SaveTokens = true; - options.RetrieveUserDetails = true; - }) - .AddFacebook(options => { /* Create App https://developers.facebook.com/apps */ - options.AppId = config["oauth.facebook.AppId"]; - options.AppSecret = config["oauth.facebook.AppSecret"]; - options.SaveTokens = true; - options.Scope.Clear(); - config.GetSection("oauth.facebook.Permissions").GetChildren() - .Each(x => options.Scope.Add(x.Value)); - }) - .AddGoogle(options => { /* Create App https://console.developers.google.com/apis/credentials */ - options.ClientId = config["oauth.google.ConsumerKey"]; - options.ClientSecret = config["oauth.google.ConsumerSecret"]; - options.SaveTokens = true; - }) - .AddMicrosoftAccount(options => { /* Create App https://apps.dev.microsoft.com */ - options.ClientId = config["oauth.microsoftgraph.AppId"]; - options.ClientSecret = config["oauth.microsoftgraph.AppSecret"]; - options.SaveTokens = true; - }); - - services.Configure(options => { - //https://github.com/aspnet/IISIntegration/issues/140#issuecomment-215135928 - options.ForwardedHeaders = ForwardedHeaders.XForwardedProto; - }); - - services.Configure(options => - { - options.Password.RequireDigit = true; - options.Password.RequiredLength = 8; - options.Password.RequireNonAlphanumeric = false; - options.Password.RequireUppercase = true; - options.Password.RequireLowercase = false; - options.Password.RequiredUniqueChars = 6; - - // Lockout settings - options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30); - options.Lockout.MaxFailedAccessAttempts = 10; - options.Lockout.AllowedForNewUsers = true; - - // User settings - options.User.RequireUniqueEmail = true; + // Configure ASP.NET Core IOC Dependencies }); - services.ConfigureApplicationCookie(options => - { - // Cookie settings - options.Cookie.HttpOnly = true; - options.ExpireTimeSpan = TimeSpan.FromDays(150); - // If the LoginPath isn't set, ASP.NET Core defaults - // the path to /Account/Login. - options.LoginPath = "/Account/Login"; - // If the AccessDeniedPath isn't set, ASP.NET Core defaults - // the path to /Account/AccessDenied. - options.AccessDeniedPath = "/Account/AccessDenied"; - options.SlidingExpiration = true; - }); - - // Add application services. - services.AddTransient(); - - // Populate ApplicationUser with Auth Info - services.AddTransient(c => - new ExternalLoginAuthInfoProvider(config)); - }) - .Configure(app => { - app.UseStaticFiles(); - app.UseCookiePolicy(); - app.UseAuthentication(); - - app.UseServiceStack(new AppHost()); - - app.UseMvc(routes => - { - routes.MapRoute( - name: "default", - template: "{controller=Home}/{action=Index}/{id?}"); - }); - - AddSeedUsers(app).Wait(); - }); - public AppHost() : base("MyApp", typeof(MyServices).Assembly) { } // Configure your AppHost with the necessary configuration and dependencies your App needs @@ -170,6 +56,9 @@ public override void Configure(Container container) } }, })); + + + AddSeedUsers(base.App).Wait(); } private async Task AddSeedUsers(IApplicationBuilder app) diff --git a/MyApp/Models/ApplicationUser.cs b/MyApp/Models/ApplicationUser.cs index c0c5959..b2648d5 100644 --- a/MyApp/Models/ApplicationUser.cs +++ b/MyApp/Models/ApplicationUser.cs @@ -1,4 +1,6 @@ -using System; +#nullable enable + +using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; diff --git a/MyApp/MyApp.csproj b/MyApp/MyApp.csproj index 3a5bdee..b3724ab 100644 --- a/MyApp/MyApp.csproj +++ b/MyApp/MyApp.csproj @@ -2,10 +2,12 @@ net6.0 - enable enable InProcess + + + diff --git a/MyApp/Program.cs b/MyApp/Program.cs index b119e6b..95309d7 100644 --- a/MyApp/Program.cs +++ b/MyApp/Program.cs @@ -1,4 +1,110 @@ -var builder = WebApplication.CreateBuilder(args); +using Microsoft.AspNetCore.HttpOverrides; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Server.IISIntegration; +using Microsoft.EntityFrameworkCore; +using ServiceStack; +using MyApp.Data; +using MyApp.Models; +using MyApp.Services; + +var builder = WebApplication.CreateBuilder(args); + +var config = builder.Configuration; +var services = builder.Services; +#if DEBUG + services.AddMvc(options => options.EnableEndpointRouting = false).AddRazorRuntimeCompilation(); +#else + services.AddMvc(options => options.EnableEndpointRouting = false); +#endif + +services.Configure(options => +{ + // This lambda determines whether user consent for non-essential cookies is needed for a given request. + options.CheckConsentNeeded = context => true; + options.MinimumSameSitePolicy = SameSiteMode.None; +}); + +// To create Identity SQL Server database, change "ConnectionStrings" in appsettings.json +// $ dotnet ef migrations add CreateMyAppIdentitySchema +// $ dotnet ef database update +services.AddDbContext(options => + options.UseSqlServer(config.GetConnectionString("DefaultConnection"))); + +services.AddIdentity(options => { + options.User.AllowedUserNameCharacters = null; + }) + .AddEntityFrameworkStores() + .AddDefaultTokenProviders(); + +services.AddAuthentication(IISDefaults.AuthenticationScheme) + .AddTwitter(options => { /* Create Twitter App at: https://dev.twitter.com/apps */ + options.ConsumerKey = config["oauth.twitter.ConsumerKey"]; + options.ConsumerSecret = config["oauth.twitter.ConsumerSecret"]; + options.SaveTokens = true; + options.RetrieveUserDetails = true; + }) + .AddFacebook(options => { /* Create App https://developers.facebook.com/apps */ + options.AppId = config["oauth.facebook.AppId"]; + options.AppSecret = config["oauth.facebook.AppSecret"]; + options.SaveTokens = true; + options.Scope.Clear(); + config.GetSection("oauth.facebook.Permissions").GetChildren() + .Each(x => options.Scope.Add(x.Value)); + }) + .AddGoogle(options => { /* Create App https://console.developers.google.com/apis/credentials */ + options.ClientId = config["oauth.google.ConsumerKey"]; + options.ClientSecret = config["oauth.google.ConsumerSecret"]; + options.SaveTokens = true; + }) + .AddMicrosoftAccount(options => { /* Create App https://apps.dev.microsoft.com */ + options.ClientId = config["oauth.microsoftgraph.AppId"]; + options.ClientSecret = config["oauth.microsoftgraph.AppSecret"]; + options.SaveTokens = true; + }); + +services.Configure(options => { + //https://github.com/aspnet/IISIntegration/issues/140#issuecomment-215135928 + options.ForwardedHeaders = ForwardedHeaders.XForwardedProto; +}); + +services.Configure(options => +{ + options.Password.RequireDigit = true; + options.Password.RequiredLength = 8; + options.Password.RequireNonAlphanumeric = false; + options.Password.RequireUppercase = true; + options.Password.RequireLowercase = false; + options.Password.RequiredUniqueChars = 6; + + // Lockout settings + options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30); + options.Lockout.MaxFailedAccessAttempts = 10; + options.Lockout.AllowedForNewUsers = true; + + // User settings + options.User.RequireUniqueEmail = true; +}); + +services.ConfigureApplicationCookie(options => +{ + // Cookie settings + options.Cookie.HttpOnly = true; + options.ExpireTimeSpan = TimeSpan.FromDays(150); + // If the LoginPath isn't set, ASP.NET Core defaults + // the path to /Account/Login. + options.LoginPath = "/Account/Login"; + // If the AccessDeniedPath isn't set, ASP.NET Core defaults + // the path to /Account/AccessDenied. + options.AccessDeniedPath = "/Account/AccessDenied"; + options.SlidingExpiration = true; +}); + +// Add application services. +services.AddTransient(); + +// Populate ApplicationUser with Auth Info +services.AddTransient(c => + new ExternalLoginAuthInfoProvider(config)); var app = builder.Build(); @@ -14,5 +120,17 @@ { app.UseDeveloperExceptionPage(); } +app.UseStaticFiles(); +app.UseCookiePolicy(); +app.UseAuthentication(); + +app.UseServiceStack(new AppHost()); + +app.UseMvc(routes => +{ + routes.MapRoute( + name: "default", + template: "{controller=Home}/{action=Index}/{id?}"); +}); app.Run();