Add preload support to Strict-Transport-Security
1. Preload support in Servlet Security(XML & Java) 2. Preload support in Reactive Security 3. Test for preload support in Servlet Security 4. Test for preload support in Reactive Security Fixes: gh-6312
This commit is contained in:
+68
-10
@@ -30,9 +30,10 @@ import org.springframework.util.Assert;
|
||||
* Security (HSTS)</a>.
|
||||
*
|
||||
* <p>
|
||||
* By default the expiration is one year and subdomains will be included. This can be
|
||||
* customized using {@link #setMaxAgeInSeconds(long)} and
|
||||
* {@link #setIncludeSubDomains(boolean)} respectively.
|
||||
* By default the expiration is one year, subdomains will be included and preload will not
|
||||
* be included. This can be customized using {@link #setMaxAgeInSeconds(long)},
|
||||
* {@link #setIncludeSubDomains(boolean)} and {@link #setPreload(boolean)}
|
||||
* respectively.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
@@ -46,6 +47,11 @@ import org.springframework.util.Assert;
|
||||
* {@link RequestMatcher}.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* See <a href="https://hstspreload.org/">Website hstspreload.org</a>
|
||||
* for additional details on HSTS preload.
|
||||
* </p>
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @since 3.2
|
||||
*/
|
||||
@@ -62,8 +68,29 @@ public final class HstsHeaderWriter implements HeaderWriter {
|
||||
|
||||
private boolean includeSubDomains;
|
||||
|
||||
private boolean preload;
|
||||
|
||||
private String hstsHeaderValue;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param requestMatcher maps to {@link #setRequestMatcher(RequestMatcher)}
|
||||
* @param maxAgeInSeconds maps to {@link #setMaxAgeInSeconds(long)}
|
||||
* @param includeSubDomains maps to {@link #setIncludeSubDomains(boolean)}
|
||||
* @param preload maps to {@link #setPreload(boolean)}
|
||||
* @since 5.2.0
|
||||
* @author Ankur Pathak
|
||||
*/
|
||||
public HstsHeaderWriter(RequestMatcher requestMatcher, long maxAgeInSeconds,
|
||||
boolean includeSubDomains, boolean preload) {
|
||||
this.requestMatcher = requestMatcher;
|
||||
this.maxAgeInSeconds = maxAgeInSeconds;
|
||||
this.includeSubDomains = includeSubDomains;
|
||||
this.preload = preload;
|
||||
updateHstsHeaderValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
@@ -73,10 +100,20 @@ public final class HstsHeaderWriter implements HeaderWriter {
|
||||
*/
|
||||
public HstsHeaderWriter(RequestMatcher requestMatcher, long maxAgeInSeconds,
|
||||
boolean includeSubDomains) {
|
||||
this.requestMatcher = requestMatcher;
|
||||
this.maxAgeInSeconds = maxAgeInSeconds;
|
||||
this.includeSubDomains = includeSubDomains;
|
||||
updateHstsHeaderValue();
|
||||
this(requestMatcher, maxAgeInSeconds, includeSubDomains, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param maxAgeInSeconds maps to {@link #setMaxAgeInSeconds(long)}
|
||||
* @param includeSubDomains maps to {@link #setIncludeSubDomains(boolean)}
|
||||
* @param preload maps to {@link #setPreload(boolean)}
|
||||
* @since 5.2.0
|
||||
* @author Ankur Pathak
|
||||
*/
|
||||
public HstsHeaderWriter(long maxAgeInSeconds, boolean includeSubDomains, boolean preload) {
|
||||
this(new SecureRequestMatcher(), maxAgeInSeconds, includeSubDomains, preload);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -86,7 +123,7 @@ public final class HstsHeaderWriter implements HeaderWriter {
|
||||
* @param includeSubDomains maps to {@link #setIncludeSubDomains(boolean)}
|
||||
*/
|
||||
public HstsHeaderWriter(long maxAgeInSeconds, boolean includeSubDomains) {
|
||||
this(new SecureRequestMatcher(), maxAgeInSeconds, includeSubDomains);
|
||||
this(new SecureRequestMatcher(), maxAgeInSeconds, includeSubDomains, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,7 +132,7 @@ public final class HstsHeaderWriter implements HeaderWriter {
|
||||
* @param maxAgeInSeconds maps to {@link #setMaxAgeInSeconds(long)}
|
||||
*/
|
||||
public HstsHeaderWriter(long maxAgeInSeconds) {
|
||||
this(new SecureRequestMatcher(), maxAgeInSeconds, true);
|
||||
this(new SecureRequestMatcher(), maxAgeInSeconds, true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,7 +141,7 @@ public final class HstsHeaderWriter implements HeaderWriter {
|
||||
* @param includeSubDomains maps to {@link #setIncludeSubDomains(boolean)}
|
||||
*/
|
||||
public HstsHeaderWriter(boolean includeSubDomains) {
|
||||
this(new SecureRequestMatcher(), DEFAULT_MAX_AGE_SECONDS, includeSubDomains);
|
||||
this(new SecureRequestMatcher(), DEFAULT_MAX_AGE_SECONDS, includeSubDomains, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -186,12 +223,33 @@ public final class HstsHeaderWriter implements HeaderWriter {
|
||||
this.includeSubDomains = includeSubDomains;
|
||||
updateHstsHeaderValue();
|
||||
}
|
||||
/**
|
||||
* <p>
|
||||
* If true, preload will be included in HSTS Header. The default is false.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* See <a href="http://tools.ietf.org/html/rfc6797#section-6.1.2">Section 6.1.2</a>
|
||||
* for additional details.
|
||||
* </p>
|
||||
*
|
||||
* @param preload true to include preload, else false
|
||||
* @since 5.2.0
|
||||
* @autor Ankur Pathak
|
||||
*/
|
||||
public void setPreload(boolean preload) {
|
||||
this.preload = preload;
|
||||
updateHstsHeaderValue();
|
||||
}
|
||||
|
||||
private void updateHstsHeaderValue() {
|
||||
String headerValue = "max-age=" + this.maxAgeInSeconds;
|
||||
if (this.includeSubDomains) {
|
||||
headerValue += " ; includeSubDomains";
|
||||
}
|
||||
if (this.preload) {
|
||||
headerValue += " ; preload";
|
||||
}
|
||||
this.hstsHeaderValue = headerValue;
|
||||
}
|
||||
|
||||
|
||||
+22
-1
@@ -34,6 +34,8 @@ public final class StrictTransportSecurityServerHttpHeadersWriter
|
||||
|
||||
private String subdomain;
|
||||
|
||||
private String preload;
|
||||
|
||||
private ServerHttpHeadersWriter delegate;
|
||||
|
||||
/**
|
||||
@@ -42,6 +44,7 @@ public final class StrictTransportSecurityServerHttpHeadersWriter
|
||||
public StrictTransportSecurityServerHttpHeadersWriter() {
|
||||
setIncludeSubDomains(true);
|
||||
setMaxAge(Duration.ofDays(365L));
|
||||
setPreload(false);
|
||||
updateDelegate();
|
||||
}
|
||||
|
||||
@@ -62,6 +65,24 @@ public final class StrictTransportSecurityServerHttpHeadersWriter
|
||||
updateDelegate();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Sets if preload should be included. Default is false
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* See <a href="https://hstspreload.org/">Website hstspreload.org</a>
|
||||
* for additional details.
|
||||
* </p>
|
||||
* @param preload if preload should be included
|
||||
* @since 5.2.0
|
||||
* @author Ankur Pathak
|
||||
*/
|
||||
public void setPreload(boolean preload) {
|
||||
this.preload = preload ? " ; preload" : "";
|
||||
updateDelegate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the max age of the header. Default is a year.
|
||||
* @param maxAge the max age of the header
|
||||
@@ -73,7 +94,7 @@ public final class StrictTransportSecurityServerHttpHeadersWriter
|
||||
|
||||
private void updateDelegate() {
|
||||
delegate = StaticServerHttpHeadersWriter.builder()
|
||||
.header(STRICT_TRANSPORT_SECURITY, maxAge + subdomain)
|
||||
.header(STRICT_TRANSPORT_SECURITY, maxAge + subdomain + preload)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user