Fix to many request filter usage in DDI (#526)
* Fix DOS filter usage in DDI Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Add optional CSP definition. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Fix for empty case. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * readability and ensure that manual enforcement is also possible in timeforced active but no hit yet. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Class order to bean order. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Fix exception propagation. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
package org.eclipse.hawkbit.security;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -23,6 +24,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
@@ -40,6 +42,9 @@ public class DosFilter extends OncePerRequestFilter {
|
||||
private static final Logger LOG_BLACKLIST = LoggerFactory
|
||||
.getLogger(SecurityConstants.SECURITY_LOG_PREFIX + ".blacklist");
|
||||
|
||||
private final AntPathMatcher antMatcher = new AntPathMatcher();
|
||||
private final Collection<String> includeAntPaths;
|
||||
|
||||
private final Pattern ipAdressBlacklist;
|
||||
|
||||
private final Cache<String, AtomicInteger> readCountCache = Caffeine.newBuilder()
|
||||
@@ -57,6 +62,9 @@ public class DosFilter extends OncePerRequestFilter {
|
||||
|
||||
/**
|
||||
* Filter constructor including configuration.
|
||||
*
|
||||
* @param includeAntPaths
|
||||
* paths where filter should hit
|
||||
*
|
||||
* @param maxRead
|
||||
* Maximum number of allowed REST read/GET requests per second
|
||||
@@ -73,9 +81,10 @@ public class DosFilter extends OncePerRequestFilter {
|
||||
* the header containing the forwarded IP address e.g.
|
||||
* {@code x-forwarded-for}
|
||||
*/
|
||||
public DosFilter(final int maxRead, final int maxWrite, final String ipDosWhiteListPattern,
|
||||
final String ipBlackListPattern, final String forwardHeader) {
|
||||
public DosFilter(final Collection<String> includeAntPaths, final int maxRead, final int maxWrite,
|
||||
final String ipDosWhiteListPattern, final String ipBlackListPattern, final String forwardHeader) {
|
||||
|
||||
this.includeAntPaths = includeAntPaths;
|
||||
this.maxRead = maxRead;
|
||||
this.maxWrite = maxWrite;
|
||||
this.forwardHeader = forwardHeader;
|
||||
@@ -93,10 +102,24 @@ public class DosFilter extends OncePerRequestFilter {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldInclude(final HttpServletRequest request) {
|
||||
if (includeAntPaths == null || includeAntPaths.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return includeAntPaths.stream()
|
||||
.anyMatch(pattern -> antMatcher.match(request.getContextPath() + pattern, request.getRequestURI()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response,
|
||||
final FilterChain filterChain) throws ServletException, IOException {
|
||||
|
||||
if (!shouldInclude(request)) {
|
||||
filterChain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean processChain;
|
||||
|
||||
final String ip = IpUtil.getClientIpFromRequest(request, forwardHeader).getHost();
|
||||
|
||||
@@ -27,14 +27,13 @@ import org.springframework.web.filter.ShallowEtagHeaderFilter;
|
||||
public class ExcludePathAwareShallowETagFilter extends ShallowEtagHeaderFilter {
|
||||
|
||||
private final String[] excludeAntPaths;
|
||||
private final AntPathMatcher antMatcher;
|
||||
private final AntPathMatcher antMatcher = new AntPathMatcher();
|
||||
|
||||
/**
|
||||
* @param excludeAntPaths
|
||||
*/
|
||||
public ExcludePathAwareShallowETagFilter(final String... excludeAntPaths) {
|
||||
this.excludeAntPaths = excludeAntPaths;
|
||||
this.antMatcher = new AntPathMatcher();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,6 +20,19 @@ public class HawkbitSecurityProperties {
|
||||
private final Clients clients = new Clients();
|
||||
private final Dos dos = new Dos();
|
||||
|
||||
/**
|
||||
* Content Security policy Header for Manager UI.
|
||||
*/
|
||||
private String contentSecurityPolicy;
|
||||
|
||||
public String getContentSecurityPolicy() {
|
||||
return contentSecurityPolicy;
|
||||
}
|
||||
|
||||
public void setContentSecurityPolicy(final String contentSecurityPolicy) {
|
||||
this.contentSecurityPolicy = contentSecurityPolicy;
|
||||
}
|
||||
|
||||
public Dos getDos() {
|
||||
return dos;
|
||||
}
|
||||
|
||||
@@ -98,6 +98,8 @@ public class SystemSecurityContext {
|
||||
setSystemContext(SecurityContextHolder.getContext());
|
||||
return callable.call();
|
||||
|
||||
} catch (final RuntimeException e) {
|
||||
throw e;
|
||||
} catch (final Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user