diff --git a/source/Core/Configuration/DiscoveryOptions.cs b/source/Core/Configuration/DiscoveryOptions.cs index ad87b1f75..69dafbfac 100644 --- a/source/Core/Configuration/DiscoveryOptions.cs +++ b/source/Core/Configuration/DiscoveryOptions.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; namespace IdentityServer3.Core.Configuration { @@ -57,6 +58,14 @@ public class DiscoveryOptions /// public bool ShowTokenEndpointAuthenticationMethods { get; set; } + /// + /// Sets the maxage value of the cache control header. This gives clients a hint how often they should refresh their cached copy of the discovery document (defaults to one hour). + /// + /// + /// The cache interval. + /// + public TimeSpan ClientCacheInterval { get; set; } + /// /// Adds custom entries to the discovery document /// @@ -77,6 +86,7 @@ public DiscoveryOptions() ShowGrantTypes = true; ShowCustomGrantTypes = true; ShowTokenEndpointAuthenticationMethods = true; + ClientCacheInterval = TimeSpan.FromHours(1); CustomEntries = new Dictionary(); } } diff --git a/source/Core/Configuration/Hosting/DiscoveryCacheControlAttribute.cs b/source/Core/Configuration/Hosting/DiscoveryCacheControlAttribute.cs new file mode 100644 index 000000000..3e35fd255 --- /dev/null +++ b/source/Core/Configuration/Hosting/DiscoveryCacheControlAttribute.cs @@ -0,0 +1,25 @@ +using System; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Web.Http.Filters; +using IdentityServer3.Core.Extensions; + +namespace IdentityServer3.Core.Configuration.Hosting +{ + internal class DiscoveryCacheControlAttribute : ActionFilterAttribute + { + public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) + { + base.OnActionExecuted(actionExecutedContext); + + var ctx = actionExecutedContext.Request.GetOwinContext(); + var options = ctx.ResolveDependency(); + SetCache(actionExecutedContext.Response, options.DiscoveryOptions.ClientCacheInterval); + } + + public static void SetCache(HttpResponseMessage response, TimeSpan maxAge) + { + response.Headers.CacheControl = new CacheControlHeaderValue { MaxAge = maxAge }; + } + } +} diff --git a/source/Core/Core.csproj b/source/Core/Core.csproj index e20f24881..8ab5402e2 100644 --- a/source/Core/Core.csproj +++ b/source/Core/Core.csproj @@ -140,6 +140,7 @@ + diff --git a/source/Core/Endpoints/Connect/DiscoveryEndpointController.cs b/source/Core/Endpoints/Connect/DiscoveryEndpointController.cs index c6e23f314..2aa992836 100644 --- a/source/Core/Endpoints/Connect/DiscoveryEndpointController.cs +++ b/source/Core/Endpoints/Connect/DiscoveryEndpointController.cs @@ -31,12 +31,14 @@ using System.Security.Cryptography; using System.Threading.Tasks; using System.Web.Http; +using IdentityServer3.Core.Configuration.Hosting; namespace IdentityServer3.Core.Endpoints { /// /// OpenID Connect discovery document endpoint /// + [DiscoveryCacheControl] internal class DiscoveryEndpointController : ApiController { private readonly static ILog Logger = LogProvider.GetCurrentClassLogger();