diff --git a/.gitignore b/.gitignore index 885d09c2..19c8cad1 100644 --- a/.gitignore +++ b/.gitignore @@ -31,7 +31,7 @@ DataProtection/ /src/Yavsc/Temp-*/ /src/Yavsc/*-Avatars/ /src/Yavsc/bower_components/ -/src/Yavsc/AppData*/ +/src/Yavsc/Data-Dev/ /src/test/testingrepo/ connectionsettings.Development.json appsettings.Development.json @@ -42,3 +42,4 @@ builds/ /test/yavscTests/test-results.html /binaries/Debug/yavscd yavsc-pre + diff --git a/src/Yavsc/Config.cs b/src/Yavsc/Config.cs new file mode 100644 index 00000000..4b4e9ccf --- /dev/null +++ b/src/Yavsc/Config.cs @@ -0,0 +1,52 @@ +using Duende.IdentityServer.Models; + +namespace Yavsc; + +public static class Config +{ + public static IEnumerable IdentityResources => + new IdentityResource[] + { + new IdentityResources.OpenId(), + new IdentityResources.Profile(), + }; + + public static IEnumerable ApiScopes => + new ApiScope[] + { + new ApiScope("scope1"), + new ApiScope("scope2"), + }; + + public static IEnumerable Clients => + new Client[] + { + // m2m client credentials flow client + new Client + { + ClientId = "m2m.client", + ClientName = "Client Credentials Client", + + AllowedGrantTypes = GrantTypes.ClientCredentials, + ClientSecrets = { new Secret("511536EF-F270-4058-80CA-1C89C192F69A".Sha256()) }, + + AllowedScopes = { "scope1" } + }, + + // interactive client using code flow + pkce + new Client + { + ClientId = "interactive", + ClientSecrets = { new Secret("49C1A7E1-0C79-4A89-A3D6-A37998FB86B0".Sha256()) }, + + AllowedGrantTypes = GrantTypes.Code, + + RedirectUris = { "https://localhost:5001/signin-oidc" }, + FrontChannelLogoutUri = "https://localhost:5001/signout-oidc", + PostLogoutRedirectUris = { "https://localhost:5001/signout-callback-oidc" }, + + AllowOfflineAccess = true, + AllowedScopes = { "openid", "profile", "scope2" } + }, + }; +} diff --git a/src/Yavsc/Startup/Startup.cs b/src/Yavsc/Startup/Startup.cs index 30f76f76..75baddf6 100755 --- a/src/Yavsc/Startup/Startup.cs +++ b/src/Yavsc/Startup/Startup.cs @@ -20,6 +20,7 @@ using Microsoft.AspNetCore.Identity; using Yavsc.Interface; using Yavsc.Settings; using Microsoft.AspNetCore.DataProtection; +using Duende.IdentityServer; namespace Yavsc { @@ -93,7 +94,7 @@ namespace Yavsc // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { - + services.AddRazorPages(); IConfigurationSection siteSettings = Configuration.GetSection("Site"); _ = services.Configure(siteSettings); @@ -245,7 +246,7 @@ namespace Yavsc { options.ResourcesPath = "Resources"; }); - var datadi = new DirectoryInfo(Configuration["Keys:Dir"]); + var datadi = new DirectoryInfo(Configuration["Site:DataDir"]); // Add session related services. services.AddSession(); services.AddDataProtection().PersistKeysToFileSystem(datadi); @@ -267,19 +268,37 @@ namespace Yavsc options.AddPolicy("Authenticated", policy => policy.RequireAuthenticatedUser()); }); - services.AddAuthentication("Bearer") - .AddJwtBearer("Bearer", options => - { - options.Authority = siteSettings.GetValue("Authority"); - options.TokenValidationParameters = new TokenValidationParameters - { - ValidateAudience = false - }; - }); + _ = services.AddControllersWithViews() .AddNewtonsoftJson(); + services.AddIdentityServer(options => + { + options.Events.RaiseErrorEvents = true; + options.Events.RaiseInformationEvents = true; + options.Events.RaiseFailureEvents = true; + options.Events.RaiseSuccessEvents = true; + + // see https://docs.duendesoftware.com/identityserver/v6/fundamentals/resources/ + options.EmitStaticAudienceClaim = true; + }) + .AddInMemoryIdentityResources(Config.IdentityResources) + .AddInMemoryApiScopes(Config.ApiScopes) + .AddInMemoryClients(Config.Clients) + .AddAspNetIdentity(); + + services.AddAuthentication() + .AddGoogle(options => + { + options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; + + // register your IdentityServer with Google at https://console.developers.google.com + // enable the Google+ API + // set the redirect URI to https://localhost:5001/signin-google + options.ClientId = "copy client ID from Google here"; + options.ClientSecret = "copy client secret from Google here"; + }); } public static IServiceProvider Services { get; private set; } @@ -383,8 +402,13 @@ Environment.SpecialFolder.LocalApplicationData, Environment.SpecialFolderOption. app.UseSession(); - _ = app.UseStatusCodePages().UseStaticFiles().UseAuthentication(); - _ = app.UseMvcWithDefaultRoute(); + _ = app.UseStatusCodePages(); + + app.UseStaticFiles(); + app.UseRouting(); + app.UseIdentityServer(); + app.UseAuthorization(); + app.UseMvcWithDefaultRoute(); } diff --git a/src/Yavsc/Yavsc.csproj b/src/Yavsc/Yavsc.csproj index ea84ae7f..087b111a 100644 --- a/src/Yavsc/Yavsc.csproj +++ b/src/Yavsc/Yavsc.csproj @@ -9,7 +9,9 @@ - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/src/Yavsc/appsettings.json b/src/Yavsc/appsettings.json index f62b0943..f9192259 100644 --- a/src/Yavsc/appsettings.json +++ b/src/Yavsc/appsettings.json @@ -22,11 +22,12 @@ "Name": "[a name for a site admin]", "EMail": "[an e-mail for a site admin]" }, - "Avatars": "Avatars", + "Avatars": "avatars", "Quota": 200000000, - "Bills": "Bills", - "Blog": "Blog", - "TempDir": "Temp" + "Bills": "bills", + "Blog": "blog", + "TempDir": "temp", + "DataDir": "data" }, "Smtp": { "Host": "[YOURSMTPHOST]",