zoukankan      html  css  js  c++  java
  • spring-security使用-安全防护HttpFirewall(七)

    类图

     默认提供2种实现 defaultfHttpFirewall 看源码可以看出来比较宽松,我们一般使用StrictHttpFirewall

    限制请求方法

    如果需要修改可以自定义StrictHttpFirewall 

    public class StrictHttpFirewall implements HttpFirewall {
        //空的集合
        private static final Set<String> ALLOW_ANY_HTTP_METHOD = Collections.unmodifiableSet(Collections.emptySet());
        private Set<String> allowedHttpMethods = createDefaultAllowedHttpMethods();
        //设置允许的请求方式
        private static Set<String> createDefaultAllowedHttpMethods() {
            Set<String> result = new HashSet();
            result.add(HttpMethod.DELETE.name());
            result.add(HttpMethod.GET.name());
            result.add(HttpMethod.HEAD.name());
            result.add(HttpMethod.OPTIONS.name());
            result.add(HttpMethod.PATCH.name());
            result.add(HttpMethod.POST.name());
            result.add(HttpMethod.PUT.name());
            return result;
        }
        public void setUnsafeAllowAnyHttpMethod(boolean unsafeAllowAnyHttpMethod) {
            //如果是false则设置空的集合
            this.allowedHttpMethods = unsafeAllowAnyHttpMethod ? ALLOW_ANY_HTTP_METHOD : createDefaultAllowedHttpMethods();
        }
    
        private void rejectForbiddenHttpMethod(HttpServletRequest request) {
            if (this.allowedHttpMethods != ALLOW_ANY_HTTP_METHOD) {
                //如果不存在运行的方法里面 则抛出异常
                if (!this.allowedHttpMethods.contains(request.getMethod())) {
                    throw new RequestRejectedException("The request was rejected because the HTTP method "" + request.getMethod() + "" was not included within the whitelist " + this.allowedHttpMethods);
                }
            }
        }
    }

    使用方式

    @Bean
    HttpFirewall httpFirewall() {
        StrictHttpFirewall firewall = new StrictHttpFirewall();
        firewall.setUnsafeAllowAnyHttpMethod(true);
        return firewall;
    }

    请求地址不能有分号

    如地址:http://localhost:8080/index;id=ddd

    public class StrictHttpFirewall implements HttpFirewall {
        private Set<String> encodedUrlBlacklist = new HashSet();
        private Set<String> decodedUrlBlacklist = new HashSet();
    
        //;的urlecod和decode的几种
        private static final List<String> FORBIDDEN_SEMICOLON = Collections.unmodifiableList(Arrays.asList(";", "%3b", "%3B"));
        public void setAllowSemicolon(boolean allowSemicolon) {
            //如果是false则删除调
            if (allowSemicolon) {
                this.urlBlacklistsRemoveAll(FORBIDDEN_SEMICOLON);
            } else {
                this.urlBlacklistsAddAll(FORBIDDEN_SEMICOLON);
            }
        }
        //加入到校验list
        private void urlBlacklistsAddAll(Collection<String> values) {
            this.encodedUrlBlacklist.addAll(values);
            this.decodedUrlBlacklist.addAll(values);
        }
        //清除到校验list
        private void urlBlacklistsRemoveAll(Collection<String> values) {
            this.encodedUrlBlacklist.removeAll(values);
            this.decodedUrlBlacklist.removeAll(values);
        }
    
        private void rejectedBlacklistedUrls(HttpServletRequest request) {
            Iterator var2 = this.encodedUrlBlacklist.iterator();
    
            String forbidden;
            do {
                if (!var2.hasNext()) {
                    var2 = this.decodedUrlBlacklist.iterator();
    
                    do {
                        if (!var2.hasNext()) {
                            return;
                        }
    
                        forbidden = (String)var2.next();
                    } while(!decodedUrlContains(request, forbidden));
    
                    throw new RequestRejectedException("The request was rejected because the URL contained a potentially malicious String "" + forbidden + """);
                }
    
                forbidden = (String)var2.next();
            } while(!encodedUrlContains(request, forbidden));
    
            throw new RequestRejectedException("The request was rejected because the URL contained a potentially malicious String "" + forbidden + """);
        }
    }

    必须是可打印的 ASCII 字符

    private static boolean containsOnlyPrintableAsciiCharacters(String uri) {
        int length = uri.length();
        for (int i = 0; i < length; i++) {
            char c = uri.charAt(i);
            if (c < 'u0020' || c > 'u007e') {
                return false;
            }
        }
        return true;
    }

    不能使用双斜杠

    @Bean
    HttpFirewall httpFirewall() {
        StrictHttpFirewall firewall = new StrictHttpFirewall();
        firewall.setAllowUrlEncodedDoubleSlash(true);
        return firewall;
    }

    % 不被允许

    如果需要去掉

    @Bean
    HttpFirewall httpFirewall() {
        StrictHttpFirewall firewall = new StrictHttpFirewall();
    //允许%的配置 firewall.setAllowUrlEncodedPercent(
    true); return firewall; }

    反斜杠不被允许

    如果需要去掉

    @Bean
    HttpFirewall httpFirewall() {
        StrictHttpFirewall firewall = new StrictHttpFirewall();
        firewall.setAllowBackSlash(true);
        firewall.setAllowUrlEncodedSlash(true);
        return firewall;
    }

    . 不被允许

    如果需要去掉

    @Bean
    HttpFirewall httpFirewall() {
        StrictHttpFirewall firewall = new StrictHttpFirewall();
        firewall.setAllowUrlEncodedPeriod(true);
        return firewall;
    }

    入口处

      public FirewalledRequest getFirewalledRequest(HttpServletRequest request) throws RequestRejectedException {
            this.rejectForbiddenHttpMethod(request);
            this.rejectedBlacklistedUrls(request);
            this.rejectedUntrustedHosts(request);
            if (!isNormalized(request)) {
                throw new RequestRejectedException("The request was rejected because the URL was not normalized.");
            } else {
                String requestUri = request.getRequestURI();
                if (!containsOnlyPrintableAsciiCharacters(requestUri)) {
                    throw new RequestRejectedException("The requestURI was rejected because it can only contain printable ASCII characters.");
                } else {
                    return new FirewalledRequest(request) {
                        public void reset() {
                        }
                    };
                }
            }
        }
  • 相关阅读:
    Eclipse / android studio 添加第三方jar包 步骤
    Android checkbox 自定义点击效果
    Android 程序打包和安装过程
    Android 基础
    (转)Genymotion安装virtual device的“unable to create virtual device, Server returned Http status code 0”的解决方法
    (转)eclipse 导入Android 项目 步骤
    微信开放平台注册 步骤
    Android Studio 初级安装
    数组
    作用域问题代码
  • 原文地址:https://www.cnblogs.com/LQBlog/p/14343497.html
Copyright © 2011-2022 走看看