Browse Source

Store the expiration date of the backchannel/frontchannel access tokens as a token in AuthenticationProperties

pull/1842/head
Kévin Chalet 3 years ago
parent
commit
7915f28d90
  1. 2
      src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreConstants.cs
  2. 24
      src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreHandler.cs
  3. 2
      src/OpenIddict.Client.Owin/OpenIddictClientOwinConstants.cs
  4. 16
      src/OpenIddict.Client.Owin/OpenIddictClientOwinHandler.cs
  5. 10
      src/OpenIddict.Client/OpenIddictClientEvents.cs
  6. 24
      src/OpenIddict.Client/OpenIddictClientHandlers.cs

2
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";

24
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<Op
// Attach the tokens to allow any ASP.NET Core component (e.g a controller)
// to retrieve them (e.g to make an API request to another application).
//
// Note: for consistency with the ASP.NET Core OpenID Connect handler, the expiration
// dates of the backchannel/frontchannel access tokens are also stored as tokens.
if (!string.IsNullOrEmpty(context.AuthorizationCode))
{
@ -213,6 +217,16 @@ public sealed class OpenIddictClientAspNetCoreHandler : AuthenticationHandler<Op
});
}
if (context.BackchannelAccessTokenExpirationDate is not null)
{
tokens ??= new(capacity: 1);
tokens.Add(new AuthenticationToken
{
Name = Tokens.BackchannelAccessTokenExpirationDate,
Value = context.BackchannelAccessTokenExpirationDate.Value.ToString("o", CultureInfo.InvariantCulture)
});
}
if (!string.IsNullOrEmpty(context.BackchannelIdentityToken))
{
tokens ??= new(capacity: 1);
@ -233,6 +247,16 @@ public sealed class OpenIddictClientAspNetCoreHandler : AuthenticationHandler<Op
});
}
if (context.FrontchannelAccessTokenExpirationDate is not null)
{
tokens ??= new(capacity: 1);
tokens.Add(new AuthenticationToken
{
Name = Tokens.FrontchannelAccessTokenExpirationDate,
Value = context.FrontchannelAccessTokenExpirationDate.Value.ToString("o", CultureInfo.InvariantCulture)
});
}
if (!string.IsNullOrEmpty(context.FrontchannelIdentityToken))
{
tokens ??= new(capacity: 1);

2
src/OpenIddict.Client.Owin/OpenIddictClientOwinConstants.cs

@ -52,8 +52,10 @@ public static class OpenIddictClientOwinConstants
{
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";

16
src/OpenIddict.Client.Owin/OpenIddictClientOwinHandler.cs

@ -8,6 +8,7 @@ using System.Collections.Immutable;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Security.Claims;
using System.Text.Json;
@ -208,6 +209,9 @@ public sealed class OpenIddictClientOwinHandler : AuthenticationHandler<OpenIddi
// Attach the tokens to allow any OWIN component (e.g a controller)
// to retrieve them (e.g to make an API request to another application).
//
// Note: for consistency with the OWIN OpenID Connect middleware, the expiration
// dates of the backchannel/frontchannel access tokens are also stored as tokens.
if (!string.IsNullOrEmpty(context.AuthorizationCode))
{
@ -219,6 +223,12 @@ public sealed class OpenIddictClientOwinHandler : AuthenticationHandler<OpenIddi
properties.Dictionary[Tokens.BackchannelAccessToken] = context.BackchannelAccessToken;
}
if (context.BackchannelAccessTokenExpirationDate is not null)
{
properties.Dictionary[Tokens.BackchannelAccessTokenExpirationDate] =
context.BackchannelAccessTokenExpirationDate.Value.ToString("o", CultureInfo.InvariantCulture);
}
if (!string.IsNullOrEmpty(context.BackchannelIdentityToken))
{
properties.Dictionary[Tokens.BackchannelIdentityToken] = context.BackchannelIdentityToken;
@ -229,6 +239,12 @@ public sealed class OpenIddictClientOwinHandler : AuthenticationHandler<OpenIddi
properties.Dictionary[Tokens.FrontchannelAccessToken] = context.FrontchannelAccessToken;
}
if (context.FrontchannelAccessTokenExpirationDate is not null)
{
properties.Dictionary[Tokens.FrontchannelAccessTokenExpirationDate] =
context.FrontchannelAccessTokenExpirationDate.Value.ToString("o", CultureInfo.InvariantCulture);
}
if (!string.IsNullOrEmpty(context.FrontchannelIdentityToken))
{
properties.Dictionary[Tokens.FrontchannelIdentityToken] = context.FrontchannelIdentityToken;

10
src/OpenIddict.Client/OpenIddictClientEvents.cs

@ -683,6 +683,11 @@ public static partial class OpenIddictClientEvents
/// </summary>
public string? BackchannelAccessToken { get; set; }
/// <summary>
/// Gets or sets the expiration date of the backchannel access token, if applicable.
/// </summary>
public DateTimeOffset? BackchannelAccessTokenExpirationDate { get; set; }
/// <summary>
/// Gets or sets the backchannel identity token to validate, if applicable.
/// </summary>
@ -698,6 +703,11 @@ public static partial class OpenIddictClientEvents
/// </summary>
public string? FrontchannelAccessToken { get; set; }
/// <summary>
/// Gets or sets the expiration date of the frontchannel access token, if applicable.
/// </summary>
public DateTimeOffset? FrontchannelAccessTokenExpirationDate { get; set; }
/// <summary>
/// Gets or sets the frontchannel identity token to validate, if applicable.
/// </summary>

24
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;
}

Loading…
Cancel
Save