Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to .NET 6 #623

Merged
merged 5 commits into from
Nov 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
- name: Checkout code
uses: actions/checkout@v2

- name: Setup .NET Core SDK
- name: Setup .NET SDK
uses: actions/setup-dotnet@v1

# Arcade only allows the revision to contain up to two characters, and GitHub Actions does not roll-over
Expand Down
4 changes: 2 additions & 2 deletions AspNet.Security.OAuth.Providers.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28803.156
# Visual Studio Version 17
VisualStudioVersion = 17.0.31825.309
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{C1352FD3-AE8B-43EE-B45B-F6E0B3FBAC6D}"
EndProject
Expand Down
20 changes: 19 additions & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
<Import Project="Sdk.props" Sdk="Microsoft.DotNet.Arcade.Sdk" />

<PropertyGroup>
<DefaultNetCoreTargetFramework>net5.0</DefaultNetCoreTargetFramework>
<DefaultNetCoreTargetFramework>net6.0</DefaultNetCoreTargetFramework>
<LangVersion>latest</LangVersion>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<!-- TODO Actually resolve this by using the logging source generator -->
<NoWarn>$(NoWarn);CA1848</NoWarn>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<DebugSymbols>true</DebugSymbols>
<DebugType>portable</DebugType>
Expand Down Expand Up @@ -63,6 +65,12 @@
<EnableNETAnalyzers>true</EnableNETAnalyzers>
</PropertyGroup>

<PropertyGroup>
<EnablePackageValidation>$(IsPackable)</EnablePackageValidation>
<!-- TODO Remove suppression once 6.0.0 is released. -->
<NoWarn>$(NoWarn);PKV006</NoWarn>
martincostello marked this conversation as resolved.
Show resolved Hide resolved
</PropertyGroup>

<ItemGroup>
<AdditionalFiles Include="$(MSBuildThisFileDirectory)stylecop.json" Link="stylecop.json" />
<PackageReference Include="StyleCop.Analyzers" PrivateAssets="All" />
Expand All @@ -73,4 +81,14 @@
<ProjectCapability Include="DynamicFileNesting" />
</ItemGroup>

<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<Using Include="JetBrains.Annotations" />
<Using Include="Microsoft.AspNetCore.Authentication" />
<Using Include="Microsoft.AspNetCore.Authentication.OAuth" />
</ItemGroup>

</Project>
7 changes: 5 additions & 2 deletions NuGet.config
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="NuGet" value="https://api.nuget.org/v3/index.json" />
<add key="dotnet-eng" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json" />
<add key="dotnet-tools" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json" />
<add key="dotnet-core" value="https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json" />
<add key="azureadwebstacknightly" value="https://www.myget.org/F/azureadwebstacknightly/api/v3/index.json" />
<add key="dotnet-public" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json" />
</packageSources>
<disabledPackageSources>
<clear />
</disabledPackageSources>
</configuration>
19 changes: 9 additions & 10 deletions Packages.props
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
<Project>

<ItemGroup>
<PackageReference Update="JetBrains.Annotations" Version="2021.1.0" />
<PackageReference Update="JustEat.HttpClientInterception" Version="3.1.0" />
<PackageReference Update="MartinCostello.Logging.XUnit" Version="0.1.1" />
<PackageReference Update="Microsoft.AspNetCore.Authentication.Google" Version="5.0.6" />
<PackageReference Update="Microsoft.AspNetCore.Authentication.Twitter" Version="5.0.6" />
<PackageReference Update="Microsoft.AspNetCore.Mvc.Testing" Version="5.0.6" />
<PackageReference Update="Microsoft.AspNetCore.TestHost" Version="5.0.6" />
<PackageReference Update="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="6.6.0" />
<PackageReference Update="JetBrains.Annotations" Version="2021.3.0" />
<PackageReference Update="JustEat.HttpClientInterception" Version="3.1.1" />
<PackageReference Update="MartinCostello.Logging.XUnit" Version="0.2.0" />
<PackageReference Update="Microsoft.AspNetCore.Authentication.Google" Version="6.0.0" />
<PackageReference Update="Microsoft.AspNetCore.Authentication.Twitter" Version="6.0.0" />
<PackageReference Update="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.0" />
<PackageReference Update="Microsoft.AspNetCore.TestHost" Version="6.0.0" />
<PackageReference Update="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="6.10.0" />
<PackageReference Update="Moq" Version="4.16.1" />
<PackageReference Update="Shouldly" Version="4.0.3" />
<PackageReference Update="StyleCop.Analyzers" Version="1.1.118" />
<PackageReference Update="System.IdentityModel.Tokens.Jwt" Version="6.6.0" />
<PackageReference Update="StyleCop.Analyzers" Version="1.2.0-beta.354" />
</ItemGroup>

</Project>
25 changes: 23 additions & 2 deletions docs/discord.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,27 @@ _None._

| Property Name | Property Type | Description | Default Value |
|:--|:--|:--|:--|
| `DiscordAvatarFormat` | `string` | Gets or sets the URL format string to use for user avatar images. | `DiscordAuthenticationConstants.Urls.AvatarUrlFormat` |
| `DiscordCdn` | `string` | The URL to use for the Discord CDN. | `DiscordAuthenticationConstants.Urls.DiscordCdn` |
| `Prompt` | `string?` | The value to use for the `prompt` query string parameter when making HTTP requests to the authorization endpoint. | `null` |

## Avatars as Claims

Versions of the Discord provider before version `6.0.0` would automatically map the user's avatar URL as the `urn:discord:avatar:url` claim.

This functionality is no longer built-in (see [#584](https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers/issues/584) and [#585](https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers/pull/585)), but can be added to your application with some extra code similar to that shown in the sample below.

```csharp
services.AddAuthentication(options => /* Auth configuration */)
.AddDiscord(options =>
{
options.ClientId = "my-client-id";
options.ClientSecret = "my-client-secret";

options.ClaimActions.MapCustomJson("urn:discord:avatar:url", user =>
string.Format(
CultureInfo.InvariantCulture,
"https://cdn.discordapp.com/avatars/{0}/{1}.{2}",
user.GetString("id"),
user.GetString("avatar"),
user.GetString("avatar").StartsWith("a_") ? "gif" : "png"));
});
```
57 changes: 42 additions & 15 deletions docs/sign-in-with-apple.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ This document provides some additional information and context to help you confi

Unlike other providers, the `ClientSecret` property is not used as _Sign in with Apple_ does not use a static client secret value. Instead the client secret has to be generated using a private key file provided by Apple from the Developer Portal that is used with the Key ID and Team ID to create a signed JSON Web Token (JWT).

The provider comes with a built-in extension method ([`UsePrivateKey(string)`](https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers/blob/8e4c19008f518f3730bab90a980e01347ba6f3d3/src/AspNet.Security.OAuth.Apple/AppleAuthenticationOptionsExtensions.cs#L20-L33 "UsePrivateKey() extension method")) to generate they secret from a `.p8` certificate file on disk that you provide. Here's a [code example](https://github.com/martincostello/SignInWithAppleSample/blob/245bb70a164b66ec98ea3c2040a7387b0a3e8f0e/src/SignInWithApple/Startup.cs#L37-L46 "Example code to configure the Apple provider"):
The provider comes with a built-in extension method `UsePrivateKey(string)` to generate they secret from a `.p8` certificate file on disk that you provide. Here's a code example:

```csharp
services.AddAuthentication(options => /* Auth configuration */)
Expand All @@ -25,20 +25,49 @@ services.AddAuthentication(options => /* Auth configuration */)
});
```

Alternatively you can use the [`Func<string, Task<byte[]>> PrivateKeyBytes`](https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers/blob/8e4c19008f518f3730bab90a980e01347ba6f3d3/src/AspNet.Security.OAuth.Apple/AppleAuthenticationOptions.cs#L78-L85 "Definition of PrivateKeyBytes property") property of the `AppleAuthenticationOptions` class to provide a delegate to a custom method of your own that loads the private key's bytes from another location, such as Azure Key Vault, Kubernetes secrets etc.
Alternatively you can use the `Func<string, Task<ReadOnlyMemory<char>>> PrivateKey` property of the `AppleAuthenticationOptions` class to provide a delegate to a custom method of your own that loads the private key's bytes from another location, such as Azure Key Vault, Kubernetes secrets etc.

### Issues Loading Private Key
Below are two examples of this approach.

#### Loading from an Environment Variable

If you encounter issues loading the private key of the certificate, the reasons could include one of the two scenarios:
```csharp
services.AddAuthentication(options => /* Auth configuration */)
.AddApple(options =>
{
options.ClientId = Configuration["Apple:ClientId"];
options.KeyId = Configuration["Apple:KeyId"];
options.TeamId = Configuration["Apple:TeamId"];
options.PrivateKey = (keyId, _) =>
{
return Task.FromResult(Configuration[$"Apple:Key:{keyId}"].AsMemory());
};
});
```

1. Using .NET Core 2.x on Linux or macOS
1. Using Windows Server with IIS
#### Loading from Azure Key Vault

#### .NET Core 2.x on Linux or macOS
```csharp
services.AddAuthentication(options => /* Auth configuration */)
.AddApple()
.Services
.AddOptions<AppleAuthenticationOptions>(AppleAuthenticationDefaults.AuthenticationScheme)
.Configure<IConfiguration, SecretClient>((options, configuration, client) =>
{
options.ClientId = configuration["Apple:ClientId"];
options.KeyId = configuration["Apple:KeyId"];
options.TeamId = configuration["Apple:TeamId"];
options.PrivateKey = async (keyId, cancellationToken) =>
{
var secret = await client.GetSecretAsync($"AuthKey-{keyId}", cancellationToken: cancellationToken);
return secret.Value.Value.AsMemory();
};
});
```

For the first scenario, before .NET Core 3.0 non-Windows platforms did not support loading `.p8` (PKCS #8) files. If you cannot use .NET Core 3.1 or later, it is recommended that you create a `.pfx` certificate file from your `.p8` file and use that instead.
### Issues Loading Private Key

Further information can be found in this GitHub issue: https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers/issues/390
If you encounter issues loading the private key of the certificate, the reasons could include one of the following scenarios.

#### Windows Server with IIS

Expand All @@ -63,7 +92,7 @@ Below are links to some issues raised against this repository that were related

## Sign in with Apple on iOS

When using _Sign In with Apple_ on an iOS 13+ Device, [Apple provides a different authentication workflow](https://developer.apple.com/documentation/authenticationservices) that returns the validation response to the app instead of in a server callback. Using that response to authenticate a user against your own backend requires sending the response to your servers and [communicating with the Apple authentication endpoint from there](https://developer.apple.com/documentation/sign_in_with_apple/generate_and_validate_tokens).
When using _Sign In with Apple_ on an iOS 13+ Device, [Apple provides a different authentication workflow](https://developer.apple.com/documentation/authenticationservices) that returns the validation response to the app instead of in a server callback. Using that response to authenticate a user against your own backend requires sending the response to your servers and [communicating with the Apple authentication endpoint from there](https://developer.apple.com/documentation/sign_in_with_apple/generate_and_validate_tokens).

This workflow is out of the scope of this package but client secret generation and token validation can provide a starting point for an ASP.NET.Core integration. Note that the `ClientId` in this case is the App Id where the authentication was requested, not your Services Id.

Expand All @@ -84,14 +113,12 @@ Below are links to a number of other documentation sources, blog posts and sampl
|:--|:--|:--|:--|
| `ClientSecretExpiresAfter` | `TimeSpan` | The period of time after which generated client secrets expire if `GenerateClientSecret` is set to `true`. | 6 months |
| `ClientSecretGenerator` | `AppleClientSecretGenerator` | A service that generates client secrets for Sign In with Apple. | _An internal implementation_ |
| `ConfigurationManager` | `IConfigurationManager<OpenIdConnectConfiguration>?` | The configuration manager to use for the OpenID configuration. | `null` |
| `GenerateClientSecret` | `bool` | Whether to automatically generate a client secret. | `false` |
| `JwtSecurityTokenHandler` | `JwtSecurityTokenHandler` | The handler to use to validate JSON Web Keys. | `new JwtSecurityTokenHandler()` |
| `KeyId` | `string?` | The optional ID for your Sign in with Apple private key. | `null` |
| `KeyStore` | `AppleKeyStore` | A service that loads private keys to use with Sign In with Apple. | _An internal implementation_ |
| `PublicKeyCacheLifetime` | `TimeSpan` | The default period of time to cache Apple public key(s) for. | `TimeSpan.FromMinutes(15)` |
| `PublicKeyEndpoint` | `string` | The URI to use to retrieve the Apple public keys. | `AppleAuthenticationDefaults.PublicKeyEndpoint` |
| `PrivateKeyBytes` | `Func<string, Task<byte[]>>?` | An optional delegate to use to get the raw bytes of the client's private key in PKCS #8 format. | `null` |
| `PrivateKeyBytes` | `Func<string, Task<ReadOnlyMemory<char>>>?` | An optional delegate to use to get the characters of the client's private key in PKCS #8 format. | `null` |
| `TeamId` | `string` | The Team ID for your Apple Developer account. | `""` |
| `TokenAudience` | `string` | The audience used for tokens. | `AppleAuthenticationConstants.Audience` |
| `TokenValidator` | `AppleIdTokenValidator` | A service that validates Apple ID tokens. | `An internal implementation` |
| `TokenValidationParameters` | `TokenValidationParameters` | The JSON Web Token validation parameters to use. | `new TokenValidationParameters()` |
| `ValidateTokens` | `bool` | Whether to validate tokens using Apple's public key. | `true` |
9 changes: 5 additions & 4 deletions eng/Version.Details.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@
</ProductDependencies>

<ToolsetDependencies>
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="5.0.0-beta.20180.5">
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="6.0.0-beta.21519.3">
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha>09bb9d929120b402348c9a0e9c8c951e824059aa</Sha>
<Sha>85f3aa16d8797b5020f1fda11df1a958feb5f8df</Sha>
<SourceBuild RepoName="arcade" ManagedOnly="true" />
</Dependency>

<Dependency Name="Microsoft.DotNet.Helix.Sdk" Version="5.0.0-beta.20180.5">
<Dependency Name="Microsoft.DotNet.Helix.Sdk" Version="6.0.0-beta.21519.3">
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha>09bb9d929120b402348c9a0e9c8c951e824059aa</Sha>
<Sha>85f3aa16d8797b5020f1fda11df1a958feb5f8df</Sha>
</Dependency>
</ToolsetDependencies>

Expand Down
6 changes: 4 additions & 2 deletions eng/Versions.props
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
<Project>

<PropertyGroup>
<MajorVersion>5</MajorVersion>
<MajorVersion>6</MajorVersion>
<MinorVersion>0</MinorVersion>
<PatchVersion>19</PatchVersion>
<PatchVersion>0</PatchVersion>
<VersionPrefix>$(MajorVersion).$(MinorVersion).$(PatchVersion)</VersionPrefix>
<!-- TODO Baseline to 6.0.0 once released -->
<PackageValidationBaselineVersion>5.0.17</PackageValidationBaselineVersion>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<PreReleaseVersionLabel>preview</PreReleaseVersionLabel>
<PreReleaseVersionIteration></PreReleaseVersionIteration>
<PreReleaseBrandingLabel>Preview $(PreReleaseVersionIteration)</PreReleaseBrandingLabel>
Expand Down
Loading