Skip to content

Commit 65c5d15

Browse files
authored
Merge pull request #30 from jokk-itu/feature/update-authtime
Feature/update authtime
2 parents 4901bd6 + e75b778 commit 65c5d15

27 files changed

+389
-124
lines changed

src/AuthServer.TestIdentityProvider/Migrations/20250223170151_Initial.Designer.cs renamed to src/AuthServer.TestIdentityProvider/Migrations/20250302163943_Initial.Designer.cs

Lines changed: 7 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/AuthServer.TestIdentityProvider/Migrations/20250223170151_Initial.cs renamed to src/AuthServer.TestIdentityProvider/Migrations/20250302163943_Initial.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,8 @@ protected override void Up(MigrationBuilder migrationBuilder)
429429
columns: table => new
430430
{
431431
Id = table.Column<string>(type: "nvarchar(450)", nullable: false),
432-
AuthTime = table.Column<DateTime>(type: "datetime2", nullable: false),
432+
UpdatedAuthTime = table.Column<DateTime>(type: "datetime2", nullable: false),
433+
CreatedAuthTime = table.Column<DateTime>(type: "datetime2", nullable: false),
433434
RevokedAt = table.Column<DateTime>(type: "datetime2", nullable: true),
434435
Subject = table.Column<string>(type: "nvarchar(255)", maxLength: 255, nullable: false),
435436
SessionId = table.Column<string>(type: "nvarchar(450)", nullable: false),

src/AuthServer.TestIdentityProvider/Migrations/AuthorizationDbContextModelSnapshot.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -206,16 +206,16 @@ protected override void BuildModel(ModelBuilder modelBuilder)
206206
b.Property<string>("Id")
207207
.HasColumnType("nvarchar(450)");
208208

209-
b.Property<DateTime>("AuthTime")
210-
.HasColumnType("datetime2");
211-
212209
b.Property<int>("AuthenticationContextReferenceId")
213210
.HasColumnType("int");
214211

215212
b.Property<string>("ClientId")
216213
.IsRequired()
217214
.HasColumnType("nvarchar(450)");
218215

216+
b.Property<DateTime>("CreatedAuthTime")
217+
.HasColumnType("datetime2");
218+
219219
b.Property<DateTime?>("RevokedAt")
220220
.HasColumnType("datetime2");
221221

@@ -228,6 +228,9 @@ protected override void BuildModel(ModelBuilder modelBuilder)
228228
.HasMaxLength(255)
229229
.HasColumnType("nvarchar(255)");
230230

231+
b.Property<DateTime>("UpdatedAuthTime")
232+
.HasColumnType("datetime2");
233+
231234
b.HasKey("Id");
232235

233236
b.HasIndex("AuthenticationContextReferenceId");

src/AuthServer.TestIdentityProvider/Program.cs

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,13 @@
33
using AuthServer.Enums;
44
using AuthServer.Extensions;
55
using Microsoft.EntityFrameworkCore;
6-
using Microsoft.IdentityModel.Tokens;
7-
using System.Security.Cryptography;
86
using AuthServer.Tests.Core;
97
using Microsoft.AspNetCore.Authentication.Cookies;
108
using Microsoft.IdentityModel.Logging;
119
using AuthServer.Options;
1210
using AuthServer.Authorize.Abstractions;
1311
using AuthServer.Authentication.Abstractions;
12+
using AuthServer.TestIdentityProvider;
1413

1514
var builder = WebApplication.CreateBuilder(args);
1615

@@ -38,10 +37,16 @@
3837
options.ProtectedResources = identitySection.GetSection("ProtectedResources").Get<ICollection<string>>() ?? [];
3938

4039
ICollection<string> signingAlgorithms =
41-
[JwsAlgConstants.RsaSha256, JwsAlgConstants.EcdsaSha256, JwsAlgConstants.RsaSsaPssSha256];
40+
[JwsAlgConstants.RsaSha256, JwsAlgConstants.RsaSha384, JwsAlgConstants.RsaSha512,
41+
JwsAlgConstants.EcdsaSha256, JwsAlgConstants.EcdsaSha384, JwsAlgConstants.EcdsaSha512,
42+
JwsAlgConstants.RsaSsaPssSha256, JwsAlgConstants.RsaSsaPssSha384, JwsAlgConstants.RsaSsaPssSha512];
43+
4244
ICollection<string> encryptionAlgorithms =
43-
[JweAlgConstants.EcdhEsA128KW, JweAlgConstants.RsaOAEP, JweAlgConstants.RsaPKCS1];
44-
ICollection<string> encoderAlgorithms = [JweEncConstants.Aes128CbcHmacSha256];
45+
[JweAlgConstants.EcdhEsA128KW, JweAlgConstants.EcdhEsA192KW, JweAlgConstants.EcdhEsA256KW,
46+
JweAlgConstants.RsaOAEP, JweAlgConstants.RsaPKCS1];
47+
48+
ICollection<string> encoderAlgorithms =
49+
[JweEncConstants.Aes128CbcHmacSha256, JweEncConstants.Aes192CbcHmacSha384, JweEncConstants.Aes256CbcHmacSha512];
4550

4651
options.TokenEndpointAuthSigningAlgValuesSupported = signingAlgorithms;
4752
options.IdTokenSigningAlgValuesSupported = signingAlgorithms;
@@ -61,40 +66,29 @@
6166
options.TokenEndpointAuthEncryptionEncValuesSupported = encoderAlgorithms;
6267
});
6368

64-
var ecdsa = ECDsa.Create();
65-
var rsa = RSA.Create(3072);
66-
67-
var ecdsaSecurityKey = new ECDsaSecurityKey(ecdsa)
68-
{
69-
KeyId = Guid.NewGuid().ToString()
70-
};
71-
var rsaSecurityKey = new RsaSecurityKey(rsa)
72-
{
73-
KeyId = Guid.NewGuid().ToString()
74-
};
7569
builder.Services
7670
.AddOptions<JwksDocument>()
7771
.Configure(options =>
7872
{
7973
options.EncryptionKeys =
8074
[
81-
new JwksDocument.EncryptionKey(ecdsaSecurityKey, EncryptionAlg.EcdhEsA128KW),
82-
new JwksDocument.EncryptionKey(ecdsaSecurityKey, EncryptionAlg.EcdhEsA192KW),
83-
new JwksDocument.EncryptionKey(ecdsaSecurityKey, EncryptionAlg.EcdhEsA256KW),
84-
new JwksDocument.EncryptionKey(rsaSecurityKey, EncryptionAlg.RsaOAEP),
85-
new JwksDocument.EncryptionKey(rsaSecurityKey, EncryptionAlg.RsaPKCS1),
75+
new JwksDocument.EncryptionKey(SecurityKeyHelper.EcdhEs128, EncryptionAlg.EcdhEsA128KW),
76+
new JwksDocument.EncryptionKey(SecurityKeyHelper.EcdhEs192, EncryptionAlg.EcdhEsA192KW),
77+
new JwksDocument.EncryptionKey(SecurityKeyHelper.EcdhEs256, EncryptionAlg.EcdhEsA256KW),
78+
new JwksDocument.EncryptionKey(SecurityKeyHelper.RsaOAep, EncryptionAlg.RsaOAEP),
79+
new JwksDocument.EncryptionKey(SecurityKeyHelper.RsaPkcs1, EncryptionAlg.RsaPKCS1),
8680
];
8781
options.SigningKeys =
8882
[
89-
new JwksDocument.SigningKey(ecdsaSecurityKey, SigningAlg.EcdsaSha256),
90-
new JwksDocument.SigningKey(ecdsaSecurityKey, SigningAlg.EcdsaSha384),
91-
new JwksDocument.SigningKey(ecdsaSecurityKey, SigningAlg.EcdsaSha512),
92-
new JwksDocument.SigningKey(rsaSecurityKey, SigningAlg.RsaSha256),
93-
new JwksDocument.SigningKey(rsaSecurityKey, SigningAlg.RsaSha384),
94-
new JwksDocument.SigningKey(rsaSecurityKey, SigningAlg.RsaSha512),
95-
new JwksDocument.SigningKey(rsaSecurityKey, SigningAlg.RsaSsaPssSha256),
96-
new JwksDocument.SigningKey(rsaSecurityKey, SigningAlg.RsaSsaPssSha384),
97-
new JwksDocument.SigningKey(rsaSecurityKey, SigningAlg.RsaSsaPssSha512),
83+
new JwksDocument.SigningKey(SecurityKeyHelper.Ecdsa256, SigningAlg.EcdsaSha256),
84+
new JwksDocument.SigningKey(SecurityKeyHelper.Ecdsa384, SigningAlg.EcdsaSha384),
85+
new JwksDocument.SigningKey(SecurityKeyHelper.Ecdsa512, SigningAlg.EcdsaSha512),
86+
new JwksDocument.SigningKey(SecurityKeyHelper.CertificateRsa256, SigningAlg.RsaSha256),
87+
new JwksDocument.SigningKey(SecurityKeyHelper.CertificateRsa384, SigningAlg.RsaSha384),
88+
new JwksDocument.SigningKey(SecurityKeyHelper.CertificateRsa512, SigningAlg.RsaSha512),
89+
new JwksDocument.SigningKey(SecurityKeyHelper.RsaSsaPss256, SigningAlg.RsaSsaPssSha256),
90+
new JwksDocument.SigningKey(SecurityKeyHelper.RsaSsaPss384, SigningAlg.RsaSsaPssSha384),
91+
new JwksDocument.SigningKey(SecurityKeyHelper.RsaSsaPss512, SigningAlg.RsaSsaPssSha512)
9892
];
9993

10094
options.GetTokenSigningKey =
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using Microsoft.IdentityModel.Tokens;
2+
using System.Security.Cryptography.X509Certificates;
3+
using System.Security.Cryptography;
4+
5+
namespace AuthServer.TestIdentityProvider;
6+
7+
public static class SecurityKeyHelper
8+
{
9+
private static readonly ECDsa _ecdsa = ECDsa.Create();
10+
private static readonly RSA _rsa = RSA.Create(3072);
11+
12+
public static readonly X509SecurityKey CertificateRsa256 = GetCertificate(HashAlgorithmName.SHA256);
13+
public static readonly X509SecurityKey CertificateRsa384 = GetCertificate(HashAlgorithmName.SHA384);
14+
public static readonly X509SecurityKey CertificateRsa512 = GetCertificate(HashAlgorithmName.SHA512);
15+
16+
public static readonly ECDsaSecurityKey Ecdsa256 = GetECDsaSecurityKey();
17+
public static readonly ECDsaSecurityKey Ecdsa384 = GetECDsaSecurityKey();
18+
public static readonly ECDsaSecurityKey Ecdsa512 = GetECDsaSecurityKey();
19+
20+
public static readonly ECDsaSecurityKey EcdhEs128 = GetECDsaSecurityKey();
21+
public static readonly ECDsaSecurityKey EcdhEs192 = GetECDsaSecurityKey();
22+
public static readonly ECDsaSecurityKey EcdhEs256 = GetECDsaSecurityKey();
23+
24+
public static readonly RsaSecurityKey RsaOAep = GetRsaSecurityKey();
25+
public static readonly RsaSecurityKey RsaPkcs1 = GetRsaSecurityKey();
26+
27+
public static readonly RsaSecurityKey RsaSsaPss256 = GetRsaSecurityKey();
28+
public static readonly RsaSecurityKey RsaSsaPss384 = GetRsaSecurityKey();
29+
public static readonly RsaSecurityKey RsaSsaPss512 = GetRsaSecurityKey();
30+
31+
private static X509SecurityKey GetCertificate(HashAlgorithmName hashAlgorithmName)
32+
{
33+
var request = new CertificateRequest("cn=authserver", _rsa, hashAlgorithmName, RSASignaturePadding.Pkcs1);
34+
var certificate = request.CreateSelfSigned(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddDays(90));
35+
return new X509SecurityKey(certificate, Guid.NewGuid().ToString());
36+
}
37+
38+
private static ECDsaSecurityKey GetECDsaSecurityKey() => new (_ecdsa) { KeyId = Guid.NewGuid().ToString() };
39+
private static RsaSecurityKey GetRsaSecurityKey() => new (_rsa){ KeyId = Guid.NewGuid().ToString() };
40+
}

src/AuthServer/Authorize/AuthorizeInteractionService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ private async Task<InteractionResult> GetPrompt(AuthorizeUser authorizeUser, Aut
177177
var hasMaxAge = int.TryParse(authorizeRequest.MaxAge, out var parsedMaxAge);
178178
var maxAge = hasMaxAge ? parsedMaxAge : authorizationGrant.Client.DefaultMaxAge;
179179

180-
if (maxAge is not null && authorizationGrant.AuthTime.AddSeconds(maxAge.Value) < DateTime.UtcNow)
180+
if (maxAge is not null && authorizationGrant.UpdatedAuthTime.AddSeconds(maxAge.Value) < DateTime.UtcNow)
181181
{
182182
_logger.LogDebug("MaxAge {MaxAge} has been reached for grant {GrantId}, deducing prompt {Prompt}", maxAge, authorizationGrant.Id, PromptConstants.Login);
183183
return InteractionResult.LoginResult(authorizeRequest.Prompt);

src/AuthServer/Core/Parameter.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ public static class Parameter
9494
public const string AuthTime = "auth_time";
9595
public const string Acr = "acr";
9696
public const string AccessControl = "access_control";
97+
public const string CreatedAt = "created_at";
98+
public const string UpdatedAt = "updated_at";
9799

98100
// Custom parameter
99101
public const string RequireReferenceToken = "require_reference_token";

src/AuthServer/Endpoints/Responses/GetGrantResponse.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,10 @@ internal class GetGrantResponse
99

1010
[JsonPropertyName(Parameter.Claims)]
1111
public IEnumerable<string> Claims { get; set; } = [];
12+
13+
[JsonPropertyName(Parameter.CreatedAt)]
14+
public DateTime CreatedAt { get; set; }
15+
16+
[JsonPropertyName(Parameter.UpdatedAt)]
17+
public DateTime UpdatedAt { get; set; }
1218
}

src/AuthServer/Entities/AuthorizationGrant.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ public class AuthorizationGrant : Entity<string>
77
public AuthorizationGrant(Session session, Client client, string subject, AuthenticationContextReference authenticationContextReference)
88
{
99
Id = Guid.NewGuid().ToString();
10-
AuthTime = DateTime.UtcNow;
10+
CreatedAuthTime = DateTime.UtcNow;
11+
UpdatedAuthTime = DateTime.UtcNow;
1112
Session = session ?? throw new ArgumentNullException(nameof(session));
1213
Client = client ?? throw new ArgumentNullException(nameof(client));
1314
Subject = subject ?? throw new ArgumentNullException(nameof(subject));
@@ -19,7 +20,8 @@ public AuthorizationGrant(Session session, Client client, string subject, Authen
1920
private AuthorizationGrant(){}
2021
#pragma warning restore
2122

22-
public DateTime AuthTime { get; private set; }
23+
public DateTime UpdatedAuthTime { get; private set; }
24+
public DateTime CreatedAuthTime { get; private init; }
2325
public DateTime? RevokedAt { get; private set; }
2426
public string Subject { get; private init; }
2527
public Session Session { get; private init; }
@@ -36,9 +38,9 @@ public void Revoke()
3638
RevokedAt ??= DateTime.UtcNow;
3739
}
3840

39-
public void SetAuthTime()
41+
public void UpdateAuthTime()
4042
{
41-
AuthTime = DateTime.UtcNow;
43+
UpdatedAuthTime = DateTime.UtcNow;
4244
}
4345

4446
public static readonly Expression<Func<AuthorizationGrant, bool>> IsActive = a => a.RevokedAt == null;

src/AuthServer/GrantManagement/Query/GrantManagementQueryEndpointHandler.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using AuthServer.Core;
1+
using AuthServer.Authentication.OAuthToken;
2+
using AuthServer.Core;
23
using AuthServer.Core.Abstractions;
34
using AuthServer.Core.Request;
45
using AuthServer.Endpoints.Responses;
@@ -33,13 +34,15 @@ public async Task<IResult> Handle(HttpContext httpContext, CancellationToken can
3334
Scopes = x.Scopes,
3435
Resources = x.Resources
3536
}),
36-
Claims = response.Claims
37+
Claims = response.Claims,
38+
CreatedAt = response.CreatedAt,
39+
UpdatedAt = response.UpdatedAt
3740
}),
3841
error =>
3942
error.ResultCode switch
4043
{
4144
ResultCode.NotFound => Results.Extensions.OAuthNotFound(error),
42-
ResultCode.Forbidden => throw new NotImplementedException(),
45+
ResultCode.Forbidden => Results.Forbid(null, [OAuthTokenAuthenticationDefaults.AuthenticationScheme]),
4346
_ => Results.Extensions.OAuthBadRequest(
4447
new OAuthError(ErrorCode.ServerError, "unexpected error occurred"))
4548
});

0 commit comments

Comments
 (0)