好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

springboot清除字符串前后空格与防xss攻击方法

springboot 清除字符串前后空格与防xss攻击

一、查看WebMvcAutoConfiguration.class中的方法源码

?

1

2

3

4

5

6

7

protected ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer() {

     try {

         //从容器中获取

         return (ConfigurableWebBindingInitializer) this .beanFactory.getBean(ConfigurableWebBindingInitializer. class );

     } catch (NoSuchBeanDefinitionException ex) {

       return super .getConfigurableWebBindingInitializer();

     }

可以发现ConfigurableWebBindingInitializer是从容器(beanFactory)中获取到的,所以我们可以配置一个

ConfigurableWebBindingInitializer来替换默认的,只需要在容器中添加一个我们自定义的转换器即可。

当我们创建了自己的ConfigurableWebBindingInitializer这个Bean,Spring boot就会自动使用它来配置Spring MVC实现参数的类型转换。

二、自定义属性编辑器

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

/**

      *

      * @description 与spring mvc的@InitBinder结合 用于防止XSS攻击

      */

      class StringEscapeEditor extends PropertyEditorSupport {

         /** 转义HTML */

         private boolean escapeHTML;

         /** 转义javascript */

         private boolean escapeJavaScript;

         /** 是否将空字符串转换为null */

         private final boolean emptyAsNull;

         /** 是否去掉前后空格 */

         private final boolean trimmed;

         public StringEscapeEditor() {

             this ( true , true , false , true );

         }

         public StringEscapeEditor( boolean escapeHTML, boolean escapeJavaScript) {

             this ( true , true ,escapeHTML,escapeJavaScript);

         }

         public StringEscapeEditor( boolean emptyAsNull, boolean trimmed, boolean escapeHTML, boolean escapeJavaScript) {

             super ();

             this .emptyAsNull = emptyAsNull;

             this .trimmed = trimmed;

             this .escapeHTML = escapeHTML;

             this .escapeJavaScript = escapeJavaScript;

         }

         @Override

         public String getAsText() {

             Object value = getValue();

             if (Objects.nonNull(value))

             {

                 return value.toString();

             }

             return value != null ? value.toString() : null ;

         }

         @Override

         public void setAsText(String text) throws IllegalArgumentException {

             String value = text;

             if (value == null || emptyAsNull && text.isEmpty()) {

                 //do nothing

             } else if (trimmed) {

                 //去字符传参数前后空格

                 value = value.trim();

             }

             if (escapeHTML) {

                 //HTML转义(防止XSS攻击)

                 //HtmlUtils.htmlEscape 默认的是ISO-8859-1编码格式,会将中文的某些符号进行转义。

                 //如果不想让中文符号进行转义请使用UTF-8的编码格式。例如:HtmlUtils.htmlEscape(text, "UTF-8")

                 value = HtmlUtils.htmlEscape(value, "UTF-8" );

             }

             if (escapeJavaScript) {

                 //javascript转义(防止XSS攻击)

                 value = JavaScriptUtils.javaScriptEscape(value);

             }

             setValue(value);

         }

     }

三、创建WebBindingInitializerConfiguration类

加上@Bean注解,交给spring容器管理。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

@Configuration

public class WebBindingInitializerConfiguration {

     @Bean

     public ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer() {

         ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer();

         FormattingConversionService conversionService = new DefaultFormattingConversionService();

         //we can add our custom converters and formatters

         //conversionService.addConverter(...);

         //conversionService.addFormatter(...);

         initializer.setConversionService(conversionService);

         //we can set our custom validator

         //initializer.setValidator(....);

         //here we are setting a custom PropertyEditor

         initializer.setPropertyEditorRegistrar(propertyEditorRegistry -> {

             propertyEditorRegistry.registerCustomEditor(String. class ,

                     new StringEscapeEditor());

         });

         return initializer;

     }

}

springboot去除参数中前后空格说明

一、 需求

使用SpringBoot使用过滤器去除@RequestBody参数两端的空格;一般我们去普通的请求我们都会对请求参数进行验证。

Java也提供了@notNull和@notBlank这种验证方式,但是对@RequestBody 这种只能验证是不是非空,对数据两端的空格未进行处理,同时大家也不想遍历一遍参数然后再处理再封装到对象中,正好项目中有这个需要,所以就参考别的做了Post请求中针对application/json格式的有@RequestBody注解的参数进行了去空格处理

二、 解决方法

2.1 新建一个过滤器

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

@Component

@WebFilter (urlPatterns = "/**" , filterName = "ParamsFilter" , dispatcherTypes = DispatcherType.REQUEST)

public class ParamsFilter implements Filter {

     @Override

     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

             throws IOException, ServletException {

         ParameterRequestWrapper parmsRequest = new ParameterRequestWrapper((HttpServletRequest) request);

         chain.doFilter(parmsRequest, response);

     }

     @Override

     public void init(FilterConfig filterConfig) throws ServletException {

     }

     @Override

     public void destroy() {

     }

}

2.2 实现ParameterRequestWrapper

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

import java.io.ByteArrayInputStream;

import java.io.IOException;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.Iterator;

import java.util.List;

import java.util.Map;

import java.util.Set;

import javax.servlet.ReadListener;

import javax.servlet.ServletInputStream;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletRequestWrapper;

import com.alibaba.fastjson.JSONArray;

import com.alibaba.fastjson.JSONObject;

import org.apache.commons.io.IOUtils;

import org.apache.commons.lang3.StringUtils;

import org.springframework.http.HttpHeaders;

import org.springframework.http.MediaType;

import com.alibaba.fastjson.JSON;

/**

  * @author :

  * @description

  * @date : 2021/4/22

  */

public class ParameterRequestWrapper extends HttpServletRequestWrapper {

     private Map<String , String[]> params = new HashMap<>();

     public ParameterRequestWrapper(HttpServletRequest request) {

         super (request);

         Map<String, String[]> requestMap=request.getParameterMap();

         this .params.putAll(requestMap);

         this .modifyParameterValues();

     }

     @Override

     public ServletInputStream getInputStream() throws IOException {

         if (! super .getHeader(HttpHeaders.CONTENT_TYPE).equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE)){

             return super .getInputStream();

         }

         String json = IOUtils.toString( super .getInputStream(), "utf-8" );

         if (StringUtils.isEmpty(json)) {

             return super .getInputStream();

         }

         Map<String,Object> map= jsonStringToMap(json);

         ByteArrayInputStream bis = new ByteArrayInputStream(JSON.toJSONString(map).getBytes( "utf-8" ));

         return new MyServletInputStream(bis);

     }

     public void modifyParameterValues(){

         Set<String> set = params.keySet();

         Iterator<String> it = set.iterator();

         while (it.hasNext()){

             String key= it.next();

             String[] values = params.get(key);

             values[ 0 ] = values[ 0 ].trim();

             params.put(key, values);

         }

     }

     @Override

     public String getParameter(String name) {

         String[]values = params.get(name);

         if (values == null || values.length == 0 ) {

             return null ;

         }

         return values[ 0 ];

     }

     @Override

     public String[] getParameterValues(String name) {

         return params.get(name);

     }

     class MyServletInputStream extends ServletInputStream {

         private ByteArrayInputStream bis;

         public MyServletInputStream(ByteArrayInputStream bis){

             this .bis=bis;

         }

         @Override

         public boolean isFinished() {

             return true ;

         }

         @Override

         public boolean isReady() {

             return true ;

         }

         @Override

         public void setReadListener(ReadListener listener) {

         }

         @Override

         public int read(){

             return bis.read();

         }

     }

     public static Map<String, Object> jsonStringToMap(String jsonString) {

         Map<String, Object> map = new HashMap<>();

         JSONObject jsonObject = JSONObject.parseObject(jsonString);

         for (Object k : jsonObject.keySet()) {

             Object o = jsonObject.get(k);

             if (o instanceof JSONArray) {

                 List<Map<String, Object>> list = new ArrayList<>();

                 Iterator<Object> it = ((JSONArray) o).iterator();

                 while (it.hasNext()) {

                     Object obj = it.next();

                     list.add(jsonStringToMap(obj.toString()));

                 }

                 map.put(k.toString(), list);

             } else if (o instanceof JSONObject) {

                 map.put(k.toString(), jsonStringToMap(o.toString()));

             } else {

                 if (o instanceof String) {

                     map.put(k.toString(), o.toString().trim());

                 } else {

                     map.put(k.toString(), o);

                 }

             }

         }

         return map;

     }

}

三、 完美解决

参数前后空格完美去除!

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

原文链接:https://www.jianshu.com/p/2b8ac1adb7a1

查看更多关于springboot清除字符串前后空格与防xss攻击方法的详细内容...

  阅读:25次