diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index 02b8f95..447a69b 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"dotnet-reportgenerator-globaltool": {
- "version": "4.8.13",
+ "version": "5.0.0",
"commands": [
"reportgenerator"
]
diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml
index 09e600d..8459841 100644
--- a/.github/workflows/cd.yml
+++ b/.github/workflows/cd.yml
@@ -16,7 +16,7 @@ jobs:
- name: Set up .NET SDK
uses: actions/setup-dotnet@v1
with:
- dotnet-version: 5.0.x
+ dotnet-version: 6.0.x
- name: Build packages
run: |
dotnet --info
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 8a8b746..9cde236 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -24,10 +24,10 @@ jobs:
uses: actions/setup-dotnet@v1
with:
dotnet-version: 3.1.x
- - name: Set up .NET 5 SDK
+ - name: Set up .NET 6 SDK
uses: actions/setup-dotnet@v1
with:
- dotnet-version: 5.0.x
+ dotnet-version: 6.0.x
- name: Build
run: |
dotnet --info
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 046c782..ebe1191 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,12 @@
All notable changes to this project will be documented in this file.
+## 2.3.1 (2021-11-14)
+
+- Floating latest dependencies for .NET 6
+- [RNGCryptoServiceProvider is obsolete since .NET 6](https://github.com/dotnet/runtime/issues/40169)
+- Bump System.ComponentModel.Annotations from 4.5.0 to 4.7.0
+
## 2.3.0 (2021-06-11)
- Floating latest dependencies for .NET Core 3.1 and .NET 5
diff --git a/OAuth.sln b/OAuth.sln
index f1a6823..b7c1bdb 100644
--- a/OAuth.sln
+++ b/OAuth.sln
@@ -35,6 +35,9 @@ EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GSS.Authorization.OAuth2.HttpClient.Tests", "test\GSS.Authorization.OAuth2.HttpClient.Tests\GSS.Authorization.OAuth2.HttpClient.Tests.csproj", "{28080D26-3251-4619-AD9D-54381759ED2A}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{F0FA418E-E9E8-4A7F-835D-A00476B78754}"
+ProjectSection(SolutionItems) = preProject
+ samples\Directory.Build.props = samples\Directory.Build.props
+EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OAuth2HttpClientSample", "samples\OAuth2HttpClientSample\OAuth2HttpClientSample.csproj", "{D67C5C98-4344-4E1F-B809-5A91551C90EC}"
EndProject
diff --git a/samples/Directory.Build.props b/samples/Directory.Build.props
new file mode 100644
index 0000000..54e3cb2
--- /dev/null
+++ b/samples/Directory.Build.props
@@ -0,0 +1,11 @@
+
+
+
+
+
+ enable
+ enable
+ false
+
+
+
\ No newline at end of file
diff --git a/samples/OAuth2HttpClientSample/OAuth2HttpClientSample.csproj b/samples/OAuth2HttpClientSample/OAuth2HttpClientSample.csproj
index 09bc206..a749807 100644
--- a/samples/OAuth2HttpClientSample/OAuth2HttpClientSample.csproj
+++ b/samples/OAuth2HttpClientSample/OAuth2HttpClientSample.csproj
@@ -1,9 +1,8 @@
- net5.0
+ net6.0
Exe
- false
diff --git a/samples/OAuth2HttpClientSample/Program.cs b/samples/OAuth2HttpClientSample/Program.cs
index 463b572..2f1828c 100644
--- a/samples/OAuth2HttpClientSample/Program.cs
+++ b/samples/OAuth2HttpClientSample/Program.cs
@@ -1,60 +1,45 @@
-using System;
-using System.Collections.Generic;
using System.Net;
using System.Net.Http.Headers;
-using System.Threading.Tasks;
using GSS.Authorization.OAuth2;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
-namespace OAuth2HttpClientSample
+static void ConfigureAuthorizerOptions(IServiceProvider resolver, AuthorizerOptions options)
{
- public class Program
- {
- public static async Task Main(string[] args)
- {
- var host = Host.CreateDefaultBuilder(args)
- .ConfigureServices((hostContext, services) =>
- {
- var clientBuilder =
- hostContext.Configuration.GetValue("OAuth2:GrantFlow", "ClientCredentials")
- .Equals("ClientCredentials", StringComparison.OrdinalIgnoreCase)
- ? services.AddOAuth2HttpClient(
- ConfigureAuthorizerOptions)
- : services.AddOAuth2HttpClient(
- ConfigureAuthorizerOptions);
- clientBuilder.ConfigureHttpClient(client =>
- {
- client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
- });
- }).Build();
- var configuration = host.Services.GetRequiredService();
+ var configuration = resolver.GetRequiredService();
+ options.AccessTokenEndpoint = configuration.GetValue("OAuth2:AccessTokenEndpoint");
+ options.ClientId = configuration["OAuth2:ClientId"];
+ options.ClientSecret = configuration["OAuth2:ClientSecret"];
+ options.Credentials = new NetworkCredential(
+ configuration["OAuth2:Credentials:UserName"],
+ configuration["OAuth2:Credentials:Password"]);
+ options.Scopes = configuration.GetSection("OAuth2:Scopes").Get>();
+ options.OnError = (code, message) => Console.Error.Write($"ERROR: [${code}]: {message}");
+}
- Console.WriteLine("Creating a client...");
- var oauth2Client = host.Services.GetRequiredService();
+var host = Host.CreateDefaultBuilder(args)
+.ConfigureServices((hostContext, services) =>
+{
+ var clientBuilder =
+ hostContext.Configuration.GetValue("OAuth2:GrantFlow", "ClientCredentials")
+ .Equals("ClientCredentials", StringComparison.OrdinalIgnoreCase)
+ ? services.AddOAuth2HttpClient(
+ ConfigureAuthorizerOptions)
+ : services.AddOAuth2HttpClient(
+ ConfigureAuthorizerOptions);
+ clientBuilder.ConfigureHttpClient(client => client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")));
+}).Build();
+var configuration = host.Services.GetRequiredService();
+
+Console.WriteLine("Creating a client...");
+var oauth2Client = host.Services.GetRequiredService();
+
+Console.WriteLine("Sending a request...");
+var response = await oauth2Client.HttpClient.GetAsync(configuration.GetValue("OAuth2:ResourceEndpoint")).ConfigureAwait(false);
+
+Console.WriteLine("Response data:");
+var data = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
+Console.WriteLine(data);
- Console.WriteLine("Sending a request...");
- var response = await oauth2Client.HttpClient.GetAsync(configuration.GetValue("OAuth2:ResourceEndpoint")).ConfigureAwait(false);
- var data = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
- Console.WriteLine("Response data:");
- Console.WriteLine(data);
- }
- private static void ConfigureAuthorizerOptions(IServiceProvider resolver, AuthorizerOptions options)
- {
- var configuration = resolver.GetRequiredService();
- options.AccessTokenEndpoint = configuration.GetValue("OAuth2:AccessTokenEndpoint");
- options.ClientId = configuration["OAuth2:ClientId"];
- options.ClientSecret = configuration["OAuth2:ClientSecret"];
- options.Credentials = new NetworkCredential(
- configuration["OAuth2:Credentials:UserName"],
- configuration["OAuth2:Credentials:Password"]);
- options.Scopes = configuration.GetSection("OAuth2:Scopes").Get>();
- options.OnError = (code, message) =>
- {
- Console.Error.Write($"ERROR: [${code}]: {message}");
- };
- }
- }
-}
diff --git a/samples/OAuth2HttpClientSample/appsettings.json b/samples/OAuth2HttpClientSample/appsettings.json
index e951edb..4acf8b4 100644
--- a/samples/OAuth2HttpClientSample/appsettings.json
+++ b/samples/OAuth2HttpClientSample/appsettings.json
@@ -1,14 +1,11 @@
{
"Logging": {
- "IncludeScopes": false,
"LogLevel": {
- "Default": "Debug",
- "System": "Information",
- "Microsoft": "Information"
+ "Default": "Information"
}
},
"OAuth2": {
- "AccessTokenEndpoint": "https://example.com/oauth2/accessToken",
+ "AccessTokenEndpoint": "https://example.com/oauth2/token",
"ResourceEndpoint": "https://example.com/oauth2/profile",
"ClientId": "CHANGE_ME",
"ClientSecret": "CHANGE_ME",
diff --git a/samples/OAuthHttpClientSample/OAuthHttpClientSample.csproj b/samples/OAuthHttpClientSample/OAuthHttpClientSample.csproj
index 829ba62..f9c611e 100644
--- a/samples/OAuthHttpClientSample/OAuthHttpClientSample.csproj
+++ b/samples/OAuthHttpClientSample/OAuthHttpClientSample.csproj
@@ -1,9 +1,8 @@
- net5.0
+ net6.0
Exe
- false
diff --git a/samples/OAuthHttpClientSample/Program.cs b/samples/OAuthHttpClientSample/Program.cs
index 93c399c..57165f4 100644
--- a/samples/OAuthHttpClientSample/Program.cs
+++ b/samples/OAuthHttpClientSample/Program.cs
@@ -1,54 +1,40 @@
-using System;
-using System.Collections.Generic;
-using System.Net.Http;
using System.Net.Http.Headers;
-using System.Threading.Tasks;
using GSS.Authorization.OAuth;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
-namespace OAuthHttpClientSample
+var host = Host.CreateDefaultBuilder(args)
+.ConfigureServices((hostContext, services) =>
{
- public static class Program
+ services.AddOAuthHttpClient((_, options) =>
{
- public static async Task Main(string[] args)
- {
- var host = Host.CreateDefaultBuilder(args)
- .ConfigureServices((hostContext, services) =>
- {
- services.AddOAuthHttpClient((_, options) =>
- {
- options.ClientCredentials = new OAuthCredential(
- hostContext.Configuration["OAuth:ClientId"],
- hostContext.Configuration["OAuth:ClientSecret"]);
- options.TokenCredentials = new OAuthCredential(
- hostContext.Configuration["OAuth:TokenId"],
- hostContext.Configuration["OAuth:TokenSecret"]);
- options.SignedAsQuery = hostContext.Configuration.GetValue("OAuth:SignedAsQuery", false);
- options.SignedAsBody = hostContext.Configuration.GetValue("OAuth:SignedAsBody", false);
- }).ConfigureHttpClient(client =>
- {
- client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
- });
- }).Build();
- var configuration = host.Services.GetRequiredService();
+ options.ClientCredentials = new OAuthCredential(
+ hostContext.Configuration["OAuth:ClientId"],
+ hostContext.Configuration["OAuth:ClientSecret"]);
+ options.TokenCredentials = new OAuthCredential(
+ hostContext.Configuration["OAuth:TokenId"],
+ hostContext.Configuration["OAuth:TokenSecret"]);
+ options.SignedAsQuery = hostContext.Configuration.GetValue("OAuth:SignedAsQuery", false);
+ options.SignedAsBody = hostContext.Configuration.GetValue("OAuth:SignedAsBody", false);
+ }).ConfigureHttpClient(client => client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")));
+}).Build();
- Console.WriteLine("Creating a client...");
- var oauthClient = host.Services.GetRequiredService();
+var configuration = host.Services.GetRequiredService();
- Console.WriteLine("Sending a request...");
- var method = new HttpMethod(configuration.GetValue("Request:Method", HttpMethod.Get.Method));
- var request = new HttpRequestMessage(method, configuration.GetValue("Request:Uri"));
- var body = configuration.GetSection("Request:Body").Get>();
- if (body != null)
- {
- request.Content = new FormUrlEncodedContent(body);
- }
- var response = await oauthClient.HttpClient.SendAsync(request).ConfigureAwait(false);
- var data = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
- Console.WriteLine("Response data:");
- Console.WriteLine(data);
- }
- }
+Console.WriteLine("Creating a client...");
+var oauthClient = host.Services.GetRequiredService();
+
+Console.WriteLine("Sending a request...");
+var method = new HttpMethod(configuration.GetValue("Request:Method", HttpMethod.Get.Method));
+var request = new HttpRequestMessage(method, configuration.GetValue("Request:Uri"));
+var body = configuration.GetSection("Request:Body").Get>();
+if (body != null)
+{
+ request.Content = new FormUrlEncodedContent(body);
}
+var response = await oauthClient.HttpClient.SendAsync(request).ConfigureAwait(false);
+
+Console.WriteLine("Response data:");
+var data = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
+Console.WriteLine(data);
diff --git a/samples/OAuthHttpClientSample/appsettings.json b/samples/OAuthHttpClientSample/appsettings.json
index ad4762b..f80a2f1 100644
--- a/samples/OAuthHttpClientSample/appsettings.json
+++ b/samples/OAuthHttpClientSample/appsettings.json
@@ -1,10 +1,7 @@
{
"Logging": {
- "IncludeScopes": false,
"LogLevel": {
- "Default": "Debug",
- "System": "Information",
- "Microsoft": "Information"
+ "Default": "Information"
}
},
"OAuth": {
@@ -14,7 +11,7 @@
"TokenSecret": "CHANGE_ME"
},
"Request": {
- "Uri": "https://example.com/oauth/profile",
- "Method": "GET"
+ "Method": "GET",
+ "Uri": "https://example.com/oauth/profile"
}
}
\ No newline at end of file
diff --git a/samples/OAuthInteractiveConsoleAuthorizer/OAuthInteractiveConsoleAuthorizer.csproj b/samples/OAuthInteractiveConsoleAuthorizer/OAuthInteractiveConsoleAuthorizer.csproj
index ab2234c..4fa1ed7 100644
--- a/samples/OAuthInteractiveConsoleAuthorizer/OAuthInteractiveConsoleAuthorizer.csproj
+++ b/samples/OAuthInteractiveConsoleAuthorizer/OAuthInteractiveConsoleAuthorizer.csproj
@@ -1,9 +1,8 @@
+ net6.0
Exe
- net5.0
- false
@@ -25,9 +24,8 @@
-
-
+
diff --git a/samples/OAuthInteractiveConsoleAuthorizer/Program.cs b/samples/OAuthInteractiveConsoleAuthorizer/Program.cs
index 82d7e9f..20ffffa 100644
--- a/samples/OAuthInteractiveConsoleAuthorizer/Program.cs
+++ b/samples/OAuthInteractiveConsoleAuthorizer/Program.cs
@@ -1,72 +1,34 @@
-using System;
using System.ComponentModel.DataAnnotations;
-using System.Diagnostics;
-using System.IO;
-using System.Threading;
-using System.Threading.Tasks;
using GSS.Authorization.OAuth;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
-namespace OAuthInteractiveConsoleGrantTool
+var host = Host.CreateDefaultBuilder()
+.ConfigureServices((context, services) =>
{
- public class Program
- {
- private readonly IAuthorizer _authorizer;
-
- public Program(IAuthorizer authorizer)
- {
- _authorizer = authorizer;
- }
-
- public static async Task Main(string[] args)
+ services.AddOptions()
+ .Configure(options =>
{
- var mainModule = Process.GetCurrentProcess().MainModule;
- var hostBuilder = Host.CreateDefaultBuilder();
- if (mainModule != null)
- {
- hostBuilder.ConfigureAppConfiguration(config =>
- {
- config.SetBasePath(Path.GetDirectoryName(mainModule.FileName));
- });
- }
- return await hostBuilder.ConfigureServices((context, services) =>
- {
- services.AddOptions()
- .Configure(options =>
- {
- options.ClientCredentials = new OAuthCredential(
- context.Configuration["OAuth:ClientId"],
- context.Configuration["OAuth:ClientSecret"]);
- options.CallBack = context.Configuration.GetValue("OAuth:Callback");
- options.TemporaryCredentialRequestUri = context.Configuration.GetValue("OAuth:TemporaryCredentialRequestUri");
- options.ResourceOwnerAuthorizeUri = context.Configuration.GetValue("OAuth:ResourceOwnerAuthorizeUri");
- options.TokenRequestUri = context.Configuration.GetValue("OAuth:TokenRequestUri");
- })
- .PostConfigure(options =>
- {
- Validator.ValidateObject(options, new ValidationContext(options), true);
- });
- services.AddSingleton();
- services.AddHttpClient()
- .ConfigureHttpClient(client =>
- {
- client.BaseAddress = context.Configuration.GetValue("OAuth:BaseAddress");
- });
- services.AddTransient(resolver => resolver.GetRequiredService());
- })
- .RunCommandLineApplicationAsync(args).ConfigureAwait(false);
- }
+ options.ClientCredentials = new OAuthCredential(
+ context.Configuration["OAuth:ClientId"],
+ context.Configuration["OAuth:ClientSecret"]);
+ options.CallBack = context.Configuration.GetValue("OAuth:Callback");
+ options.TemporaryCredentialRequestUri = context.Configuration.GetValue("OAuth:TemporaryCredentialRequestUri");
+ options.ResourceOwnerAuthorizeUri = context.Configuration.GetValue("OAuth:ResourceOwnerAuthorizeUri");
+ options.TokenRequestUri = context.Configuration.GetValue("OAuth:TokenRequestUri");
+ })
+ .PostConfigure(options => Validator.ValidateObject(options, new ValidationContext(options), true));
+ services.AddSingleton();
+ services.AddHttpClient()
+ .ConfigureHttpClient(client => client.BaseAddress = context.Configuration.GetValue("OAuth:BaseAddress"));
+ services.AddTransient(resolver => resolver.GetRequiredService());
+}).Build();
- private async Task OnExecuteAsync(CancellationToken cancellationToken = default)
- {
- var tokenCredentials = await _authorizer.GrantAccessAsync(cancellationToken).ConfigureAwait(false);
- Console.WriteLine("Token Credentials ...");
- Console.WriteLine($"Key: {tokenCredentials.Key}");
- Console.WriteLine($"Secret: {tokenCredentials.Secret}");
- Console.WriteLine("Press any key to exit...");
- Console.ReadKey();
- }
- }
-}
+var authorizer = host.Services.GetRequiredService();
+var tokenCredentials = await authorizer.GrantAccessAsync().ConfigureAwait(false);
+Console.WriteLine("Token Credentials ...");
+Console.WriteLine($"Key: {tokenCredentials.Key}");
+Console.WriteLine($"Secret: {tokenCredentials.Secret}");
+Console.WriteLine("Press any key to exit...");
+Console.ReadKey();
diff --git a/samples/OAuthInteractiveConsoleAuthorizer/appsettings.json b/samples/OAuthInteractiveConsoleAuthorizer/appsettings.json
index 7ff62dd..e87fae8 100644
--- a/samples/OAuthInteractiveConsoleAuthorizer/appsettings.json
+++ b/samples/OAuthInteractiveConsoleAuthorizer/appsettings.json
@@ -1,10 +1,7 @@
{
"Logging": {
- "IncludeScopes": false,
"LogLevel": {
- "Default": "Information",
- "System": "Warning",
- "Microsoft": "Warning"
+ "Default": "Information"
}
},
"OAuth": {
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index 6c4f8d8..13218b2 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -8,8 +8,9 @@
$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb
true
true
+ true
enable
- 2.3.0
+ 2.3.1
@@ -23,8 +24,7 @@
-
-
+
\ No newline at end of file
diff --git a/src/GSS.Authorization.OAuth.HttpClient/GSS.Authorization.OAuth.HttpClient.csproj b/src/GSS.Authorization.OAuth.HttpClient/GSS.Authorization.OAuth.HttpClient.csproj
index 9d5fc38..65fb0f0 100644
--- a/src/GSS.Authorization.OAuth.HttpClient/GSS.Authorization.OAuth.HttpClient.csproj
+++ b/src/GSS.Authorization.OAuth.HttpClient/GSS.Authorization.OAuth.HttpClient.csproj
@@ -1,7 +1,7 @@
- netstandard2.0;netcoreapp3.1;net5.0
+ netstandard2.0;netcoreapp3.1;net5.0;net6.0
OAuth 1.0 authorized HttpClient, friendly with HttpClientFactory
OAuth;HttpClient;HttpHandler
GSS.Authorization.OAuth
@@ -27,4 +27,8 @@
+
+
+
+
diff --git a/src/GSS.Authorization.OAuth/InteractiveConsoleAuthorizer.cs b/src/GSS.Authorization.OAuth/InteractiveConsoleAuthorizer.cs
index b797dbc..8017b4f 100644
--- a/src/GSS.Authorization.OAuth/InteractiveConsoleAuthorizer.cs
+++ b/src/GSS.Authorization.OAuth/InteractiveConsoleAuthorizer.cs
@@ -39,16 +39,9 @@ private static void OpenBrowser(Uri uri)
UseShellExecute = true
});
}
- catch
+ catch when (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
- {
- Process.Start("xdg-open", uri.AbsoluteUri);
- }
- else
- {
- throw;
- }
+ Process.Start("xdg-open", uri.AbsoluteUri);
}
}
}
diff --git a/src/GSS.Authorization.OAuth/OAuthOptions.cs b/src/GSS.Authorization.OAuth/OAuthOptions.cs
index 541df2f..2c40d18 100644
--- a/src/GSS.Authorization.OAuth/OAuthOptions.cs
+++ b/src/GSS.Authorization.OAuth/OAuthOptions.cs
@@ -7,7 +7,7 @@ namespace GSS.Authorization.OAuth
{
public class OAuthOptions
{
- private static readonly RNGCryptoServiceProvider _rngCrypto = new RNGCryptoServiceProvider();
+ private static readonly RandomNumberGenerator _randomNumberGenerator = RandomNumberGenerator.Create();
[Required]
public OAuthCredential ClientCredentials { get; set; }
@@ -16,7 +16,7 @@ public class OAuthOptions
public Func NonceProvider { get; set; } = () =>
{
var bytes = new byte[16];
- _rngCrypto.GetNonZeroBytes(bytes);
+ _randomNumberGenerator.GetNonZeroBytes(bytes);
return Convert.ToBase64String(bytes);
};
diff --git a/src/GSS.Authorization.OAuth2.HttpClient/GSS.Authorization.OAuth2.HttpClient.csproj b/src/GSS.Authorization.OAuth2.HttpClient/GSS.Authorization.OAuth2.HttpClient.csproj
index 9d95fcb..e770825 100644
--- a/src/GSS.Authorization.OAuth2.HttpClient/GSS.Authorization.OAuth2.HttpClient.csproj
+++ b/src/GSS.Authorization.OAuth2.HttpClient/GSS.Authorization.OAuth2.HttpClient.csproj
@@ -1,7 +1,7 @@
- netstandard2.0;netcoreapp3.1;net5.0
+ netstandard2.0;netcoreapp3.1;net5.0;net6.0
OAuth 2.0 authorized HttpClient, friendly with HttpClientFactory
OAuth;OAuth2;HttpClient;HttpHandler
GSS.Authorization.OAuth2
@@ -30,4 +30,9 @@
+
+
+
+
+
diff --git a/src/GSS.Authorization.OAuth2.HttpClient/OAuth2HttpHandler.cs b/src/GSS.Authorization.OAuth2.HttpClient/OAuth2HttpHandler.cs
index b92a573..1dc401d 100644
--- a/src/GSS.Authorization.OAuth2.HttpClient/OAuth2HttpHandler.cs
+++ b/src/GSS.Authorization.OAuth2.HttpClient/OAuth2HttpHandler.cs
@@ -11,7 +11,7 @@ namespace GSS.Authorization.OAuth2
{
public class OAuth2HttpHandler : DelegatingHandler
{
- private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
+ private readonly SemaphoreSlim _semaphore = new(1, 1);
private readonly IAuthorizer _authorizer;
private readonly IMemoryCache _memoryCache;
private readonly string _cacheKey;
diff --git a/src/GSS.Authorization.OAuth2/AccessToken.cs b/src/GSS.Authorization.OAuth2/AccessToken.cs
index fa3c8cb..c482a9a 100644
--- a/src/GSS.Authorization.OAuth2/AccessToken.cs
+++ b/src/GSS.Authorization.OAuth2/AccessToken.cs
@@ -5,7 +5,7 @@ namespace GSS.Authorization.OAuth2
{
public class AccessToken
{
- public static readonly AccessToken Empty = new AccessToken();
+ public static readonly AccessToken Empty = new();
[JsonPropertyName("access_token")]
public string Token { get; set; } = default!;
diff --git a/src/GSS.Authorization.OAuth2/GSS.Authorization.OAuth2.csproj b/src/GSS.Authorization.OAuth2/GSS.Authorization.OAuth2.csproj
index 100bbe9..c835839 100644
--- a/src/GSS.Authorization.OAuth2/GSS.Authorization.OAuth2.csproj
+++ b/src/GSS.Authorization.OAuth2/GSS.Authorization.OAuth2.csproj
@@ -8,7 +8,7 @@
-
+
diff --git a/test/Directory.Build.props b/test/Directory.Build.props
index 03895e0..10e8685 100644
--- a/test/Directory.Build.props
+++ b/test/Directory.Build.props
@@ -3,6 +3,8 @@
+ enable
+ enable
false
diff --git a/test/GSS.Authorization.OAuth.HttpClient.Tests/GSS.Authorization.OAuth.HttpClient.Tests.csproj b/test/GSS.Authorization.OAuth.HttpClient.Tests/GSS.Authorization.OAuth.HttpClient.Tests.csproj
index 49ae4f2..c5a4a9f 100644
--- a/test/GSS.Authorization.OAuth.HttpClient.Tests/GSS.Authorization.OAuth.HttpClient.Tests.csproj
+++ b/test/GSS.Authorization.OAuth.HttpClient.Tests/GSS.Authorization.OAuth.HttpClient.Tests.csproj
@@ -1,7 +1,7 @@
- net5.0;netcoreapp3.1
+ net6.0;netcoreapp3.1
diff --git a/test/GSS.Authorization.OAuth.HttpClient.Tests/OAuthHttpClientTests.cs b/test/GSS.Authorization.OAuth.HttpClient.Tests/OAuthHttpClientTests.cs
index dcc5187..5ffd24a 100644
--- a/test/GSS.Authorization.OAuth.HttpClient.Tests/OAuthHttpClientTests.cs
+++ b/test/GSS.Authorization.OAuth.HttpClient.Tests/OAuthHttpClientTests.cs
@@ -1,11 +1,6 @@
-using System;
-using System.Collections.Generic;
using System.Globalization;
-using System.Linq;
using System.Net;
-using System.Net.Http;
using System.Security.Cryptography;
-using System.Threading.Tasks;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
@@ -18,8 +13,9 @@ namespace GSS.Authorization.OAuth.HttpClient.Tests
{
public class OAuthHttpClientTests : IClassFixture
{
- private static readonly RNGCryptoServiceProvider _rngCrypto = new RNGCryptoServiceProvider();
- private readonly MockHttpMessageHandler _mockHttp;
+ private static readonly RandomNumberGenerator _randomNumberGenerator = RandomNumberGenerator.Create();
+
+ private readonly MockHttpMessageHandler? _mockHttp;
private readonly IRequestSigner _signer = new HmacSha1RequestSigner();
private readonly IConfiguration _configuration;
private readonly OAuthCredential _tokenCredentials;
@@ -57,7 +53,7 @@ public async Task HttpClient_AccessProtectedResourceWithAuthorizationHeader_Shou
handlerOptions.NonceProvider = () => nonce;
}
})
- .ConfigurePrimaryHttpMessageHandler(_ => (HttpMessageHandler)_mockHttp ?? new HttpClientHandler())
+ .ConfigurePrimaryHttpMessageHandler(_ => _mockHttp ?? new HttpClientHandler() as HttpMessageHandler)
.Services.BuildServiceProvider();
var client = services.GetRequiredService();
var options = services.GetRequiredService>();
@@ -98,12 +94,12 @@ public async Task HttpClient_AccessProtectedResourceWithQueryString_ShouldAuthor
handlerOptions.NonceProvider = () => nonce;
}
})
- .ConfigurePrimaryHttpMessageHandler(_ => (HttpMessageHandler)_mockHttp ?? new HttpClientHandler())
+ .ConfigurePrimaryHttpMessageHandler(_ => _mockHttp ?? new HttpClientHandler() as HttpMessageHandler)
.Services.BuildServiceProvider();
var client = services.GetRequiredService();
var options = services.GetRequiredService>();
var resourceUri = new UriBuilder(_configuration["Request:Uri"]);
- resourceUri.Query += resourceUri.Query.Contains("?", StringComparison.Ordinal)
+ resourceUri.Query += resourceUri.Query.Contains('?', StringComparison.Ordinal)
? "&foo=v1&foo=v2"
: "?foo=v1&foo=v2";
var parameters = _signer.AppendAuthorizationParameters(HttpMethod.Get, resourceUri.Uri,
@@ -151,13 +147,13 @@ public async Task HttpClient_AccessProtectedResourceWithFormBody_ShouldAuthorize
handlerOptions.NonceProvider = () => nonce;
}
})
- .ConfigurePrimaryHttpMessageHandler(_ => (HttpMessageHandler)_mockHttp ?? new HttpClientHandler())
+ .ConfigurePrimaryHttpMessageHandler(_ => _mockHttp ?? new HttpClientHandler() as HttpMessageHandler)
.Services.BuildServiceProvider();
var client = services.GetRequiredService();
var options = services.GetRequiredService>();
var resourceUri = new UriBuilder(_configuration["Request:Uri"]);
var queryString = QueryHelpers.ParseQuery(resourceUri.Uri.Query);
- var body = _configuration.GetSection("Request:Body").Get>();
+ var body = _configuration.GetSection("Request:Body").Get>();
var formData = new Dictionary();
foreach (var (key, value) in body)
{
@@ -179,7 +175,7 @@ public async Task HttpClient_AccessProtectedResourceWithFormBody_ShouldAuthorize
{
if (!queryString.ContainsKey(parameter.Key))
{
- values.AddRange(parameter.Value.Select(value=> new KeyValuePair(parameter.Key, value)));
+ values.AddRange(parameter.Value.Select(value => new KeyValuePair(parameter.Key, value)));
}
}
@@ -197,10 +193,10 @@ public async Task HttpClient_AccessProtectedResourceWithFormBody_ShouldAuthorize
_mockHttp?.VerifyNoOutstandingRequest();
}
- private string generateNonce()
+ private static string generateNonce()
{
var bytes = new byte[16];
- _rngCrypto.GetNonZeroBytes(bytes);
+ _randomNumberGenerator.GetNonZeroBytes(bytes);
return Convert.ToBase64String(bytes);
}
}
diff --git a/test/GSS.Authorization.OAuth.HttpClient.Tests/ServiceCollectionExtensionsTests.cs b/test/GSS.Authorization.OAuth.HttpClient.Tests/ServiceCollectionExtensionsTests.cs
index 78c3744..4adf18a 100644
--- a/test/GSS.Authorization.OAuth.HttpClient.Tests/ServiceCollectionExtensionsTests.cs
+++ b/test/GSS.Authorization.OAuth.HttpClient.Tests/ServiceCollectionExtensionsTests.cs
@@ -1,5 +1,3 @@
-using System;
-using System.Net.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Http;
using Microsoft.Extensions.Options;
@@ -17,7 +15,9 @@ public void AddOAuthHttpClient_WithoutConfigureOptions_ShouldThrows()
var collection = new ServiceCollection();
// Act & Assert
+#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
Assert.Throws(() => collection.AddOAuthHttpClient(null));
+#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type.
}
[Fact]
@@ -53,10 +53,9 @@ public void AddOAuthHttpClient_WithoutClientSecret_ShouldThrowsOnAccessOptionVal
{
// Arrange
var collection = new ServiceCollection();
- var services = collection.AddOAuthHttpClient((_, options) =>
- {
- options.ClientCredentials = new OAuthCredential("foo", null);
- }).Services.BuildServiceProvider();
+#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
+ var services = collection.AddOAuthHttpClient((_, options) => options.ClientCredentials = new OAuthCredential("foo", null)).Services.BuildServiceProvider();
+#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type.
// Act
var ex = Assert.Throws(() => services.GetRequiredService>().Value);
@@ -73,7 +72,9 @@ public void AddOAuthHttpClient_WithoutTokenId_ShouldThrowsOnAccessOptionValue()
var services = collection.AddOAuthHttpClient((_, options) =>
{
options.ClientCredentials = new OAuthCredential("foo", "bar");
+#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
options.TokenCredentials = new OAuthCredential(null, "bar");
+#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type.
}).Services.BuildServiceProvider();
// Act
@@ -91,7 +92,9 @@ public void AddOAuthHttpClient_WithoutTokenSecret_ShouldThrowsOnAccessOptionValu
var services = collection.AddOAuthHttpClient((_, options) =>
{
options.ClientCredentials = new OAuthCredential("foo", "bar");
+#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
options.TokenCredentials = new OAuthCredential("foo", null);
+#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type.
}).Services.BuildServiceProvider();
// Act
@@ -136,10 +139,10 @@ public void AddOAuthHttpClient_WithValidConfigureOptions_ShouldAddInServiceProvi
// Assert
Assert.NotNull(client);
}
-
+
[Fact]
public void AddOAuthHttpClient_WithGenericConfigurePrimaryHttpMessageHandler_ShouldAddInHttpMessageHandlerBuilderActions()
- {
+ {
// Arrange
var mockHttp = new MockHttpMessageHandler();
var collection = new ServiceCollection();
@@ -151,10 +154,10 @@ public void AddOAuthHttpClient_WithGenericConfigurePrimaryHttpMessageHandler_Sho
options.TokenCredentials = new OAuthCredential("foo", "bar");
}).ConfigurePrimaryHttpMessageHandler();
var services = builder.Services.BuildServiceProvider();
-
+
// Act
var optionsMonitor = services.GetRequiredService>();
-
+
// Assert
var httpClientFactoryOptions = optionsMonitor.Get(builder.Name);
Assert.Contains(httpClientFactoryOptions.HttpMessageHandlerBuilderActions, x => x.Target?.ToString()?.Contains("MockHttpMessageHandler") == true);
@@ -212,7 +215,7 @@ public void AddTypedOAuthHttpClient_WithValidConfigureOptions_ShouldAddInService
private class DemoOptions : OAuthHttpHandlerOptions
{
- public Uri BaseAddress { get; set; }
+ public Uri BaseAddress { get; set; } = default!;
}
[Fact]
diff --git a/test/GSS.Authorization.OAuth.HttpClient.Tests/appsettings.json b/test/GSS.Authorization.OAuth.HttpClient.Tests/appsettings.json
index 6ce7bd9..529ec30 100644
--- a/test/GSS.Authorization.OAuth.HttpClient.Tests/appsettings.json
+++ b/test/GSS.Authorization.OAuth.HttpClient.Tests/appsettings.json
@@ -3,11 +3,8 @@
"Mock": true
},
"Logging": {
- "IncludeScopes": false,
"LogLevel": {
- "Default": "Debug",
- "System": "Information",
- "Microsoft": "Information"
+ "Default": "Information"
}
},
"OAuth": {
diff --git a/test/GSS.Authorization.OAuth.Tests/AuthorizerTests.cs b/test/GSS.Authorization.OAuth.Tests/AuthorizerTests.cs
index 286bb5f..68563bb 100644
--- a/test/GSS.Authorization.OAuth.Tests/AuthorizerTests.cs
+++ b/test/GSS.Authorization.OAuth.Tests/AuthorizerTests.cs
@@ -1,8 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Net.Http;
using System.Text;
-using System.Threading.Tasks;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;
@@ -14,7 +10,7 @@ namespace GSS.Authorization.OAuth.Tests
// see https://tools.ietf.org/html/rfc5849#section-1.2
public class AuthorizerTests
{
- private readonly AuthorizerOptions _options = new AuthorizerOptions
+ private readonly AuthorizerOptions _options = new()
{
ClientCredentials = new OAuthCredential("dpf43f3p2l4k3l03", "kd94hf93k423kf44"),
TemporaryCredentialRequestUri = new Uri("https://photos.example.net/initiate"),
@@ -25,7 +21,7 @@ public class AuthorizerTests
ProvideVersion = false
};
- private readonly MockHttpMessageHandler _mockHttp = new MockHttpMessageHandler();
+ private readonly MockHttpMessageHandler _mockHttp = new();
private readonly IRequestSigner _signer = new HmacSha1RequestSigner();
[Fact]
@@ -67,7 +63,7 @@ public async Task GetTemporaryCredentialAsync()
public async Task GetVerificationCodeAsync()
{
// Arrange
- var expected = "hfdp7dh39dks9884";
+ const string expected = "hfdp7dh39dks9884";
var authorizeHtml = $@"