Skip to content

Commit

Permalink
SslFilter with HTTP Strict Transport Security (HSTS)
Browse files Browse the repository at this point in the history
  • Loading branch information
raupach-e2n authored and fpapon committed Oct 20, 2020
1 parent 74d4cb6 commit 243e892
Showing 1 changed file with 82 additions and 2 deletions.
84 changes: 82 additions & 2 deletions web/src/main/java/org/apache/shiro/web/filter/authz/SslFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

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
Expand All @@ -30,21 +31,46 @@
* 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
Expand Down Expand Up @@ -73,4 +99,58 @@ protected String getScheme(String requestScheme, int port) {
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;
}

}
}

0 comments on commit 243e892

Please sign in to comment.