diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
index fb6d48c..4ec4f2e 100644
--- a/.github/workflows/dotnet.yml
+++ b/.github/workflows/dotnet.yml
@@ -16,20 +16,11 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- - uses: actions/checkout@v2
- - name: Setup .NET Core 3.1
- uses: actions/setup-dotnet@v1
+ - uses: actions/checkout@v4
+ - name: Setup .NET 10
+ uses: actions/setup-dotnet@v4
with:
- dotnet-version: '3.1.x'
- - name: Setup .NET 5.0
- uses: actions/setup-dotnet@v1
- with:
- dotnet-version: '5.0.x'
- - name: Fix Windows VM bug
- shell: bash
- if: matrix.os == 'windows-latest'
- run: |
- dotnet nuget locals all --clear
+ dotnet-version: '10.0.x'
- name: Restore
run: dotnet restore
- name: Build
@@ -41,7 +32,7 @@ jobs:
run: dotnet pack -c Release
- name: upload artifact
if: matrix.os == 'ubuntu-latest'
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v4
with:
name: nupkg
path: '**/*.nupkg'
diff --git a/README.md b/README.md
index d29df3d..8b0805b 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# OAuth Token Exchange (RFC 8693) for IdentityServer
-An implementation of OAuth token exchange ([RFC 8693](https://www.rfc-editor.org/rfc/rfc8693.html)) for IdentityServer4 and Duende IdentityServer. This implementation provides the required abstractions for token exchange with extensibility points to implement your own authorization rules, with default implementation covering an API to API scenario.
+An implementation of OAuth token exchange ([RFC 8693](https://www.rfc-editor.org/rfc/rfc8693.html)) for [Open.IdentityServer](https://github.com/RockSolidKnowledge/Open.IdentityServer) and Duende IdentityServer. This implementation provides the required abstractions for token exchange with extensibility points to implement your own authorization rules, with default implementation covering an API to API scenario.
This library includes:
@@ -13,10 +13,11 @@ To learn more about token exchange and why it is useful for microservices and AP
## Installation
-This library is available as a nuget package for both IdentityServer4 and Duende IdentityServer.
+This library is available as a nuget package for both Open.IdentityServer and Duende IdentityServer.
+- [Rsk.TokenExchange.Open.IdentityServer](https://www.nuget.org/packages/Rsk.TokenExchange.Open.IdentityServer/)
- [Rsk.TokenExchange.DuendeIdentityServer](https://www.nuget.org/packages/Rsk.TokenExchange.DuendeIdentityServer/)
-- [Rsk.TokenExchange.IdentityServer4](https://www.nuget.org/packages/Rsk.TokenExchange.IdentityServer4/)
+
Once you have installed the correct nuget package, you can enable the token exchange grant type by using the `AddTokenExchange` extension on `IdentityServerBuilder`.
diff --git a/Rsk.TokenExchange.sln b/Rsk.TokenExchange.sln
index 65e6bcc..aa7b710 100644
--- a/Rsk.TokenExchange.sln
+++ b/Rsk.TokenExchange.sln
@@ -13,9 +13,9 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rsk.TokenExchange.Tests", "
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rsk.TokenExchange.Tests.Integration", "test\Rsk.TokenExchange.Tests.Integration\Rsk.TokenExchange.Tests.Integration.csproj", "{98215ED6-5DE9-42AD-BF08-176833F1F22C}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rsk.TokenExchange.IdentityServer4", "src\Rsk.TokenExchange.IdentityServer4\Rsk.TokenExchange.IdentityServer4.csproj", "{D41B4200-C0A6-488A-9FC5-C0AD075A8228}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rsk.TokenExchange.Open.IdentityServer", "src\Rsk.TokenExchange.Open.IdentityServer\Rsk.TokenExchange.Open.IdentityServer.csproj", "{D41B4200-C0A6-488A-9FC5-C0AD075A8228}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rsk.TokenExchange.IdentityServer4.Tests", "test\Rsk.TokenExchange.IdentityServer4.Tests\Rsk.TokenExchange.IdentityServer4.Tests.csproj", "{3B3A599B-0B55-4146-A96D-A6A4E1DC1E77}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rsk.TokenExchange.Open.IdentityServer.Tests", "test\Rsk.TokenExchange.Open.IdentityServer.Tests\Rsk.TokenExchange.Open.IdentityServer.Tests.csproj", "{3B3A599B-0B55-4146-A96D-A6A4E1DC1E77}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rsk.TokenExchange.DuendeIdentityServer", "src\Rsk.TokenExchange.DuendeIdentityServer\Rsk.TokenExchange.DuendeIdentityServer.csproj", "{4F826FC4-8C6B-43A0-9EB3-031400C01427}"
EndProject
diff --git a/src/Rsk.TokenExchange.DuendeIdentityServer/IdentityServerSubjectTokenValidator.cs b/src/Rsk.TokenExchange.DuendeIdentityServer/IdentityServerSubjectTokenValidator.cs
index 74fab99..65a925b 100644
--- a/src/Rsk.TokenExchange.DuendeIdentityServer/IdentityServerSubjectTokenValidator.cs
+++ b/src/Rsk.TokenExchange.DuendeIdentityServer/IdentityServerSubjectTokenValidator.cs
@@ -1,3 +1,4 @@
+using System.Threading;
using System.Threading.Tasks;
using Duende.IdentityServer.Validation;
using Rsk.TokenExchange.Validators.Adaptors;
@@ -24,7 +25,7 @@ public IdentityServerSubjectTokenValidator(ITokenValidator tokenValidator)
///
public async Task ValidateAccessToken(string token)
{
- var result = await tokenValidator.ValidateAccessTokenAsync(token);
+ var result = await tokenValidator.ValidateAccessTokenAsync(token, expectedScope: null, CancellationToken.None);
return new TokenValidationResult(result.IsError, result.Claims);
}
}
diff --git a/src/Rsk.TokenExchange.DuendeIdentityServer/Rsk.TokenExchange.DuendeIdentityServer.csproj b/src/Rsk.TokenExchange.DuendeIdentityServer/Rsk.TokenExchange.DuendeIdentityServer.csproj
index 11fa972..cebd707 100644
--- a/src/Rsk.TokenExchange.DuendeIdentityServer/Rsk.TokenExchange.DuendeIdentityServer.csproj
+++ b/src/Rsk.TokenExchange.DuendeIdentityServer/Rsk.TokenExchange.DuendeIdentityServer.csproj
@@ -1,7 +1,7 @@
- netcoreapp3.1;net5.0
+ net10.0
Rock Solid Knowledge Ltd
Token Exchange (RFC 8693) implementation for Deunde IdentityServer.
https://github.com/RockSolidKnowledge/TokenExchange
@@ -15,7 +15,7 @@
-
+
diff --git a/src/Rsk.TokenExchange.DuendeIdentityServer/TokenExchangeExtensionGrantValidator.cs b/src/Rsk.TokenExchange.DuendeIdentityServer/TokenExchangeExtensionGrantValidator.cs
index e01a4bf..dfa27c1 100644
--- a/src/Rsk.TokenExchange.DuendeIdentityServer/TokenExchangeExtensionGrantValidator.cs
+++ b/src/Rsk.TokenExchange.DuendeIdentityServer/TokenExchangeExtensionGrantValidator.cs
@@ -2,10 +2,11 @@
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
+using System.Threading;
using System.Threading.Tasks;
+using Duende.IdentityModel;
using Duende.IdentityServer.Models;
using Duende.IdentityServer.Validation;
-using IdentityModel;
using Microsoft.Extensions.Logging;
using Rsk.TokenExchange.Exceptions;
using Rsk.TokenExchange.Validators;
@@ -46,10 +47,15 @@ public TokenExchangeExtensionGrantValidator(
public string GrantType => TokenExchangeConstants.GrantType;
///
- public async Task ValidateAsync(ExtensionGrantValidationContext context)
+ public async Task ValidateAsync(ExtensionGrantValidationContext context, CancellationToken cancellationToken = default)
{
+ ArgumentNullException.ThrowIfNull(context);
+
// warn on no client auth
- if (context.Request.Secret == null) logger.LogInformation("Recieved unauthenticated token exchange request");
+ if (context.Request.Secret == null)
+ {
+ logger.LogInformation("Received unauthenticated token exchange request");
+ }
// parse request
ITokenExchangeRequest tokenExchangeRequest;
@@ -105,15 +111,14 @@ public async Task ValidateAsync(ExtensionGrantValidationContext context)
///
public virtual void UpdateRequest(ValidatedTokenRequest request, IEnumerable claims)
{
- if (request == null) throw new ArgumentNullException(nameof(request));
- if (claims == null) throw new ArgumentNullException(nameof(claims));
+ ArgumentNullException.ThrowIfNull(request);
+ ArgumentNullException.ThrowIfNull(claims);
// update client_id to act as original client app
var clientId = claims.First(x => x.Type == JwtClaimTypes.ClientId).Value;
request.ClientId = clientId;
}
- private static readonly Dictionary CustomResponseParameters = new Dictionary
- {{TokenExchangeConstants.ResponseParameters.IssuedTokenType, TokenExchangeConstants.TokenTypes.AccessToken}};
+ private static readonly Dictionary CustomResponseParameters = new() {{TokenExchangeConstants.ResponseParameters.IssuedTokenType, TokenExchangeConstants.TokenTypes.AccessToken}};
}
}
\ No newline at end of file
diff --git a/src/Rsk.TokenExchange.IdentityServer4/IdentityServerBuilderExtensions.cs b/src/Rsk.TokenExchange.Open.IdentityServer/IdentityServerBuilderExtensions.cs
similarity index 86%
rename from src/Rsk.TokenExchange.IdentityServer4/IdentityServerBuilderExtensions.cs
rename to src/Rsk.TokenExchange.Open.IdentityServer/IdentityServerBuilderExtensions.cs
index 2073ee5..7cbf22c 100644
--- a/src/Rsk.TokenExchange.IdentityServer4/IdentityServerBuilderExtensions.cs
+++ b/src/Rsk.TokenExchange.Open.IdentityServer/IdentityServerBuilderExtensions.cs
@@ -2,7 +2,7 @@
using Rsk.TokenExchange.Configuration;
using Rsk.TokenExchange.Validators.Adaptors;
-namespace Rsk.TokenExchange.IdentityServer4
+namespace Rsk.TokenExchange.Open.IdentityServer
{
///
/// Token exchange registrations for IIdentityServerBuilder
@@ -10,7 +10,7 @@ namespace Rsk.TokenExchange.IdentityServer4
public static class IdentityServerBuilderExtensions
{
///
- /// Adds the default token exchange registrations for IdentityServer4.
+ /// Adds the default token exchange registrations for Open.IdentityServer.
/// Uses the default authorization policy, designed for token exchange between microservices.
///
public static IIdentityServerBuilder AddTokenExchange(this IIdentityServerBuilder builder)
diff --git a/src/Rsk.TokenExchange.IdentityServer4/IdentityServerSubjectTokenValidator.cs b/src/Rsk.TokenExchange.Open.IdentityServer/IdentityServerSubjectTokenValidator.cs
similarity index 86%
rename from src/Rsk.TokenExchange.IdentityServer4/IdentityServerSubjectTokenValidator.cs
rename to src/Rsk.TokenExchange.Open.IdentityServer/IdentityServerSubjectTokenValidator.cs
index b3e525a..388f924 100644
--- a/src/Rsk.TokenExchange.IdentityServer4/IdentityServerSubjectTokenValidator.cs
+++ b/src/Rsk.TokenExchange.Open.IdentityServer/IdentityServerSubjectTokenValidator.cs
@@ -1,12 +1,12 @@
using System.Threading.Tasks;
-using IdentityServer4.Validation;
+using Open.IdentityServer.Validation;
using Rsk.TokenExchange.Validators.Adaptors;
using TokenValidationResult = Rsk.TokenExchange.Validators.Adaptors.TokenValidationResult;
-namespace Rsk.TokenExchange.IdentityServer4
+namespace Rsk.TokenExchange.Open.IdentityServer
{
///
- /// Wrapper around IdentityServer4's ITokenValidator
+ /// Wrapper around Open.IdentityServer's ITokenValidator
///
public class IdentityServerSubjectTokenValidator : ITokenValidatorAdaptor
{
diff --git a/src/Rsk.TokenExchange.IdentityServer4/Rsk.TokenExchange.IdentityServer4.csproj b/src/Rsk.TokenExchange.Open.IdentityServer/Rsk.TokenExchange.Open.IdentityServer.csproj
similarity index 79%
rename from src/Rsk.TokenExchange.IdentityServer4/Rsk.TokenExchange.IdentityServer4.csproj
rename to src/Rsk.TokenExchange.Open.IdentityServer/Rsk.TokenExchange.Open.IdentityServer.csproj
index 7b1553a..9ea3ed5 100644
--- a/src/Rsk.TokenExchange.IdentityServer4/Rsk.TokenExchange.IdentityServer4.csproj
+++ b/src/Rsk.TokenExchange.Open.IdentityServer/Rsk.TokenExchange.Open.IdentityServer.csproj
@@ -1,21 +1,22 @@
- netcoreapp3.1
+ net10.0
Rock Solid Knowledge Ltd
- Token Exchange (RFC 8693) implementation for IdentityServer4.
+ Token Exchange (RFC 8693) implementation for Open.IdentityServer.
https://github.com/RockSolidKnowledge/TokenExchange
https://github.com/RockSolidKnowledge/TokenExchange/releases
Copyright 2021 (c) Rock Solid Knowledge Ltd. All rights reserved.
- IdentityServer OAuth Token Exchange IdentityServer4
+ IdentityServer OAuth Token Exchange IdentityServer4 Open.IdentityServer
true
icon.png
Apache-2.0
true
+ Rsk.TokenExchange.Open.IdentityServer
-
+
diff --git a/src/Rsk.TokenExchange.IdentityServer4/TokenExchangeExtensionGrantValidator.cs b/src/Rsk.TokenExchange.Open.IdentityServer/TokenExchangeExtensionGrantValidator.cs
similarity index 87%
rename from src/Rsk.TokenExchange.IdentityServer4/TokenExchangeExtensionGrantValidator.cs
rename to src/Rsk.TokenExchange.Open.IdentityServer/TokenExchangeExtensionGrantValidator.cs
index 941e678..c42d8a5 100644
--- a/src/Rsk.TokenExchange.IdentityServer4/TokenExchangeExtensionGrantValidator.cs
+++ b/src/Rsk.TokenExchange.Open.IdentityServer/TokenExchangeExtensionGrantValidator.cs
@@ -3,14 +3,14 @@
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
-using IdentityModel;
-using IdentityServer4.Models;
-using IdentityServer4.Validation;
+using Open.IdentityServer.Models;
+using Open.IdentityServer.Validation;
using Microsoft.Extensions.Logging;
+using Open.IdentityServer;
using Rsk.TokenExchange.Exceptions;
using Rsk.TokenExchange.Validators;
-namespace Rsk.TokenExchange.IdentityServer4
+namespace Rsk.TokenExchange.Open.IdentityServer
{
///
/// Extension grant validator for OAuth Token Exchange (RFC 8693).
@@ -48,8 +48,16 @@ public TokenExchangeExtensionGrantValidator(
///
public async Task ValidateAsync(ExtensionGrantValidationContext context)
{
+ if (context == null)
+ {
+ throw new ArgumentNullException(nameof(context));
+ }
+
// warn on no client auth
- if (context.Request.Secret == null) logger.LogInformation("Recieved unauthenticated token exchange request");
+ if (context.Request.Secret == null)
+ {
+ logger.LogInformation("Received unauthenticated token exchange request");
+ }
// parse request
ITokenExchangeRequest tokenExchangeRequest;
@@ -105,15 +113,14 @@ public async Task ValidateAsync(ExtensionGrantValidationContext context)
///
public virtual void UpdateRequest(ValidatedTokenRequest request, IEnumerable claims)
{
- if (request == null) throw new ArgumentNullException(nameof(request));
- if (claims == null) throw new ArgumentNullException(nameof(claims));
+ ArgumentNullException.ThrowIfNull(request);
+ ArgumentNullException.ThrowIfNull(claims);
// update client_id to act as original client app
var clientId = claims.First(x => x.Type == JwtClaimTypes.ClientId).Value;
request.ClientId = clientId;
}
- private static readonly Dictionary CustomResponseParameters = new Dictionary
- {{TokenExchangeConstants.ResponseParameters.IssuedTokenType, TokenExchangeConstants.TokenTypes.AccessToken}};
+ private static readonly Dictionary CustomResponseParameters = new() {{TokenExchangeConstants.ResponseParameters.IssuedTokenType, TokenExchangeConstants.TokenTypes.AccessToken}};
}
}
\ No newline at end of file
diff --git a/src/Rsk.TokenExchange/Exceptions/ClaimsParsingException.cs b/src/Rsk.TokenExchange/Exceptions/ClaimsParsingException.cs
index 874322c..923c8d9 100644
--- a/src/Rsk.TokenExchange/Exceptions/ClaimsParsingException.cs
+++ b/src/Rsk.TokenExchange/Exceptions/ClaimsParsingException.cs
@@ -16,8 +16,5 @@ public SubjectParsingException(string message) : base(message) { }
///
public SubjectParsingException(string message, Exception inner) : base(message, inner) { }
-
- ///
- protected SubjectParsingException(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
}
\ No newline at end of file
diff --git a/src/Rsk.TokenExchange/Exceptions/InvalidRequestException.cs b/src/Rsk.TokenExchange/Exceptions/InvalidRequestException.cs
index 3469db2..9d7d2c5 100644
--- a/src/Rsk.TokenExchange/Exceptions/InvalidRequestException.cs
+++ b/src/Rsk.TokenExchange/Exceptions/InvalidRequestException.cs
@@ -17,8 +17,5 @@ public InvalidRequestException(string message) : base(message) { }
///
public InvalidRequestException(string message, Exception inner) : base(message, inner) { }
-
- ///
- protected InvalidRequestException(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
}
\ No newline at end of file
diff --git a/src/Rsk.TokenExchange/Exceptions/TokenExchangeException.cs b/src/Rsk.TokenExchange/Exceptions/TokenExchangeException.cs
index c77f5d9..f2efdd1 100644
--- a/src/Rsk.TokenExchange/Exceptions/TokenExchangeException.cs
+++ b/src/Rsk.TokenExchange/Exceptions/TokenExchangeException.cs
@@ -17,8 +17,5 @@ public TokenExchangeException(string message) : base(message) { }
///
public TokenExchangeException(string message, Exception inner) : base(message, inner) { }
-
- ///
- protected TokenExchangeException(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
}
\ No newline at end of file
diff --git a/src/Rsk.TokenExchange/Models/Actor.cs b/src/Rsk.TokenExchange/Models/Actor.cs
index 5e8c352..a8ee10e 100644
--- a/src/Rsk.TokenExchange/Models/Actor.cs
+++ b/src/Rsk.TokenExchange/Models/Actor.cs
@@ -1,4 +1,4 @@
-using Newtonsoft.Json;
+using System.Text.Json.Serialization;
namespace Rsk.TokenExchange
{
@@ -12,21 +12,21 @@ public class Actor
/// The original issuer (iss) of exchanged token.
/// Useful for cross-tenant/identity provider token exchange.
///
- [JsonProperty("iss")]
+ [JsonPropertyName("iss")]
public string Issuer { get; set; }
///
/// The original client ID (client_id) of the exchanged token.
/// Useful for tracking who originally requested the exchanged token.
///
- [JsonProperty("client_id")]
+ [JsonPropertyName("client_id")]
public string ClientId { get; set; }
///
/// The inner actor claim.
/// Useful for multiple token exchange requests.
///
- [JsonProperty("act")]
+ [JsonPropertyName("act")]
public string InnerActor { get; set; }
}
diff --git a/src/Rsk.TokenExchange/Models/TokenExchangeRequest.cs b/src/Rsk.TokenExchange/Models/TokenExchangeRequest.cs
index 78bb3a5..99f7760 100644
--- a/src/Rsk.TokenExchange/Models/TokenExchangeRequest.cs
+++ b/src/Rsk.TokenExchange/Models/TokenExchangeRequest.cs
@@ -17,9 +17,13 @@ public class TokenExchangeRequest : ITokenExchangeRequest
/// Throw on missing grant_type, subject_token, and subject_token_type.
public TokenExchangeRequest(string clientId, NameValueCollection request)
{
- if (string.IsNullOrWhiteSpace(clientId)) throw new ArgumentNullException(nameof(clientId));
- if (request == null) throw new ArgumentNullException(nameof(request));
-
+ if (string.IsNullOrWhiteSpace(clientId))
+ {
+ throw new ArgumentNullException(nameof(clientId));
+ }
+
+ ArgumentNullException.ThrowIfNull(request);
+
ClientId = clientId;
// grant type must be urn:ietf:params:oauth:grant-type:token-exchange
diff --git a/src/Rsk.TokenExchange/Parsers/TokenExchangeClaimsParser.cs b/src/Rsk.TokenExchange/Parsers/TokenExchangeClaimsParser.cs
index 7a87d7b..c576c2b 100644
--- a/src/Rsk.TokenExchange/Parsers/TokenExchangeClaimsParser.cs
+++ b/src/Rsk.TokenExchange/Parsers/TokenExchangeClaimsParser.cs
@@ -2,9 +2,10 @@
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
+using System.Text.Json;
+using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Microsoft.IdentityModel.JsonWebTokens;
-using Newtonsoft.Json;
using Rsk.TokenExchange.Exceptions;
namespace Rsk.TokenExchange
@@ -17,10 +18,13 @@ public class TokenExchangeClaimsParser : ITokenExchangeClaimsParser
/// Throws when more than one subject claim is present in the subject token claims.
public virtual Task ParseSubject(IEnumerable subjectClaims, ITokenExchangeRequest request)
{
- if (subjectClaims == null) throw new ArgumentNullException(nameof(subjectClaims));
+ ArgumentNullException.ThrowIfNull(subjectClaims);
var subjectValues = subjectClaims.Where(x => x.Type == "sub").Select(x => x.Value).ToList();
- if (1 < subjectValues.Count) throw new SubjectParsingException("More than one subject claim present on token exchange request");
+ if (subjectValues.Count > 1)
+ {
+ throw new SubjectParsingException("More than one subject claim present on token exchange request");
+ }
return Task.FromResult(subjectValues.FirstOrDefault());
}
@@ -29,8 +33,8 @@ public virtual Task ParseSubject(IEnumerable subjectClaims, IToke
/// Returns the subject claims along with an actor claim when client_id != subject token client_id
public virtual Task> ParseClaims(IEnumerable subjectClaims, ITokenExchangeRequest request)
{
- if (subjectClaims == null) throw new ArgumentNullException(nameof(subjectClaims));
- if (request == null) throw new ArgumentNullException(nameof(request));
+ ArgumentNullException.ThrowIfNull(subjectClaims);
+ ArgumentNullException.ThrowIfNull(request);
var claims = subjectClaims.ToList();
@@ -43,7 +47,7 @@ public virtual Task> ParseClaims(IEnumerable subjectCl
var actor = new Actor {ClientId = request.ClientId, InnerActor = previousActor?.Value};
claims.Add(new Claim(
"act",
- JsonConvert.SerializeObject(actor, new JsonSerializerSettings {NullValueHandling = NullValueHandling.Ignore}),
+ JsonSerializer.Serialize(actor, new JsonSerializerOptions {DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull}),
JsonClaimValueTypes.Json));
}
diff --git a/src/Rsk.TokenExchange/Rsk.TokenExchange.csproj b/src/Rsk.TokenExchange/Rsk.TokenExchange.csproj
index 18e544e..c9f14d6 100644
--- a/src/Rsk.TokenExchange/Rsk.TokenExchange.csproj
+++ b/src/Rsk.TokenExchange/Rsk.TokenExchange.csproj
@@ -1,9 +1,9 @@
- netcoreapp3.1;net5.0
+ net10.0
Rock Solid Knowledge Ltd
- Token Exchange (RFC 8693) implementation for IdentityServer. This is the core library shared between the IdentityServer4 and Duende IdentityServer implementations.
+ Token Exchange (RFC 8693) implementation for IdentityServer. This is the core library shared between the Open.IdentityServer and Duende IdentityServer implementations.
https://github.com/RockSolidKnowledge/TokenExchange
https://github.com/RockSolidKnowledge/TokenExchange/releases
Copyright 2021 (c) Rock Solid Knowledge Ltd. All rights reserved.
@@ -14,17 +14,10 @@
true
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
diff --git a/src/Rsk.TokenExchange/Validators/DefaultSubjectTokenValidator.cs b/src/Rsk.TokenExchange/Validators/DefaultSubjectTokenValidator.cs
index 7a39bc7..aa632b4 100644
--- a/src/Rsk.TokenExchange/Validators/DefaultSubjectTokenValidator.cs
+++ b/src/Rsk.TokenExchange/Validators/DefaultSubjectTokenValidator.cs
@@ -26,8 +26,15 @@ public DefaultSubjectTokenValidator(ITokenValidatorAdaptor tokenValidator, ILogg
///
public async Task Validate(string token, string tokenType)
{
- if (string.IsNullOrWhiteSpace(token)) throw new ArgumentNullException(nameof(token));
- if (string.IsNullOrWhiteSpace(tokenType)) throw new ArgumentNullException(nameof(tokenType));
+ if (string.IsNullOrWhiteSpace(token))
+ {
+ throw new ArgumentNullException(nameof(token));
+ }
+
+ if (string.IsNullOrWhiteSpace(tokenType))
+ {
+ throw new ArgumentNullException(nameof(tokenType));
+ }
if (tokenType != TokenExchangeConstants.TokenTypes.AccessToken)
{
diff --git a/src/Rsk.TokenExchange/Validators/DefaultTokenExchangeRequestValidator.cs b/src/Rsk.TokenExchange/Validators/DefaultTokenExchangeRequestValidator.cs
index 634735f..16c4d02 100644
--- a/src/Rsk.TokenExchange/Validators/DefaultTokenExchangeRequestValidator.cs
+++ b/src/Rsk.TokenExchange/Validators/DefaultTokenExchangeRequestValidator.cs
@@ -23,7 +23,10 @@ public DefaultTokenExchangeRequestValidator(ISubjectTokenValidator subjectTokenV
///
public async Task Validate(ITokenExchangeRequest request)
{
- if (request == null) throw new ArgumentNullException(nameof(request));
+ if (request == null)
+ {
+ throw new ArgumentNullException(nameof(request));
+ }
// validate subject token is issued by IdentityServer
var result = await subjectTokenValidator.Validate(request.SubjectToken, request.SubjectTokenType);
diff --git a/test/Rsk.TokenExchange.DuendeIdentityServer.Tests/Rsk.TokenExchange.DuendeIdentityServer.Tests.csproj b/test/Rsk.TokenExchange.DuendeIdentityServer.Tests/Rsk.TokenExchange.DuendeIdentityServer.Tests.csproj
index 184cc0f..c5ba680 100644
--- a/test/Rsk.TokenExchange.DuendeIdentityServer.Tests/Rsk.TokenExchange.DuendeIdentityServer.Tests.csproj
+++ b/test/Rsk.TokenExchange.DuendeIdentityServer.Tests/Rsk.TokenExchange.DuendeIdentityServer.Tests.csproj
@@ -1,16 +1,16 @@
- netcoreapp3.1;net5.0
+ net10.0
false
-
-
-
-
-
+
+
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
diff --git a/test/Rsk.TokenExchange.DuendeIdentityServer.Tests/TokenExchangeExtensionGrantValidatorTests.cs b/test/Rsk.TokenExchange.DuendeIdentityServer.Tests/TokenExchangeExtensionGrantValidatorTests.cs
index 707456b..2e9ceee 100644
--- a/test/Rsk.TokenExchange.DuendeIdentityServer.Tests/TokenExchangeExtensionGrantValidatorTests.cs
+++ b/test/Rsk.TokenExchange.DuendeIdentityServer.Tests/TokenExchangeExtensionGrantValidatorTests.cs
@@ -18,12 +18,12 @@ namespace Rsk.TokenExchange.Tests.IdentityServer
{
public class TokenExchangeExtensionGrantValidatorTests
{
- private Mock mockParser = new Mock();
- private Mock mockRequestValidator = new Mock();
- private Mock mockClaimsParser = new Mock();
+ private Mock mockParser = new();
+ private Mock mockRequestValidator = new();
+ private Mock mockClaimsParser = new();
private ILogger logger = new NullLogger();
- private ExtensionGrantValidationContext context = new ExtensionGrantValidationContext
+ private ExtensionGrantValidationContext context = new()
{
Request = new ValidatedTokenRequest
{
@@ -33,7 +33,7 @@ public class TokenExchangeExtensionGrantValidatorTests
};
private TokenExchangeExtensionGrantValidator CreateSut()
- => new TokenExchangeExtensionGrantValidator(mockParser?.Object, mockRequestValidator?.Object, mockClaimsParser?.Object, logger);
+ => new(mockParser?.Object, mockRequestValidator?.Object, mockClaimsParser?.Object, logger);
private Mock CreateMockedSut()
{
@@ -83,8 +83,8 @@ public void GrantType_ExpectRfcGrantType()
}
[Fact]
- public void ValidateAsync_WhenContextIsNull_ExpectArgumentNullException()
- => Assert.ThrowsAsync(() => CreateMockedSut().Object.ValidateAsync(null));
+ public async Task ValidateAsync_WhenContextIsNull_ExpectArgumentNullException()
+ => await Assert.ThrowsAsync(() => CreateMockedSut().Object.ValidateAsync(null));
[Fact]
public async Task ValidateAsync_WhenParseRequestThrowsTokenExchangeException_ExpectFailureResult()
diff --git a/test/Rsk.TokenExchange.IdentityServer4.Tests/IdentityServerBuilderExtensionTests.cs b/test/Rsk.TokenExchange.Open.IdentityServer.Tests/IdentityServerBuilderExtensionTests.cs
similarity index 88%
rename from test/Rsk.TokenExchange.IdentityServer4.Tests/IdentityServerBuilderExtensionTests.cs
rename to test/Rsk.TokenExchange.Open.IdentityServer.Tests/IdentityServerBuilderExtensionTests.cs
index 35895fd..fdf6550 100644
--- a/test/Rsk.TokenExchange.IdentityServer4.Tests/IdentityServerBuilderExtensionTests.cs
+++ b/test/Rsk.TokenExchange.Open.IdentityServer.Tests/IdentityServerBuilderExtensionTests.cs
@@ -1,11 +1,11 @@
using System.Collections.Generic;
using FluentAssertions;
-using IdentityServer4.Models;
-using IdentityServer4.Validation;
using Microsoft.Extensions.DependencyInjection;
+using Open.IdentityServer.Models;
+using Open.IdentityServer.Validation;
using Xunit;
-namespace Rsk.TokenExchange.IdentityServer4.Tests
+namespace Rsk.TokenExchange.Open.IdentityServer.Tests
{
public class IdentityServerBuilderExtensionTests
{
diff --git a/test/Rsk.TokenExchange.IdentityServer4.Tests/Rsk.TokenExchange.IdentityServer4.Tests.csproj b/test/Rsk.TokenExchange.Open.IdentityServer.Tests/Rsk.TokenExchange.Open.IdentityServer.Tests.csproj
similarity index 50%
rename from test/Rsk.TokenExchange.IdentityServer4.Tests/Rsk.TokenExchange.IdentityServer4.Tests.csproj
rename to test/Rsk.TokenExchange.Open.IdentityServer.Tests/Rsk.TokenExchange.Open.IdentityServer.Tests.csproj
index a2dc157..74e4909 100644
--- a/test/Rsk.TokenExchange.IdentityServer4.Tests/Rsk.TokenExchange.IdentityServer4.Tests.csproj
+++ b/test/Rsk.TokenExchange.Open.IdentityServer.Tests/Rsk.TokenExchange.Open.IdentityServer.Tests.csproj
@@ -1,23 +1,24 @@
- netcoreapp3.1
+ net10.0
false
+ Rsk.TokenExchange.Open.IdentityServer.Tests
-
-
-
-
-
+
+
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
diff --git a/test/Rsk.TokenExchange.IdentityServer4.Tests/TokenExchangeExtensionGrantValidatorTests.cs b/test/Rsk.TokenExchange.Open.IdentityServer.Tests/TokenExchangeExtensionGrantValidatorTests.cs
similarity index 93%
rename from test/Rsk.TokenExchange.IdentityServer4.Tests/TokenExchangeExtensionGrantValidatorTests.cs
rename to test/Rsk.TokenExchange.Open.IdentityServer.Tests/TokenExchangeExtensionGrantValidatorTests.cs
index 4ed68c0..148ad8a 100644
--- a/test/Rsk.TokenExchange.IdentityServer4.Tests/TokenExchangeExtensionGrantValidatorTests.cs
+++ b/test/Rsk.TokenExchange.Open.IdentityServer.Tests/TokenExchangeExtensionGrantValidatorTests.cs
@@ -5,24 +5,24 @@
using System.Security.Claims;
using System.Threading.Tasks;
using FluentAssertions;
-using IdentityServer4.Validation;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Moq;
+using Open.IdentityServer.Validation;
using Rsk.TokenExchange.Exceptions;
using Rsk.TokenExchange.Validators;
using Xunit;
-namespace Rsk.TokenExchange.IdentityServer4.Tests
+namespace Rsk.TokenExchange.Open.IdentityServer.Tests
{
public class TokenExchangeExtensionGrantValidatorTests
{
- private Mock mockParser = new Mock();
- private Mock mockRequestValidator = new Mock();
- private Mock mockClaimsParser = new Mock();
+ private Mock mockParser = new();
+ private Mock mockRequestValidator = new();
+ private Mock mockClaimsParser = new();
private ILogger logger = new NullLogger();
- private ExtensionGrantValidationContext context = new ExtensionGrantValidationContext
+ private ExtensionGrantValidationContext context = new()
{
Request = new ValidatedTokenRequest
{
@@ -32,7 +32,7 @@ public class TokenExchangeExtensionGrantValidatorTests
};
private TokenExchangeExtensionGrantValidator CreateSut()
- => new TokenExchangeExtensionGrantValidator(mockParser?.Object, mockRequestValidator?.Object, mockClaimsParser?.Object, logger);
+ => new(mockParser?.Object, mockRequestValidator?.Object, mockClaimsParser?.Object, logger);
private Mock CreateMockedSut()
{
@@ -82,8 +82,8 @@ public void GrantType_ExpectRfcGrantType()
}
[Fact]
- public void ValidateAsync_WhenContextIsNull_ExpectArgumentNullException()
- => Assert.ThrowsAsync(() => CreateMockedSut().Object.ValidateAsync(null));
+ public async Task ValidateAsync_WhenContextIsNull_ExpectArgumentNullException()
+ => await Assert.ThrowsAsync(() => CreateMockedSut().Object.ValidateAsync(null));
[Fact]
public async Task ValidateAsync_WhenParseRequestThrowsTokenExchangeException_ExpectFailureResult()
diff --git a/test/Rsk.TokenExchange.Tests.Integration/Rsk.TokenExchange.Tests.Integration.csproj b/test/Rsk.TokenExchange.Tests.Integration/Rsk.TokenExchange.Tests.Integration.csproj
index 633044d..cfae197 100644
--- a/test/Rsk.TokenExchange.Tests.Integration/Rsk.TokenExchange.Tests.Integration.csproj
+++ b/test/Rsk.TokenExchange.Tests.Integration/Rsk.TokenExchange.Tests.Integration.csproj
@@ -1,21 +1,24 @@
- netcoreapp3.1
+ net10.0
false
-
-
-
-
-
-
+
+
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
-
+
diff --git a/test/Rsk.TokenExchange.Tests.Integration/TestServer.cs b/test/Rsk.TokenExchange.Tests.Integration/TestServer.cs
index 06f1824..9b23c66 100644
--- a/test/Rsk.TokenExchange.Tests.Integration/TestServer.cs
+++ b/test/Rsk.TokenExchange.Tests.Integration/TestServer.cs
@@ -2,9 +2,8 @@
using System.IO;
using System.Security.Cryptography;
using System.Threading.Tasks;
-using IdentityServer4;
-using IdentityServer4.Models;
-using IdentityServer4.Test;
+using Open.IdentityServer.Models;
+using Open.IdentityServer.Test;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
@@ -13,7 +12,8 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
-using Rsk.TokenExchange.IdentityServer4;
+using Open.IdentityServer;
+using Rsk.TokenExchange.Open.IdentityServer;
namespace Rsk.TokenExchange.Tests.Integration
{
@@ -38,43 +38,43 @@ protected override IHost CreateHost(IHostBuilder builder)
public class TestStartup
{
- public static readonly Client Client = new Client
+ public static readonly Client Client = new()
{
ClientId = "client",
RequireClientSecret = false,
AllowedGrantTypes = GrantTypes.ClientCredentials,
- AllowedScopes = new[] {"api1", "api2"},
+ AllowedScopes = ["api1", "api2"],
// pretending this is a token from a user interactive flow
- Claims = new[] {new ClientClaim("sub", "1")},
+ Claims = [new ClientClaim("sub", "1")],
ClientClaimsPrefix = null
};
- public static readonly Client ApiClient = new Client
+ public static readonly Client ApiClient = new()
{
ClientId = "api1",
RequireClientSecret = false,
- AllowedGrantTypes = new[] {TokenExchangeConstants.GrantType},
- AllowedScopes = new[] {"api2"}
+ AllowedGrantTypes = [TokenExchangeConstants.GrantType],
+ AllowedScopes = ["api2"]
};
- public static readonly ApiResource Api1 = new ApiResource("api1") {Scopes = new[] {"api1"}};
- public static readonly ApiResource Api2 = new ApiResource("api2") {Scopes = new[] {"api2"}};
+ public static readonly ApiResource Api1 = new("api1") {Scopes = ["api1"] };
+ public static readonly ApiResource Api2 = new("api2") {Scopes = ["api2"] };
- public static readonly TestUser Alice = new TestUser {SubjectId = "1", Username = "alice"};
- public static readonly TestUser Bob = new TestUser {SubjectId = "2", Username = "bob"};
+ public static readonly TestUser Alice = new() {SubjectId = "1", Username = "alice"};
+ public static readonly TestUser Bob = new() {SubjectId = "2", Username = "bob"};
- private static readonly ApiScope ApiScope1 = new ApiScope("api1");
- private static readonly ApiScope ApiScope2 = new ApiScope("api2");
+ private static readonly ApiScope ApiScope1 = new("api1");
+ private static readonly ApiScope ApiScope2 = new("api2");
public void ConfigureServices(IServiceCollection services)
{
services.AddIdentityServer()
- .AddInMemoryClients(new[] {Client, ApiClient})
- .AddInMemoryApiResources(new[] {Api1, Api2})
- .AddInMemoryApiScopes(new[] {ApiScope1, ApiScope2})
+ .AddInMemoryClients([Client, ApiClient])
+ .AddInMemoryApiResources([Api1, Api2])
+ .AddInMemoryApiScopes([ApiScope1, ApiScope2])
.AddInMemoryIdentityResources(new List {new IdentityResources.OpenId(), new IdentityResources.Profile()})
- .AddTestUsers(new List {Alice, Bob})
+ .AddTestUsers([Alice, Bob])
.AddSigningCredential(
new ECDsaSecurityKey(ECDsa.Create(ECCurve.NamedCurves.nistP256)),
IdentityServerConstants.ECDsaSigningAlgorithm.ES256)
diff --git a/test/Rsk.TokenExchange.Tests.Integration/TestServerTests.cs b/test/Rsk.TokenExchange.Tests.Integration/TestServerTests.cs
index 50f1afd..8660483 100644
--- a/test/Rsk.TokenExchange.Tests.Integration/TestServerTests.cs
+++ b/test/Rsk.TokenExchange.Tests.Integration/TestServerTests.cs
@@ -1,10 +1,10 @@
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
+using System.Text.Json;
using System.Threading.Tasks;
using FluentAssertions;
using Microsoft.IdentityModel.JsonWebTokens;
-using Newtonsoft.Json.Linq;
using Xunit;
namespace Rsk.TokenExchange.Tests.Integration
@@ -23,34 +23,32 @@ public async Task TokenExchange_WhenAuthorizedApiSwapsToken_ExpectSuccessfulToke
{
var client = factory.CreateClient();
- var subjectTokenResponse = await client.PostAsync("/connect/token", new FormUrlEncodedContent(new []
- {
+ var subjectTokenResponse = await client.PostAsync("/connect/token", new FormUrlEncodedContent([
new KeyValuePair("grant_type", "client_credentials"),
new KeyValuePair("client_id", TestStartup.Client.ClientId),
- new KeyValuePair("scope", TestStartup.Api1.Name)
- }));
+ new KeyValuePair("scope", TestStartup.Api1.Name)
+ ]));
subjectTokenResponse.IsSuccessStatusCode.Should().BeTrue();
var subjectTokenResponseString = await subjectTokenResponse.Content.ReadAsStringAsync();
- var subjectToken = JObject.Parse(subjectTokenResponseString)["access_token"];
+ var subjectToken = GetStringProperty(subjectTokenResponseString, "access_token");
- var tokenExchangeResponse = await client.PostAsync("/connect/token", new FormUrlEncodedContent(new[]
- {
+ var tokenExchangeResponse = await client.PostAsync("/connect/token", new FormUrlEncodedContent([
new KeyValuePair("grant_type", TokenExchangeConstants.GrantType),
new KeyValuePair("client_id", TestStartup.Api1.Name),
new KeyValuePair("scope", TestStartup.Api2.Name),
new KeyValuePair(
TokenExchangeConstants.RequestParameters.SubjectToken,
- subjectToken.Value()),
+ subjectToken),
new KeyValuePair(
TokenExchangeConstants.RequestParameters.SubjectTokenType,
- TokenExchangeConstants.TokenTypes.AccessToken),
- }));
+ TokenExchangeConstants.TokenTypes.AccessToken)
+ ]));
tokenExchangeResponse.IsSuccessStatusCode.Should().BeTrue();
var tokenExchangeResponseString = await tokenExchangeResponse.Content.ReadAsStringAsync();
- JObject.Parse(tokenExchangeResponseString)["access_token"].Should().NotBeNull();
+ GetStringProperty(tokenExchangeResponseString, "access_token").Should().NotBeNullOrEmpty();
}
[Fact]
@@ -58,30 +56,28 @@ public async Task TokenExchange_WhenUnauthorizedApiSwapsToken_ExpectFailure()
{
var client = factory.CreateClient();
- var subjectTokenResponse = await client.PostAsync("/connect/token", new FormUrlEncodedContent(new []
- {
+ var subjectTokenResponse = await client.PostAsync("/connect/token", new FormUrlEncodedContent([
new KeyValuePair("grant_type", "client_credentials"),
new KeyValuePair("client_id", TestStartup.Client.ClientId),
- new KeyValuePair("scope", TestStartup.Api2.Name)
- }));
+ new KeyValuePair("scope", TestStartup.Api2.Name)
+ ]));
subjectTokenResponse.IsSuccessStatusCode.Should().BeTrue();
var subjectTokenResponseString = await subjectTokenResponse.Content.ReadAsStringAsync();
- var subjectToken = JObject.Parse(subjectTokenResponseString)["access_token"];
+ var subjectToken = GetStringProperty(subjectTokenResponseString, "access_token");
- var tokenExchangeResponse = await client.PostAsync("/connect/token", new FormUrlEncodedContent(new[]
- {
+ var tokenExchangeResponse = await client.PostAsync("/connect/token", new FormUrlEncodedContent([
new KeyValuePair("grant_type", TokenExchangeConstants.GrantType),
new KeyValuePair("client_id", TestStartup.Api1.Name),
new KeyValuePair("scope", TestStartup.Api2.Name),
new KeyValuePair(
TokenExchangeConstants.RequestParameters.SubjectToken,
- subjectToken.Value()),
+ subjectToken),
new KeyValuePair(
TokenExchangeConstants.RequestParameters.SubjectTokenType,
- TokenExchangeConstants.TokenTypes.AccessToken),
- }));
+ TokenExchangeConstants.TokenTypes.AccessToken)
+ ]));
tokenExchangeResponse.IsSuccessStatusCode.Should().BeFalse();
}
@@ -99,44 +95,47 @@ public async Task TokenExchange_ExpectCorrectClientIdAndActorClaim()
// actor claim containing client app acting on their behalf
token.Claims.Should().Contain(x => x.Type == "act");
var actorClaim = token.Claims.First(x => x.Type == "act");
- var actorClientId = JObject.Parse(actorClaim.Value)["client_id"];
- actorClientId.Should().NotBeNull();
- actorClientId.Value().Should().Be(TestStartup.Api1.Name);
+ var actorClientId = GetStringProperty(actorClaim.Value, "client_id");
+ actorClientId.Should().Be(TestStartup.Api1.Name);
}
private async Task TokenExchange()
{
var client = factory.CreateClient();
- var subjectTokenResponse = await client.PostAsync("/connect/token", new FormUrlEncodedContent(new[]
- {
+ var subjectTokenResponse = await client.PostAsync("/connect/token", new FormUrlEncodedContent([
new KeyValuePair("grant_type", "client_credentials"),
new KeyValuePair("client_id", TestStartup.Client.ClientId),
new KeyValuePair("scope", TestStartup.Api1.Name)
- }));
+ ]));
subjectTokenResponse.IsSuccessStatusCode.Should().BeTrue();
var subjectTokenResponseString = await subjectTokenResponse.Content.ReadAsStringAsync();
- var subjectToken = JObject.Parse(subjectTokenResponseString)["access_token"];
+ var subjectToken = GetStringProperty(subjectTokenResponseString, "access_token");
- var tokenExchangeResponse = await client.PostAsync("/connect/token", new FormUrlEncodedContent(new[]
- {
+ var tokenExchangeResponse = await client.PostAsync("/connect/token", new FormUrlEncodedContent([
new KeyValuePair("grant_type", TokenExchangeConstants.GrantType),
new KeyValuePair("client_id", TestStartup.Api1.Name),
new KeyValuePair("scope", TestStartup.Api2.Name),
new KeyValuePair(
TokenExchangeConstants.RequestParameters.SubjectToken,
- subjectToken.Value()),
+ subjectToken),
new KeyValuePair(
TokenExchangeConstants.RequestParameters.SubjectTokenType,
- TokenExchangeConstants.TokenTypes.AccessToken),
- }));
+ TokenExchangeConstants.TokenTypes.AccessToken)
+ ]));
tokenExchangeResponse.IsSuccessStatusCode.Should().BeTrue();
var tokenExchangeResponseString = await tokenExchangeResponse.Content.ReadAsStringAsync();
- return JObject.Parse(tokenExchangeResponseString)["access_token"].Value();
+ return GetStringProperty(tokenExchangeResponseString, "access_token");
+ }
+
+ private static string GetStringProperty(string json, string propertyName)
+ {
+ using var document = JsonDocument.Parse(json);
+ return document.RootElement.GetProperty(propertyName).GetString();
}
}
}
\ No newline at end of file
diff --git a/test/Rsk.TokenExchange.Tests/Models/TokenExchangeRequestTests.cs b/test/Rsk.TokenExchange.Tests/Models/TokenExchangeRequestTests.cs
index 951d914..c0cbfda 100644
--- a/test/Rsk.TokenExchange.Tests/Models/TokenExchangeRequestTests.cs
+++ b/test/Rsk.TokenExchange.Tests/Models/TokenExchangeRequestTests.cs
@@ -10,7 +10,7 @@ namespace Rsk.TokenExchange.Tests.Models
{
public class TokenExchangeRequestTests
{
- private readonly NameValueCollection rawRequest = new NameValueCollection
+ private readonly NameValueCollection rawRequest = new()
{
{TokenExchangeConstants.RequestParameters.GrantType, TokenExchangeConstants.GrantType},
{TokenExchangeConstants.RequestParameters.SubjectToken, "eyJ.eyJ"},
diff --git a/test/Rsk.TokenExchange.Tests/Parsers/TokenExchangeClaimsParserTests.cs b/test/Rsk.TokenExchange.Tests/Parsers/TokenExchangeClaimsParserTests.cs
index b6bb283..fffa503 100644
--- a/test/Rsk.TokenExchange.Tests/Parsers/TokenExchangeClaimsParserTests.cs
+++ b/test/Rsk.TokenExchange.Tests/Parsers/TokenExchangeClaimsParserTests.cs
@@ -2,11 +2,11 @@
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
+using System.Text.Json;
using System.Threading.Tasks;
using FluentAssertions;
using Microsoft.IdentityModel.JsonWebTokens;
using Moq;
-using Newtonsoft.Json;
using Rsk.TokenExchange.Exceptions;
using Xunit;
@@ -14,9 +14,9 @@ namespace Rsk.TokenExchange.Tests.Parsers
{
public class TokenExchangeClaimsParserTests
{
- private readonly Mock mockRequest = new Mock();
+ private readonly Mock mockRequest = new();
- private TokenExchangeClaimsParser CreateSut() => new TokenExchangeClaimsParser();
+ private TokenExchangeClaimsParser CreateSut() => new();
[Fact]
public async Task ParseSubject_WhenSubjectClaimsAreNull_ExpectArgumentNullException()
@@ -115,7 +115,7 @@ public async Task ParseClaims_WhenClientIdIsDifferent_ExpectSubjectClaimsWithAct
actor.Should().NotBeNull();
actor?.ValueType.Should().Be(JsonClaimValueTypes.Json);
- var parsedActor = JsonConvert.DeserializeObject(actor?.Value);
+ var parsedActor = JsonSerializer.Deserialize(actor?.Value);
parsedActor.ClientId.Should().Be(actorClientId);
parsedActor.InnerActor.Should().BeNull();
}
@@ -141,10 +141,13 @@ public async Task ParseClaims_WhenClientIdIsDifferentAndActorClaimAlreadyPresent
var actor = parsedClaims.FirstOrDefault(x => x.Type == "act");
actor.Should().NotBeNull();
actor?.ValueType.Should().Be(JsonClaimValueTypes.Json);
-
- var parsedActor = JsonConvert.DeserializeObject(actor?.Value);
- parsedActor.ClientId.Should().Be(actorClientId);
- parsedActor.InnerActor.Should().Be(innerActor);
+
+ if (actor?.Value != null)
+ {
+ var parsedActor = JsonSerializer.Deserialize(actor.Value);
+ parsedActor.ClientId.Should().Be(actorClientId);
+ parsedActor.InnerActor.Should().Be(innerActor);
+ }
}
}
}
\ No newline at end of file
diff --git a/test/Rsk.TokenExchange.Tests/Parsers/TokenExchangeRequestParserTests.cs b/test/Rsk.TokenExchange.Tests/Parsers/TokenExchangeRequestParserTests.cs
index 55fbc31..b95b1ed 100644
--- a/test/Rsk.TokenExchange.Tests/Parsers/TokenExchangeRequestParserTests.cs
+++ b/test/Rsk.TokenExchange.Tests/Parsers/TokenExchangeRequestParserTests.cs
@@ -8,9 +8,9 @@ namespace Rsk.TokenExchange.Tests.Parsers
{
public class TokenExchangeRequestParserTests
{
- private readonly TokenExchangeRequestParser sut = new TokenExchangeRequestParser();
+ private readonly TokenExchangeRequestParser sut = new();
- private readonly NameValueCollection parameters = new NameValueCollection
+ private readonly NameValueCollection parameters = new()
{
{TokenExchangeConstants.RequestParameters.GrantType, TokenExchangeConstants.GrantType},
{TokenExchangeConstants.RequestParameters.SubjectToken, "eyJ.eyJ"},
diff --git a/test/Rsk.TokenExchange.Tests/Rsk.TokenExchange.Tests.csproj b/test/Rsk.TokenExchange.Tests/Rsk.TokenExchange.Tests.csproj
index 9d7590b..93fdc21 100644
--- a/test/Rsk.TokenExchange.Tests/Rsk.TokenExchange.Tests.csproj
+++ b/test/Rsk.TokenExchange.Tests/Rsk.TokenExchange.Tests.csproj
@@ -1,31 +1,24 @@
- netcoreapp3.1;net5.0
+ net10.0
false
-
-
-
-
-
+
+
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
-
-
-
-
-
-
-
-
-
+
+
+
diff --git a/test/Rsk.TokenExchange.Tests/Validators/DefaultSubjectTokenValidatorTests.cs b/test/Rsk.TokenExchange.Tests/Validators/DefaultSubjectTokenValidatorTests.cs
index d2a7182..9a794e9 100644
--- a/test/Rsk.TokenExchange.Tests/Validators/DefaultSubjectTokenValidatorTests.cs
+++ b/test/Rsk.TokenExchange.Tests/Validators/DefaultSubjectTokenValidatorTests.cs
@@ -14,7 +14,7 @@ namespace Rsk.TokenExchange.Tests.Validators
{
public class DefaultSubjectTokenValidatorTests
{
- private Mock mockTokenValidator = new Mock();
+ private Mock mockTokenValidator = new();
private ILogger logger = new NullLogger();
private const string validToken = "eyJ.eyJ";
diff --git a/test/Rsk.TokenExchange.Tests/Validators/DefaultTokenExchangeRequestValidatorTests.cs b/test/Rsk.TokenExchange.Tests/Validators/DefaultTokenExchangeRequestValidatorTests.cs
index a1c9a8c..7ae6899 100644
--- a/test/Rsk.TokenExchange.Tests/Validators/DefaultTokenExchangeRequestValidatorTests.cs
+++ b/test/Rsk.TokenExchange.Tests/Validators/DefaultTokenExchangeRequestValidatorTests.cs
@@ -11,7 +11,7 @@ namespace Rsk.TokenExchange.Tests.Validators
{
public class DefaultTokenExchangeRequestValidatorTests
{
- private Mock mockSubjectTokenValidator = new Mock();
+ private Mock mockSubjectTokenValidator = new();
private readonly Mock mockRequest;
private readonly Mock mockSubjectTokenResponse;
@@ -24,7 +24,7 @@ public DefaultTokenExchangeRequestValidatorTests()
mockRequest.Setup(x => x.ClientId).Returns(testClientId);
mockSubjectTokenResponse = new Mock();
- mockSubjectTokenResponse.Setup(x => x.Claims).Returns(new[] {new Claim("aud", testClientId)});
+ mockSubjectTokenResponse.Setup(x => x.Claims).Returns([new Claim("aud", testClientId)]);
mockSubjectTokenValidator.Setup(x => x.Validate(It.IsAny(), It.IsAny()))
.ReturnsAsync(mockSubjectTokenResponse.Object);
@@ -87,7 +87,7 @@ public async Task Validate_WhenSubjectTokenIsValidWithInvalidAudience_ExpectFail
mockRequest.Setup(x => x.ClientId).Returns(Guid.NewGuid().ToString);
mockSubjectTokenResponse.Setup(x => x.IsValid).Returns(true);
- mockSubjectTokenResponse.Setup(x => x.Claims).Returns(new[] {new Claim("aud", Guid.NewGuid().ToString())});
+ mockSubjectTokenResponse.Setup(x => x.Claims).Returns([new Claim("aud", Guid.NewGuid().ToString())]);
var sut = CreateSut();
var result = await sut.Validate(mockRequest.Object);