You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shiro.apache.org by fp...@apache.org on 2020/10/20 19:16:37 UTC
[shiro] 01/03: SslFilter with HTTP Strict Transport Security (HSTS)
This is an automated email from the ASF dual-hosted git repository.
fpapon pushed a commit to branch 1.7.x
in repository https://gitbox.apache.org/repos/asf/shiro.git
commit 243e8924420518348141644175fb3dbfe0335f47
Author: Björn Raupach <ra...@e2n.de>
AuthorDate: Tue Jan 10 10:03:36 2017 +0100
SslFilter with HTTP Strict Transport Security (HSTS)
---
.../apache/shiro/web/filter/authz/SslFilter.java | 84 +++++++++++++++++++++-
1 file changed, 82 insertions(+), 2 deletions(-)
diff --git a/web/src/main/java/org/apache/shiro/web/filter/authz/SslFilter.java b/web/src/main/java/org/apache/shiro/web/filter/authz/SslFilter.java
index 3a6ab7a..d85bb23 100644
--- a/web/src/main/java/org/apache/shiro/web/filter/authz/SslFilter.java
+++ b/web/src/main/java/org/apache/shiro/web/filter/authz/SslFilter.java
@@ -20,6 +20,7 @@ package org.apache.shiro.web.filter.authz;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletResponse;
/**
* Filter which requires a request to be over SSL. Access is allowed if the request is received on the configured
@@ -30,21 +31,46 @@ import javax.servlet.ServletResponse;
* The {@link #getPort() port} property defaults to {@code 443} and also additionally guarantees that the
* request scheme is always 'https' (except for port 80, which retains the 'http' scheme).
* <p/>
- * Example config:
+ * In addition the filter allows enabling HTTP Strict Transport Security (HSTS).
+ * This feature is opt-in and disabled by default. If enabled HSTS
+ * will prevent <b>any</b> communications from being sent over HTTP to the
+ * specified domain and will instead send all communications over HTTPS.
+ * </p>
+ * <b>Warning:</b> Use this setting only if you plan to enable SSL on every path.
+ * </p>
+ * Example configs:
* <pre>
* [urls]
* /secure/path/** = ssl
* </pre>
- *
+ * with HSTS enabled
+ * <pre>
+ * [main]
+ * ssl.hsts.enabled = true
+ * [urls]
+ * /** = ssl
+ * </pre>
* @since 1.0
+ * @see <a href="https://tools.ietf.org/html/rfc6797">HTTP Strict Transport Security (HSTS)</a>
*/
public class SslFilter extends PortFilter {
public static final int DEFAULT_HTTPS_PORT = 443;
public static final String HTTPS_SCHEME = "https";
+
+ private HSTS hsts;
public SslFilter() {
setPort(DEFAULT_HTTPS_PORT);
+ this.hsts = new HSTS();
+ }
+
+ public HSTS getHsts() {
+ return hsts;
+ }
+
+ public void setHsts(HSTS hsts) {
+ this.hsts = hsts;
}
@Override
@@ -73,4 +99,58 @@ public class SslFilter extends PortFilter {
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
return super.isAccessAllowed(request, response, mappedValue) && request.isSecure();
}
+
+ @Override
+ protected void postHandle(ServletRequest request, ServletResponse response) throws Exception {
+ if (hsts.enabled) {
+ StringBuilder directives = new StringBuilder(64);
+ directives.append("max-age=").append(hsts.getMaxAge());
+ if (hsts.includeSubDomains) {
+ directives.append("; includeSubDomains");
+ }
+ HttpServletResponse resp = (HttpServletResponse) response;
+ resp.addHeader("Strict-Transport-Security", directives.toString());
+ }
+ }
+
+ public class HSTS {
+
+ static final boolean DEFAULT_ENABLED = false;
+ public static final int DEFAULT_EXPIRE_TIME = 31536000; // approx. one year in seconds
+ public static final boolean DEFAULT_INCLUDE_SUB_DOMAINS = false;
+
+ private boolean enabled;
+ private int maxAge;
+ private boolean includeSubDomains;
+
+ public HSTS() {
+ this.maxAge = DEFAULT_EXPIRE_TIME;
+ this.includeSubDomains = DEFAULT_INCLUDE_SUB_DOMAINS;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public int getMaxAge() {
+ return maxAge;
+ }
+
+ public void setMaxAge(int maxAge) {
+ this.maxAge = maxAge;
+ }
+
+ public boolean isIncludeSubDomains() {
+ return includeSubDomains;
+ }
+
+ public void setIncludeSubDomains(boolean includeSubDomains) {
+ this.includeSubDomains = includeSubDomains;
+ }
+
+ }
}