Skip to content
This repository was archived by the owner on Dec 24, 2020. It is now read-only.

Commit f808e4b

Browse files
committed
Make the caching policy configurable
1 parent 1efee55 commit f808e4b

File tree

10 files changed

+80
-49
lines changed

10 files changed

+80
-49
lines changed

src/AspNet.Security.OAuth.Introspection/OAuthIntrospectionHandler.cs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
using Microsoft.AspNetCore.Http;
1919
using Microsoft.AspNetCore.Http.Authentication;
2020
using Microsoft.AspNetCore.Http.Features.Authentication;
21-
using Microsoft.Extensions.Caching.Distributed;
2221
using Microsoft.Extensions.Logging;
2322
using Microsoft.Net.Http.Headers;
2423
using Newtonsoft.Json;
@@ -361,7 +360,7 @@ protected override async Task<bool> HandleUnauthorizedAsync(ChallengeContext con
361360
return false;
362361
}
363362

364-
protected virtual async Task<JObject> GetIntrospectionPayloadAsync(string token)
363+
private async Task<JObject> GetIntrospectionPayloadAsync(string token)
365364
{
366365
var configuration = await Options.ConfigurationManager.GetConfigurationAsync(Context.RequestAborted);
367366
if (configuration == null)
@@ -455,7 +454,7 @@ exception is JsonReaderException ||
455454
}
456455
}
457456

458-
protected virtual bool ValidateAudience(AuthenticationTicket ticket)
457+
private bool ValidateAudience(AuthenticationTicket ticket)
459458
{
460459
// If no explicit audience has been configured,
461460
// skip the default audience validation.
@@ -464,9 +463,9 @@ protected virtual bool ValidateAudience(AuthenticationTicket ticket)
464463
return true;
465464
}
466465

467-
string audiences;
468466
// Extract the audiences from the authentication ticket.
469-
if (!ticket.Properties.Items.TryGetValue(OAuthIntrospectionConstants.Properties.Audiences, out audiences))
467+
var audiences = ticket.Properties.GetProperty(OAuthIntrospectionConstants.Properties.Audiences);
468+
if (string.IsNullOrEmpty(audiences))
470469
{
471470
return false;
472471
}
@@ -483,7 +482,7 @@ protected virtual bool ValidateAudience(AuthenticationTicket ticket)
483482
return false;
484483
}
485484

486-
protected virtual async Task<AuthenticationTicket> CreateTicketAsync(string token, JObject payload)
485+
private async Task<AuthenticationTicket> CreateTicketAsync(string token, JObject payload)
487486
{
488487
var identity = new ClaimsIdentity(Options.AuthenticationScheme, Options.NameClaimType, Options.RoleClaimType);
489488
var properties = new AuthenticationProperties();
@@ -743,19 +742,26 @@ protected virtual async Task<AuthenticationTicket> CreateTicketAsync(string toke
743742
return notification.Ticket;
744743
}
745744

746-
protected virtual Task StoreTicketAsync(string token, AuthenticationTicket ticket)
745+
private Task StoreTicketAsync(string token, AuthenticationTicket ticket)
747746
{
747+
if (Options.CachingPolicy == null)
748+
{
749+
return Task.FromResult(0);
750+
}
751+
748752
var bytes = Encoding.UTF8.GetBytes(Options.AccessTokenFormat.Protect(ticket));
749753
Debug.Assert(bytes != null);
750754

751-
return Options.Cache.SetAsync(token, bytes, new DistributedCacheEntryOptions
752-
{
753-
AbsoluteExpiration = Options.SystemClock.UtcNow + TimeSpan.FromMinutes(15)
754-
});
755+
return Options.Cache.SetAsync(token, bytes, Options.CachingPolicy);
755756
}
756757

757-
protected virtual async Task<AuthenticationTicket> RetrieveTicketAsync(string token)
758+
private async Task<AuthenticationTicket> RetrieveTicketAsync(string token)
758759
{
760+
if (Options.CachingPolicy == null)
761+
{
762+
return null;
763+
}
764+
759765
// Retrieve the serialized ticket from the distributed cache.
760766
// If no corresponding entry can be found, null is returned.
761767
var bytes = await Options.Cache.GetAsync(token);

src/AspNet.Security.OAuth.Introspection/OAuthIntrospectionHelpers.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ public static string GetProperty([NotNull] this AuthenticationProperties propert
2727
throw new ArgumentException("The property name cannot be null or empty.", nameof(property));
2828
}
2929

30-
string value;
31-
if (!properties.Items.TryGetValue(property, out value))
30+
if (!properties.Items.TryGetValue(property, out string value))
3231
{
3332
return null;
3433
}

src/AspNet.Security.OAuth.Introspection/OAuthIntrospectionOptions.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,22 @@ public OAuthIntrospectionOptions()
109109
public string RoleClaimType { get; set; } = OAuthIntrospectionConstants.Claims.Role;
110110

111111
/// <summary>
112-
/// Gets or sets the cache used to store the authentication tickets
113-
/// resolved from the access tokens received by the resource server.
112+
/// Gets or sets the cache used to store the access tokens/authentication tickets
113+
/// and the introspection responses returned received by the resource server.
114114
/// </summary>
115115
public IDistributedCache Cache { get; set; }
116116

117+
/// <summary>
118+
/// Gets or sets the caching policy used to determine
119+
/// how long the introspection responses should be cached.
120+
/// Note: this property can be set to <c>null</c> to
121+
/// prevent the introspection responses from being cached.
122+
/// </summary>
123+
public DistributedCacheEntryOptions CachingPolicy { get; set; } = new DistributedCacheEntryOptions
124+
{
125+
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(15)
126+
};
127+
117128
/// <summary>
118129
/// Gets or sets the object provided by the application to process events raised by the authentication middleware.
119130
/// The application may implement the interface fully, or it may create an instance of

src/AspNet.Security.OAuth.Validation/OAuthValidationHandler.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ protected override async Task<bool> HandleUnauthorizedAsync(ChallengeContext con
339339
return false;
340340
}
341341

342-
protected virtual bool ValidateAudience(AuthenticationTicket ticket)
342+
private bool ValidateAudience(AuthenticationTicket ticket)
343343
{
344344
// If no explicit audience has been configured,
345345
// skip the default audience validation.
@@ -348,9 +348,9 @@ protected virtual bool ValidateAudience(AuthenticationTicket ticket)
348348
return true;
349349
}
350350

351-
string audiences;
352351
// Extract the audiences from the authentication ticket.
353-
if (!ticket.Properties.Items.TryGetValue(OAuthValidationConstants.Properties.Audiences, out audiences))
352+
var audiences = ticket.Properties.GetProperty(OAuthValidationConstants.Properties.Audiences);
353+
if (string.IsNullOrEmpty(audiences))
354354
{
355355
return false;
356356
}
@@ -367,7 +367,7 @@ protected virtual bool ValidateAudience(AuthenticationTicket ticket)
367367
return false;
368368
}
369369

370-
protected virtual async Task<AuthenticationTicket> CreateTicketAsync(string token)
370+
private async Task<AuthenticationTicket> CreateTicketAsync(string token)
371371
{
372372
var ticket = Options.AccessTokenFormat.Unprotect(token);
373373
if (ticket == null)
@@ -387,10 +387,10 @@ protected virtual async Task<AuthenticationTicket> CreateTicketAsync(string toke
387387
// Resolve the primary identity associated with the principal.
388388
var identity = (ClaimsIdentity) ticket.Principal.Identity;
389389

390-
string scopes;
391390
// Copy the scopes extracted from the authentication ticket to the
392391
// ClaimsIdentity to make them easier to retrieve from application code.
393-
if (ticket.Properties.Items.TryGetValue(OAuthValidationConstants.Properties.Scopes, out scopes))
392+
var scopes = ticket.Properties.GetProperty(OAuthValidationConstants.Properties.Scopes);
393+
if (!string.IsNullOrEmpty(scopes))
394394
{
395395
foreach (var scope in JArray.Parse(scopes).Values<string>())
396396
{

src/AspNet.Security.OAuth.Validation/OAuthValidationHelpers.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ public static string GetProperty([NotNull] this AuthenticationProperties propert
2727
throw new ArgumentException("The property name cannot be null or empty.", nameof(property));
2828
}
2929

30-
string value;
31-
if (!properties.Items.TryGetValue(property, out value))
30+
if (!properties.Items.TryGetValue(property, out string value))
3231
{
3332
return null;
3433
}

src/Owin.Security.OAuth.Introspection/OAuthIntrospectionHandler.cs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ protected override async Task ApplyResponseChallengeAsync()
350350
}
351351
}
352352

353-
protected virtual async Task<JObject> GetIntrospectionPayloadAsync(string token)
353+
private async Task<JObject> GetIntrospectionPayloadAsync(string token)
354354
{
355355
var configuration = await Options.ConfigurationManager.GetConfigurationAsync(Request.CallCancelled);
356356
if (configuration == null)
@@ -445,7 +445,7 @@ exception is JsonReaderException ||
445445
}
446446
}
447447

448-
protected virtual bool ValidateAudience(AuthenticationTicket ticket)
448+
private bool ValidateAudience(AuthenticationTicket ticket)
449449
{
450450
// If no explicit audience has been configured,
451451
// skip the default audience validation.
@@ -454,9 +454,9 @@ protected virtual bool ValidateAudience(AuthenticationTicket ticket)
454454
return true;
455455
}
456456

457-
string audiences;
458457
// Extract the audiences from the authentication ticket.
459-
if (!ticket.Properties.Dictionary.TryGetValue(OAuthIntrospectionConstants.Properties.Audiences, out audiences))
458+
var audiences = ticket.Properties.GetProperty(OAuthIntrospectionConstants.Properties.Audiences);
459+
if (string.IsNullOrEmpty(audiences))
460460
{
461461
return false;
462462
}
@@ -473,7 +473,7 @@ protected virtual bool ValidateAudience(AuthenticationTicket ticket)
473473
return false;
474474
}
475475

476-
protected virtual async Task<AuthenticationTicket> CreateTicketAsync(string token, JObject payload)
476+
private async Task<AuthenticationTicket> CreateTicketAsync(string token, JObject payload)
477477
{
478478
var identity = new ClaimsIdentity(Options.AuthenticationType, Options.NameClaimType, Options.RoleClaimType);
479479
var properties = new AuthenticationProperties();
@@ -728,19 +728,26 @@ protected virtual async Task<AuthenticationTicket> CreateTicketAsync(string toke
728728
return notification.Ticket;
729729
}
730730

731-
protected virtual Task StoreTicketAsync(string token, AuthenticationTicket ticket)
731+
private Task StoreTicketAsync(string token, AuthenticationTicket ticket)
732732
{
733+
if (Options.CachingPolicy == null)
734+
{
735+
return Task.FromResult(0);
736+
}
737+
733738
var bytes = Encoding.UTF8.GetBytes(Options.AccessTokenFormat.Protect(ticket));
734739
Debug.Assert(bytes != null);
735740

736-
return Options.Cache.SetAsync(token, bytes, new DistributedCacheEntryOptions
737-
{
738-
AbsoluteExpiration = Options.SystemClock.UtcNow + TimeSpan.FromMinutes(15)
739-
});
741+
return Options.Cache.SetAsync(token, bytes, Options.CachingPolicy);
740742
}
741743

742-
protected virtual async Task<AuthenticationTicket> RetrieveTicketAsync(string token)
744+
private async Task<AuthenticationTicket> RetrieveTicketAsync(string token)
743745
{
746+
if (Options.CachingPolicy == null)
747+
{
748+
return null;
749+
}
750+
744751
// Retrieve the serialized ticket from the distributed cache.
745752
// If no corresponding entry can be found, null is returned.
746753
var bytes = await Options.Cache.GetAsync(token);
@@ -752,6 +759,6 @@ protected virtual async Task<AuthenticationTicket> RetrieveTicketAsync(string to
752759
return Options.AccessTokenFormat.Unprotect(Encoding.UTF8.GetString(bytes));
753760
}
754761

755-
public ILogger Logger => Options.Logger;
762+
private ILogger Logger => Options.Logger;
756763
}
757764
}

src/Owin.Security.OAuth.Introspection/OAuthIntrospectionHelpers.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ public static string GetProperty([NotNull] this AuthenticationProperties propert
2727
throw new ArgumentException("The property name cannot be null or empty.", nameof(property));
2828
}
2929

30-
string value;
31-
if (!properties.Dictionary.TryGetValue(property, out value))
30+
if (!properties.Dictionary.TryGetValue(property, out string value))
3231
{
3332
return null;
3433
}

src/Owin.Security.OAuth.Introspection/OAuthIntrospectionOptions.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,22 @@ public OAuthIntrospectionOptions()
108108
public string RoleClaimType { get; set; } = OAuthIntrospectionConstants.Claims.Role;
109109

110110
/// <summary>
111-
/// Gets or sets the cache used to store the authentication tickets
112-
/// resolved from the access tokens received by the resource server.
111+
/// Gets or sets the cache used to store the access tokens/authentication tickets
112+
/// and the introspection responses returned received by the resource server.
113113
/// </summary>
114114
public IDistributedCache Cache { get; set; }
115115

116+
/// <summary>
117+
/// Gets or sets the caching policy used to determine
118+
/// how long the introspection responses should be cached.
119+
/// Note: this property can be set to <c>null</c> to
120+
/// prevent the introspection responses from being cached.
121+
/// </summary>
122+
public DistributedCacheEntryOptions CachingPolicy { get; set; } = new DistributedCacheEntryOptions
123+
{
124+
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(15)
125+
};
126+
116127
/// <summary>
117128
/// Gets or sets the object provided by the application to process events raised by the authentication middleware.
118129
/// The application may implement the interface fully, or it may create an instance of

src/Owin.Security.OAuth.Validation/OAuthValidationHandler.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ protected override async Task ApplyResponseChallengeAsync()
328328
}
329329
}
330330

331-
protected virtual bool ValidateAudience(AuthenticationTicket ticket)
331+
private bool ValidateAudience(AuthenticationTicket ticket)
332332
{
333333
// If no explicit audience has been configured,
334334
// skip the default audience validation.
@@ -337,9 +337,9 @@ protected virtual bool ValidateAudience(AuthenticationTicket ticket)
337337
return true;
338338
}
339339

340-
string audiences;
341340
// Extract the audiences from the authentication ticket.
342-
if (!ticket.Properties.Dictionary.TryGetValue(OAuthValidationConstants.Properties.Audiences, out audiences))
341+
var audiences = ticket.Properties.GetProperty(OAuthValidationConstants.Properties.Audiences);
342+
if (string.IsNullOrEmpty(audiences))
343343
{
344344
return false;
345345
}
@@ -356,7 +356,7 @@ protected virtual bool ValidateAudience(AuthenticationTicket ticket)
356356
return false;
357357
}
358358

359-
protected virtual async Task<AuthenticationTicket> CreateTicketAsync(string token)
359+
private async Task<AuthenticationTicket> CreateTicketAsync(string token)
360360
{
361361
var ticket = Options.AccessTokenFormat.Unprotect(token);
362362
if (ticket == null)
@@ -370,10 +370,10 @@ protected virtual async Task<AuthenticationTicket> CreateTicketAsync(string toke
370370
ticket.Properties.Dictionary[OAuthValidationConstants.Properties.Token] = token;
371371
}
372372

373-
string scopes;
374373
// Copy the scopes extracted from the authentication ticket to the
375374
// ClaimsIdentity to make them easier to retrieve from application code.
376-
if (ticket.Properties.Dictionary.TryGetValue(OAuthValidationConstants.Properties.Scopes, out scopes))
375+
var scopes = ticket.Properties.GetProperty(OAuthValidationConstants.Properties.Scopes);
376+
if (!string.IsNullOrEmpty(scopes))
377377
{
378378
foreach (var scope in JArray.Parse(scopes).Values<string>())
379379
{
@@ -404,6 +404,6 @@ protected virtual async Task<AuthenticationTicket> CreateTicketAsync(string toke
404404
return notification.Ticket;
405405
}
406406

407-
public ILogger Logger => Options.Logger;
407+
private ILogger Logger => Options.Logger;
408408
}
409409
}

src/Owin.Security.OAuth.Validation/OAuthValidationHelpers.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ public static string GetProperty([NotNull] this AuthenticationProperties propert
2727
throw new ArgumentException("The property name cannot be null or empty.", nameof(property));
2828
}
2929

30-
string value;
31-
if (!properties.Dictionary.TryGetValue(property, out value))
30+
if (!properties.Dictionary.TryGetValue(property, out string value))
3231
{
3332
return null;
3433
}

0 commit comments

Comments
 (0)