Skip to content

Commit 2f2c990

Browse files
hashtagnullavn0804
andauthored
Refactor SenseNetJwtSecurityTokenHandler class to remove dependency on obsolete method & Raise prelease (#2201)
* feat: update token handler to make compatible with sn auth * Raise prelease --------- Co-authored-by: vn0804 <129531684+vn0804@users.noreply.github.com>
1 parent c46bd5e commit 2f2c990

File tree

6 files changed

+85
-51
lines changed

6 files changed

+85
-51
lines changed
Lines changed: 76 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,101 @@
1-
using Microsoft.IdentityModel.Tokens;
1+
using Microsoft.Extensions.DependencyInjection;
2+
using Microsoft.IdentityModel.Tokens;
3+
using SenseNet.Configuration;
24
using System;
35
using System.IdentityModel.Tokens.Jwt;
46
using System.Net.Http;
57
using System.Net.Http.Headers;
68
using System.Security.Claims;
79
using System.Threading.Tasks;
810

9-
namespace SnWebApplication.Api.Sql.TokenAuth.TokenValidator
10-
{
11-
public class SenseNetJwtSecurityTokenHandler : ISecurityTokenValidator
11+
namespace SenseNet.Services.Core.Authentication;
12+
13+
public class SenseNetJwtSecurityTokenHandler : TokenHandler
14+
{
15+
private readonly string _validateTokenUrl;
16+
private readonly JwtSecurityTokenHandler _defaultHandler;
17+
private readonly IHttpClientFactory _httpClientFactory;
18+
19+
public SenseNetJwtSecurityTokenHandler(string validateTokenUrl)
1220
{
13-
private readonly string _validateTokenUrl;
14-
private readonly JwtSecurityTokenHandler _defaultHandler;
21+
_httpClientFactory = Providers.Instance.Services.GetRequiredService<IHttpClientFactory>();
22+
_validateTokenUrl = validateTokenUrl ?? throw new ArgumentNullException(nameof(validateTokenUrl));
23+
_defaultHandler = new JwtSecurityTokenHandler();
24+
}
1525

16-
public bool CanValidateToken => true;
17-
public int MaximumTokenSizeInBytes { get; set; } = TokenValidationParameters.DefaultMaximumTokenSizeInBytes;
26+
public override int MaximumTokenSizeInBytes
27+
{
28+
get => base.MaximumTokenSizeInBytes;
29+
set => base.MaximumTokenSizeInBytes = value;
30+
}
1831

19-
public SenseNetJwtSecurityTokenHandler(string validateTokenUrl)
20-
{
21-
_validateTokenUrl = validateTokenUrl ?? throw new ArgumentNullException(nameof(validateTokenUrl));
22-
_defaultHandler = new JwtSecurityTokenHandler();
23-
}
32+
public override SecurityToken ReadToken(string token)
33+
{
34+
if (string.IsNullOrWhiteSpace(token))
35+
throw new ArgumentNullException(nameof(token));
2436

25-
public bool CanReadToken(string securityToken) =>
26-
_defaultHandler.CanReadToken(securityToken);
37+
return _defaultHandler.ReadJwtToken(token);
38+
}
39+
40+
public override async Task<TokenValidationResult> ValidateTokenAsync(string token, TokenValidationParameters validationParameters)
41+
{
42+
await ValidateTokenAsync(token);
2743

28-
private async Task ValidateTokenAsync(string token)
44+
try
2945
{
30-
if (string.IsNullOrWhiteSpace(token))
31-
return;
46+
var jwtToken = ReadToken(token) as JwtSecurityToken;
3247

33-
using var httpClient = new HttpClient();
48+
return new TokenValidationResult
49+
{
50+
ClaimsIdentity = new ClaimsIdentity(jwtToken.Claims, "Custom"),
51+
SecurityToken = jwtToken,
52+
IsValid = true
53+
};
54+
}
55+
catch (Exception ex)
56+
{
57+
return new TokenValidationResult
58+
{
59+
Exception = ex
60+
};
61+
}
62+
}
3463

35-
httpClient.DefaultRequestHeaders.Clear();
36-
httpClient.DefaultRequestHeaders
37-
.Accept
38-
.Add(new MediaTypeWithQualityHeaderValue("application/json"));
39-
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
64+
public override async Task<TokenValidationResult> ValidateTokenAsync(SecurityToken token, TokenValidationParameters validationParameters)
65+
{
66+
ArgumentNullException.ThrowIfNull(token);
4067

41-
var response = await httpClient.GetAsync(_validateTokenUrl);
42-
if (!response.IsSuccessStatusCode)
43-
throw new SecurityTokenValidationException("Invalid token.");
68+
var jwtToken = token as JwtSecurityToken ?? throw new ArgumentException("The token must be of type JwtSecurityToken.");
4469

45-
var result = bool.Parse(await response.Content.ReadAsStringAsync());
46-
if (!result)
47-
throw new SecurityTokenValidationException("Invalid token.");
48-
}
70+
await ValidateTokenAsync(jwtToken.RawData);
4971

50-
public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
72+
return new TokenValidationResult
5173
{
52-
ValidateTokenAsync(securityToken).GetAwaiter().GetResult();
74+
ClaimsIdentity = new ClaimsIdentity(jwtToken.Claims, "Custom"),
75+
SecurityToken = jwtToken,
76+
IsValid = true
77+
};
78+
}
5379

54-
var jwtToken = _defaultHandler.ReadJwtToken(securityToken);
80+
private async Task ValidateTokenAsync(string token)
81+
{
82+
if (string.IsNullOrWhiteSpace(token))
83+
return;
5584

56-
var identity = new ClaimsIdentity(jwtToken.Claims, "Custom");
57-
var principal = new ClaimsPrincipal(identity);
85+
using var httpClient = _httpClientFactory.CreateClient();
5886

59-
validatedToken = jwtToken;
87+
httpClient.DefaultRequestHeaders.Clear();
88+
httpClient.DefaultRequestHeaders
89+
.Accept
90+
.Add(new MediaTypeWithQualityHeaderValue("application/json"));
91+
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
6092

61-
return principal;
62-
}
93+
var response = await httpClient.GetAsync(_validateTokenUrl);
94+
if (!response.IsSuccessStatusCode)
95+
throw new SecurityTokenValidationException("Invalid token.");
96+
97+
var result = bool.Parse(await response.Content.ReadAsStringAsync());
98+
if (!result)
99+
throw new SecurityTokenValidationException("Invalid token.");
63100
}
64101
}

src/Services.Core/SenseNet.Services.Core.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<TargetFramework>net8.0</TargetFramework>
5-
<Version>1.1.1-alpha.3</Version>
5+
<Version>1.1.1-alpha.4</Version>
66
<Authors>kavics,joe,tusmester,hashtagnulla</Authors>
77
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
88
<Company>Sense/Net Inc.</Company>

src/WebApps/SnWebApplication.Api.InMem.TokenAuth/Startup.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ public void ConfigureServices(IServiceCollection services)
5050
ValidateIssuerSigningKey = false
5151
};
5252

53-
options.SecurityTokenValidators.Clear();
54-
options.SecurityTokenValidators.Add(new SenseNetJwtSecurityTokenHandler(
53+
options.TokenHandlers.Clear();
54+
options.TokenHandlers.Add(new SenseNetJwtSecurityTokenHandler(
5555
$"{authOptions.Authority}/api/auth/validate-token"));
5656
}
5757
else

src/WebApps/SnWebApplication.Api.Sql.SearchService.TokenAuth/Startup.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
using SenseNet.Search.Lucene29.Centralized.GrpcClient;
1919
using SenseNet.Security.Messaging.RabbitMQ;
2020
using SenseNet.Services.Core.Authentication;
21-
using SnWebApplication.Api.Sql.TokenAuth.TokenValidator;
2221

2322
namespace SnWebApplication.Api.Sql.SearchService.TokenAuth
2423
{
@@ -55,8 +54,8 @@ public void ConfigureServices(IServiceCollection services)
5554
ValidateIssuerSigningKey = false
5655
};
5756

58-
options.SecurityTokenValidators.Clear();
59-
options.SecurityTokenValidators.Add(new SenseNetJwtSecurityTokenHandler(
57+
options.TokenHandlers.Clear();
58+
options.TokenHandlers.Add(new SenseNetJwtSecurityTokenHandler(
6059
$"{authOptions.Authority}/api/auth/validate-token"));
6160
}
6261
else

src/WebApps/SnWebApplication.Api.Sql.TokenAuth.Preview/Startup.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
using SenseNet.Extensions.DependencyInjection;
1919
using SenseNet.Search.Lucene29;
2020
using SenseNet.Services.Core.Authentication;
21-
using SnWebApplication.Api.Sql.TokenAuth.TokenValidator;
2221

2322
namespace SnWebApplication.Api.Sql.TokenAuth.Preview
2423
{
@@ -55,8 +54,8 @@ public void ConfigureServices(IServiceCollection services)
5554
ValidateIssuerSigningKey = false
5655
};
5756

58-
options.SecurityTokenValidators.Clear();
59-
options.SecurityTokenValidators.Add(new SenseNetJwtSecurityTokenHandler(
57+
options.TokenHandlers.Clear();
58+
options.TokenHandlers.Add(new SenseNetJwtSecurityTokenHandler(
6059
$"{authOptions.Authority}/api/auth/validate-token"));
6160
}
6261
else

src/WebApps/SnWebApplication.Api.Sql.TokenAuth/Startup.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
using SenseNet.Extensions.DependencyInjection;
2020
using SenseNet.Search.Lucene29;
2121
using SenseNet.Services.Core.Authentication;
22-
using SnWebApplication.Api.Sql.TokenAuth.TokenValidator;
2322

2423
namespace SnWebApplication.Api.Sql.TokenAuth
2524
{
@@ -56,8 +55,8 @@ public void ConfigureServices(IServiceCollection services)
5655
ValidateIssuerSigningKey = false
5756
};
5857

59-
options.SecurityTokenValidators.Clear();
60-
options.SecurityTokenValidators.Add(new SenseNetJwtSecurityTokenHandler(
58+
options.TokenHandlers.Clear();
59+
options.TokenHandlers.Add(new SenseNetJwtSecurityTokenHandler(
6160
$"{authOptions.Authority}/api/auth/validate-token"));
6261
}
6362
else

0 commit comments

Comments
 (0)