Browse Source

Update the ASP.NET Core samples to target .NET Framework 4.8

pull/1980/head
Kévin Chalet 2 years ago
parent
commit
e896a0f8d4
  1. 3
      Directory.Build.targets
  2. 6
      Directory.Packages.props
  3. 7
      sandbox/OpenIddict.Sandbox.AspNetCore.Client/Controllers/AuthenticationController.cs
  4. 2
      sandbox/OpenIddict.Sandbox.AspNetCore.Client/Controllers/HomeController.cs
  5. 12
      sandbox/OpenIddict.Sandbox.AspNetCore.Client/OpenIddict.Sandbox.AspNetCore.Client.csproj
  6. 13
      sandbox/OpenIddict.Sandbox.AspNetCore.Client/Program.cs
  7. 22
      sandbox/OpenIddict.Sandbox.AspNetCore.Client/Startup.cs
  8. 2
      sandbox/OpenIddict.Sandbox.AspNetCore.Client/Views/Home/Index.cshtml
  9. 22
      sandbox/OpenIddict.Sandbox.AspNetCore.Client/Worker.cs
  10. 7
      sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/AuthenticationController.cs
  11. 2
      sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/AuthorizationController.cs
  12. 25
      sandbox/OpenIddict.Sandbox.AspNetCore.Server/OpenIddict.Sandbox.AspNetCore.Server.csproj
  13. 13
      sandbox/OpenIddict.Sandbox.AspNetCore.Server/Program.cs
  14. 12
      sandbox/OpenIddict.Sandbox.AspNetCore.Server/Startup.cs
  15. 35
      sandbox/OpenIddict.Sandbox.AspNetCore.Server/Worker.cs

3
Directory.Build.targets

@ -70,6 +70,8 @@
<PropertyGroup
Condition=" ('$(TargetFrameworkIdentifier)' == '.NETCoreApp' And $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '3.0'))) ">
<DefineConstants>$(DefineConstants);SUPPORTS_AUTHORIZATION_MIDDLEWARE</DefineConstants>
<DefineConstants>$(DefineConstants);SUPPORTS_ENDPOINT_ROUTING</DefineConstants>
<DefineConstants>$(DefineConstants);SUPPORTS_HOST_APPLICATION_LIFETIME</DefineConstants>
<DefineConstants>$(DefineConstants);SUPPORTS_HOST_ENVIRONMENT</DefineConstants>
<DefineConstants>$(DefineConstants);SUPPORTS_HTTP_CLIENT_DEFAULT_REQUEST_VERSION</DefineConstants>
@ -109,6 +111,7 @@
Condition=" ('$(TargetFrameworkIdentifier)' == '.NETCoreApp' And $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '7.0'))) ">
<DefineConstants>$(DefineConstants);SUPPORTS_AUTHENTICATION_HANDLER_SELECTION_FALLBACK</DefineConstants>
<DefineConstants>$(DefineConstants);SUPPORTS_BULK_DBSET_OPERATIONS</DefineConstants>
<DefineConstants>$(DefineConstants);SUPPORTS_REDIRECTION_ON_SIGN_IN</DefineConstants>
</PropertyGroup>
<PropertyGroup

6
Directory.Packages.props

@ -193,6 +193,11 @@
<PackageVersion Include="Microsoft.AspNet.Mvc" Version="5.3.0" />
<PackageVersion Include="Microsoft.AspNet.Web.Optimization" Version="1.1.3" />
<PackageVersion Include="Microsoft.AspNet.WebApi.Owin" Version="5.3.0" />
<PackageVersion Include="Microsoft.AspNetCore" Version="2.1.7" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.1.34" />
<PackageVersion Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="2.1.6" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc" Version="2.1.3" />
<PackageVersion Include="Microsoft.AspNetCore.StaticFiles" Version="2.1.1" />
<PackageVersion Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" Version="4.1.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.14" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="2.1.1" />
@ -203,6 +208,7 @@
<PackageVersion Include="Microsoft.Owin.Security.OAuth" Version="4.2.2" />
<PackageVersion Include="Microsoft.Web.Infrastructure" Version="2.0.1" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="Quartz.Extensions.Hosting" Version="3.5.0" />
<PackageVersion Include="Spectre.Console" Version="0.46.0" />
<PackageVersion Include="WebGrease" Version="1.6.0" />

7
sandbox/OpenIddict.Sandbox.AspNetCore.Client/Controllers/AuthenticationController.cs

@ -191,12 +191,19 @@ public class AuthenticationController : Controller
OpenIddictClientAspNetCoreConstants.Tokens.BackchannelIdentityToken or
OpenIddictClientAspNetCoreConstants.Tokens.RefreshToken));
#if SUPPORTS_REDIRECTION_ON_SIGN_IN
// Ask the default sign-in handler to return a new cookie and redirect the
// user agent to the return URL stored in the authentication properties.
//
// For scenarios where the default sign-in handler configured in the ASP.NET Core
// authentication options shouldn't be used, a specific scheme can be specified here.
return SignIn(new ClaimsPrincipal(identity), properties);
#else
// Note: "return SignIn(...)" cannot be directly used as-is on ASP.NET Core <7.0, as the cookies handler
// doesn't allow redirecting from an endpoint that doesn't match the path set in the cookie options.
await HttpContext.SignInAsync(new ClaimsPrincipal(identity), properties);
return Redirect(properties.RedirectUri ?? "/");
#endif
}
// Note: this controller uses the same callback action for all providers

2
sandbox/OpenIddict.Sandbox.AspNetCore.Client/Controllers/HomeController.cs

@ -49,7 +49,7 @@ public class HomeController : Controller
return View("Index", new IndexViewModel
{
Message = await response.Content.ReadAsStringAsync(cancellationToken),
Message = await response.Content.ReadAsStringAsync(),
Providers = from registration in await _service.GetClientRegistrationsAsync(cancellationToken)
where !string.IsNullOrEmpty(registration.ProviderName)
where !string.IsNullOrEmpty(registration.ProviderDisplayName)

12
sandbox/OpenIddict.Sandbox.AspNetCore.Client/OpenIddict.Sandbox.AspNetCore.Client.csproj

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFrameworks>net48;net8.0</TargetFrameworks>
<IsShipping>false</IsShipping>
<Nullable>disable</Nullable>
</PropertyGroup>
@ -17,4 +17,14 @@
<PackageReference Include="Quartz.Extensions.Hosting" />
</ItemGroup>
<ItemGroup
Condition=" ('$(TargetFrameworkIdentifier)' == '.NETCoreApp' And $([MSBuild]::VersionLessThan($(TargetFrameworkVersion), '3.0'))) Or
('$(TargetFrameworkIdentifier)' == '.NETFramework') Or
('$(TargetFrameworkIdentifier)' == '.NETStandard') ">
<PackageReference Include="Microsoft.AspNetCore" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" />
</ItemGroup>
</Project>

13
sandbox/OpenIddict.Sandbox.AspNetCore.Client/Program.cs

@ -1,11 +1,22 @@
namespace OpenIddict.Sandbox.AspNetCore.Client;
using Microsoft.AspNetCore;
namespace OpenIddict.Sandbox.AspNetCore.Client;
public static class Program
{
#if SUPPORTS_WEB_INTEGRATION_IN_GENERIC_HOST
public static void Main(string[] args) =>
CreateHostBuilder(args).Build().Run();
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(builder => builder.UseStartup<Startup>());
#else
public static void Main(string[] args) =>
CreateWebHostBuilder(args).Build().Run();
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
#endif
}

22
sandbox/OpenIddict.Sandbox.AspNetCore.Client/Startup.cs

@ -111,8 +111,9 @@ public class Startup
RedirectUri = new Uri("callback/login/local", UriKind.Relative),
PostLogoutRedirectUri = new Uri("callback/logout/local", UriKind.Relative),
// Instead of sending a client secret, this application authenticates by
// generating client assertions that are signed using a private signing key.
#if SUPPORTS_PEM_ENCODED_KEY_IMPORT
// On supported platforms, this application authenticates by generating JWT client
// assertions that are signed using a signing key instead of using a client secret.
//
// As such, no client secret is set, but an ECDSA key is registered and used by
// the OpenIddict client to automatically generate client assertions when needed.
@ -129,6 +130,9 @@ public class Startup
-----END EC PRIVATE KEY-----
"""), SecurityAlgorithms.EcdsaSha256, SecurityAlgorithms.Sha256)
}
#else
ClientSecret = "901564A5-E7FE-42CB-B10D-61EF6A8F3654"
#endif
});
// Register the Web providers integrations.
@ -160,6 +164,7 @@ public class Startup
.SetDuration("permanent");
});
#if SUPPORTS_PEM_ENCODED_KEY_IMPORT
static ECDsaSecurityKey GetECDsaSigningKey(ReadOnlySpan<char> key)
{
var algorithm = ECDsa.Create();
@ -167,11 +172,12 @@ public class Startup
return new ECDsaSecurityKey(algorithm);
}
#endif
});
services.AddHttpClient();
services.AddControllersWithViews();
services.AddMvc();
// Register the worker responsible for creating the database used to store tokens.
// Note: in a real world application, this step should be part of a setup script.
@ -186,15 +192,23 @@ public class Startup
app.UseStatusCodePagesWithReExecute("/error");
#if SUPPORTS_ENDPOINT_ROUTING
app.UseRouting();
#endif
app.UseAuthentication();
#if SUPPORTS_AUTHORIZATION_MIDDLEWARE
app.UseAuthorization();
#endif
#if SUPPORTS_ENDPOINT_ROUTING
app.UseEndpoints(options =>
{
options.MapControllers();
options.MapDefaultControllerRoute();
});
#else
app.UseMvcWithDefaultRoute();
#endif
}
}

2
sandbox/OpenIddict.Sandbox.AspNetCore.Client/Views/Home/Index.cshtml

@ -6,7 +6,7 @@
@model IndexViewModel
<div class="jumbotron">
@if (User?.Identity is { IsAuthenticated: true })
@if (User.Identity != null && User.Identity.IsAuthenticated)
{
<h1>Welcome, @User.Identity.Name</h1>

22
sandbox/OpenIddict.Sandbox.AspNetCore.Client/Worker.cs

@ -11,10 +11,26 @@ public class Worker : IHostedService
public async Task StartAsync(CancellationToken cancellationToken)
{
await using var scope = _serviceProvider.CreateAsyncScope();
var scope = _serviceProvider.CreateScope();
var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
await context.Database.EnsureCreatedAsync(cancellationToken);
try
{
var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
await context.Database.EnsureCreatedAsync(cancellationToken);
}
finally
{
if (scope is IAsyncDisposable disposable)
{
await disposable.DisposeAsync();
}
else
{
scope.Dispose();
}
}
}
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;

7
sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/AuthenticationController.cs

@ -80,11 +80,18 @@ public class AuthenticationController : Controller
OpenIddictClientAspNetCoreConstants.Tokens.BackchannelAccessToken or
OpenIddictClientAspNetCoreConstants.Tokens.RefreshToken));
#if SUPPORTS_REDIRECTION_ON_SIGN_IN
// Ask the default sign-in handler to return a new cookie and redirect the
// user agent to the return URL stored in the authentication properties.
//
// For scenarios where the default sign-in handler configured in the ASP.NET Core
// authentication options shouldn't be used, a specific scheme can be specified here.
return SignIn(new ClaimsPrincipal(identity), properties);
#else
// Note: "return SignIn(...)" cannot be directly used as-is on ASP.NET Core <7.0, as the cookies handler
// doesn't allow redirecting from an endpoint that doesn't match the path set in the cookie options.
await HttpContext.SignInAsync(new ClaimsPrincipal(identity), properties);
return Redirect(properties.RedirectUri ?? "/");
#endif
}
}

2
sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/AuthorizationController.cs

@ -96,7 +96,7 @@ public class AuthorizationController : Controller
Request.Form.Where(parameter => parameter.Key != Parameters.Prompt).ToList() :
Request.Query.Where(parameter => parameter.Key != Parameters.Prompt).ToList();
parameters.Add(KeyValuePair.Create(Parameters.Prompt, new StringValues(prompt)));
parameters.Add(new(Parameters.Prompt, new StringValues(prompt)));
// For applications that want to allow the client to select the external authentication provider
// that will be used to authenticate the user, the identity_provider parameter can be used for that.

25
sandbox/OpenIddict.Sandbox.AspNetCore.Server/OpenIddict.Sandbox.AspNetCore.Server.csproj

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFrameworks>net48;net8.0</TargetFrameworks>
<IsShipping>false</IsShipping>
<SignAssembly>false</SignAssembly>
<TypeScriptEnabled>false</TypeScriptEnabled>
@ -21,4 +21,27 @@
<PackageReference Include="Quartz.Extensions.Hosting" />
</ItemGroup>
<ItemGroup
Condition=" ('$(TargetFrameworkIdentifier)' == '.NETCoreApp' And $([MSBuild]::VersionLessThan($(TargetFrameworkVersion), '3.0'))) Or
('$(TargetFrameworkIdentifier)' == '.NETFramework') Or
('$(TargetFrameworkIdentifier)' == '.NETStandard') ">
<PackageReference Include="Microsoft.AspNetCore" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" />
</ItemGroup>
<!--
Note: Entity Framework Core 2.x references System.Interactive.Async 3.x, that includes
its own IAsyncEnumerable. To work around collisions between this type and the new type
now included in the BCL (System.Runtime), an alias is added to System.Interactive.Async.
-->
<Target Name="AddAssemblyAliasToReactiveAsync" AfterTargets="ResolveAssemblyReferences">
<ItemGroup>
<ReferencePath Condition=" '%(FileName)' == 'System.Interactive.Async' ">
<Aliases>reactive</Aliases>
</ReferencePath>
</ItemGroup>
</Target>
</Project>

13
sandbox/OpenIddict.Sandbox.AspNetCore.Server/Program.cs

@ -1,11 +1,22 @@
namespace OpenIddict.Sandbox.AspNetCore.Server;
using Microsoft.AspNetCore;
namespace OpenIddict.Sandbox.AspNetCore.Server;
public static class Program
{
#if SUPPORTS_WEB_INTEGRATION_IN_GENERIC_HOST
public static void Main(string[] args) =>
CreateHostBuilder(args).Build().Run();
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(builder => builder.UseStartup<Startup>());
#else
public static void Main(string[] args) =>
CreateWebHostBuilder(args).Build().Run();
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
#endif
}

12
sandbox/OpenIddict.Sandbox.AspNetCore.Server/Startup.cs

@ -11,7 +11,7 @@ public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddMvc();
services.AddDbContext<ApplicationDbContext>(options =>
{
@ -212,8 +212,9 @@ public class Startup
app.UseStatusCodePagesWithReExecute("/error");
#if SUPPORTS_ENDPOINT_ROUTING
app.UseRouting();
#endif
app.UseRequestLocalization(options =>
{
options.AddSupportedCultures("en-US", "fr-FR");
@ -222,12 +223,19 @@ public class Startup
});
app.UseAuthentication();
#if SUPPORTS_AUTHORIZATION_MIDDLEWARE
app.UseAuthorization();
#endif
#if SUPPORTS_ENDPOINT_ROUTING
app.UseEndpoints(options =>
{
options.MapControllers();
options.MapDefaultControllerRoute();
});
#else
app.UseMvcWithDefaultRoute();
#endif
}
}

35
sandbox/OpenIddict.Sandbox.AspNetCore.Server/Worker.cs

@ -16,13 +16,29 @@ public class Worker : IHostedService
public async Task StartAsync(CancellationToken cancellationToken)
{
await using var scope = _serviceProvider.CreateAsyncScope();
var scope = _serviceProvider.CreateScope();
var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
await context.Database.EnsureCreatedAsync(cancellationToken);
try
{
var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
await context.Database.EnsureCreatedAsync(cancellationToken);
await RegisterApplicationsAsync(scope.ServiceProvider);
await RegisterScopesAsync(scope.ServiceProvider);
}
finally
{
if (scope is IAsyncDisposable disposable)
{
await disposable.DisposeAsync();
}
await RegisterApplicationsAsync(scope.ServiceProvider);
await RegisterScopesAsync(scope.ServiceProvider);
else
{
scope.Dispose();
}
}
static async Task RegisterApplicationsAsync(IServiceProvider provider)
{
@ -76,6 +92,7 @@ public class Worker : IHostedService
{
ApplicationType = ApplicationTypes.Web,
ClientId = "mvc",
ClientSecret = "901564A5-E7FE-42CB-B10D-61EF6A8F3654",
ClientType = ClientTypes.Confidential,
ConsentType = ConsentTypes.Explicit,
DisplayName = "MVC client application",
@ -83,12 +100,13 @@ public class Worker : IHostedService
{
[CultureInfo.GetCultureInfo("fr-FR")] = "Application cliente MVC"
},
#if SUPPORTS_PEM_ENCODED_KEY_IMPORT
JsonWebKeySet = new JsonWebKeySet
{
Keys =
{
// Instead of sending a client secret, this application authenticates by
// generating client assertions that are signed using an ECDSA signing key.
// On supported platforms, this application authenticates by generating JWT client
// assertions that are signed using a signing key instead of using a client secret.
//
// Note: while the client needs access to the private key, the server only needs
// to know the public key to be able to validate the client assertions it receives.
@ -100,6 +118,7 @@ public class Worker : IHostedService
"""))
}
},
#endif
RedirectUris =
{
new Uri("https://localhost:44381/callback/login/local")
@ -261,6 +280,7 @@ public class Worker : IHostedService
});
}
#if SUPPORTS_PEM_ENCODED_KEY_IMPORT
static ECDsaSecurityKey GetECDsaSigningKey(ReadOnlySpan<char> key)
{
var algorithm = ECDsa.Create();
@ -268,6 +288,7 @@ public class Worker : IHostedService
return new ECDsaSecurityKey(algorithm);
}
#endif
}
static async Task RegisterScopesAsync(IServiceProvider provider)

Loading…
Cancel
Save