From 7915f28d90d61fa7a3d34ed20ca8b56c0dd5eb26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Fri, 21 Jul 2023 07:20:14 +0200 Subject: [PATCH] Store the expiration date of the backchannel/frontchannel access tokens as a token in AuthenticationProperties --- .../OpenIddictClientAspNetCoreConstants.cs | 2 ++ .../OpenIddictClientAspNetCoreHandler.cs | 24 +++++++++++++++++++ .../OpenIddictClientOwinConstants.cs | 2 ++ .../OpenIddictClientOwinHandler.cs | 16 +++++++++++++ .../OpenIddictClientEvents.cs | 10 ++++++++ .../OpenIddictClientHandlers.cs | 24 ++++++++++++++++--- 6 files changed, 75 insertions(+), 3 deletions(-) diff --git a/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreConstants.cs b/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreConstants.cs index ccc88f47..0791e7b3 100644 --- a/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreConstants.cs +++ b/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreConstants.cs @@ -35,8 +35,10 @@ public static class OpenIddictClientAspNetCoreConstants { public const string AuthorizationCode = "authorization_code"; public const string BackchannelAccessToken = "backchannel_access_token"; + public const string BackchannelAccessTokenExpirationDate = "backchannel_access_token_expiration_date"; public const string BackchannelIdentityToken = "backchannel_id_token"; public const string FrontchannelAccessToken = "frontchannel_access_token"; + public const string FrontchannelAccessTokenExpirationDate = "frontchannel_access_token_expiration_date"; public const string FrontchannelIdentityToken = "frontchannel_id_token"; public const string RefreshToken = "refresh_token"; public const string StateToken = "state_token"; diff --git a/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreHandler.cs b/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreHandler.cs index 7dffffe7..6cb40923 100644 --- a/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreHandler.cs +++ b/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreHandler.cs @@ -6,6 +6,7 @@ using System.ComponentModel; using System.Diagnostics; +using System.Globalization; using System.Security.Claims; using System.Text.Encodings.Web; using System.Text.Json; @@ -192,6 +193,9 @@ public sealed class OpenIddictClientAspNetCoreHandler : AuthenticationHandler public string? BackchannelAccessToken { get; set; } + /// + /// Gets or sets the expiration date of the backchannel access token, if applicable. + /// + public DateTimeOffset? BackchannelAccessTokenExpirationDate { get; set; } + /// /// Gets or sets the backchannel identity token to validate, if applicable. /// @@ -698,6 +703,11 @@ public static partial class OpenIddictClientEvents /// public string? FrontchannelAccessToken { get; set; } + /// + /// Gets or sets the expiration date of the frontchannel access token, if applicable. + /// + public DateTimeOffset? FrontchannelAccessTokenExpirationDate { get; set; } + /// /// Gets or sets the frontchannel identity token to validate, if applicable. /// diff --git a/src/OpenIddict.Client/OpenIddictClientHandlers.cs b/src/OpenIddict.Client/OpenIddictClientHandlers.cs index 02c64733..43f1224f 100644 --- a/src/OpenIddict.Client/OpenIddictClientHandlers.cs +++ b/src/OpenIddict.Client/OpenIddictClientHandlers.cs @@ -1392,6 +1392,15 @@ public static partial class OpenIddictClientHandlers _ => null }; + context.FrontchannelAccessTokenExpirationDate = context.EndpointType switch + { + OpenIddictClientEndpointType.Redirection when context.ExtractFrontchannelAccessToken + => ((long?) context.Request[Parameters.ExpiresIn]) is long value ? + DateTimeOffset.UtcNow.AddSeconds(value) : null, + + _ => null + }; + context.FrontchannelIdentityToken = context.EndpointType switch { OpenIddictClientEndpointType.Redirection when context.ExtractFrontchannelIdentityToken @@ -2721,9 +2730,18 @@ public static partial class OpenIddictClientHandlers Debug.Assert(context.TokenResponse is not null, SR.GetResourceString(SR.ID4007)); - context.BackchannelAccessToken = context.ExtractBackchannelAccessToken ? context.TokenResponse.AccessToken : null; - context.BackchannelIdentityToken = context.ExtractBackchannelIdentityToken ? context.TokenResponse.IdToken : null; - context.RefreshToken = context.ExtractRefreshToken ? context.TokenResponse.RefreshToken : null; + context.BackchannelAccessToken = context.ExtractBackchannelAccessToken ? + context.TokenResponse.AccessToken : null; + + context.BackchannelAccessTokenExpirationDate = + context.ExtractBackchannelAccessToken && + context.TokenResponse.ExpiresIn is long value ? DateTimeOffset.UtcNow.AddSeconds(value) : null; + + context.BackchannelIdentityToken = context.ExtractBackchannelIdentityToken ? + context.TokenResponse.IdToken : null; + + context.RefreshToken = context.ExtractRefreshToken ? + context.TokenResponse.RefreshToken : null; return default; }