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();