[关闭]
@zhanjindong 2015-02-12T02:10:21.000000Z 字数 11722 阅读 2892

ossp-framework 1.0.2-SNAPSHOT

iFlytek

Javadoc http://172.16.82.32:8282/framework-doc/1.0.2-SNAPSHOT/javadoc


安全类库

调研文档 https://192.168.75.168:8888/svn/YHZ_OSSP2.2/Trunk/Project/03.Study/应用安全/应用程序安全问题调研文档_OSSP2.2.doc

POM依赖

  1. <dependency>
  2. <groupId>com.iflytek</groupId>
  3. <artifactId>ossp-framework-security</artifactId>
  4. <version>1.0.2-SNAPSHOT</version>
  5. </dependency>

主要包

描述
com.iflytek.ossp.framework.security.cleaners 提供相关类用于对用户的非法输入进行过滤和清理。
com.iflytek.ossp.framework.security.codecs Base64比org.apache.commons.codec.binary.Base64.Base64要更快。
com.iflytek.ossp.framework.security.crypto 提供信息加密相关的类或接口,防止敏感信息泄露。
com.iflytek.ossp.framework.security.validation 提供相关的类用于对用户的输入进行合法性验证。
com.iflytek.ossp.framework.security.wrappers 提供一些安全相关的HttpServletRequestWrapper和HttpServletResponseWrapper的封装。
com.iflytek.ossp.framework.security.filters 提供一些用于Servlet程序的过滤器,通过在web.xml简单的配置来防御一些常见的攻击,如:XSS和CSRF.

其中最主要的是com.iflytek.ossp.framework.security.filters这个包,它包含了几个实用的Servlet过滤器:

过滤器 描述
ClickjackFilter (Click Jacking)点击劫持过滤器
CsrfRefererFilter 基于Referer的CSRF过滤器
CsrfStatelessCookieFilter 基于无状态Coooie和请求令牌的CSRF(跨站请求伪造)过滤器
EncryptUrlFilter 提供了一个对URL参数进行解密的过滤器
RequestRateThrottleFilter 用来限制客户端请求的频率
SqlInjectionFilter 简单的SQL注入过滤器
XssFilter XSS(跨站脚本攻击)过滤器

使用方法很简单,以XssFilter为例,web.xml配置如下:

  1. <filter>
  2. <filter-name>xssFilter</filter-name>
  3. <filter-class>com.iflytek.ossp.framework.security.filters.XssFilter</filter-class>
  4. </filter>
  5. <filter-mapping>
  6. <filter-name>xssFilter</filter-name>
  7. <url-pattern>/security/xss.jsp</url-pattern>
  8. </filter-mapping>

有的过滤器可能会有参数,具体请参看[Javadoc]http://172.16.82.32:8282/framework-doc/1.0.2-SNAPSHOT/javadoc


log4j和logback

  1. public class LoggerFactoryExample {
  2. // 因为同时存在log4j和logback两个日志系统,如果使用slf4j不同的情况绑定的具体日志系统不确定,
  3. // 所以这种情况建议直接使用log4j api
  4. private static Logger log4jLogger = Logger.getLogger(LoggerFactoryExample.class);
  5. // logback 只能通过slf4j facade来访问
  6. private static org.slf4j.Logger logbackLogger = LogbackFactory.getLogger(LoggerFactoryExample.class);
  7. public static void main(String[] args) {
  8. log4jLogger.debug("log4j debug");
  9. logbackLogger.debug("logback debug");
  10. }
  11. }
  1. public class ExtendedLoggerExample {
  2. private static ExtendedLogger logger = ExtendedLogger.getLogger(ExtendedLoggerExample.class);
  3. private static final ExtendedLevel BIZLOG = new ExtendedLevel(70000, "BIZLOG");
  4. private static final ExtendedLevel BIZLOG2 = new ExtendedLevel(80000, "BIZLOG2");
  5. public static void main(String[] args) {
  6. ExtendedLogger.register(new ExtendedLevel[] { BIZLOG, BIZLOG2 });
  7. logger.debug("ExtendedLogger debug test!");
  8. logger.error("ExtendedLogger error test!");
  9. logger.log(BIZLOG, "ExtendedLogger biz log test!");
  10. logger.log(BIZLOG2, "ExtendedLogger biz log2 test!");
  11. }
  12. }

log4j配置文件示例:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE log4j:configuration PUBLIC "-//log4j/log4j Configuration//EN" "log4j.dtd">
  3. <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
  4. threshold="null" debug="null">
  5. <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
  6. <param name="Target" value="System.out" />
  7. <layout class="org.apache.log4j.PatternLayout">
  8. <param name="ConversionPattern"
  9. value="%-d{yyyy-MM-dd HH:mm:ss.SSS} [ %t:%r ] - [ %p ] %m%n" />
  10. </layout>
  11. </appender>
  12. <appender name="D" class="org.apache.log4j.DailyRollingFileAppender">
  13. <param name="File" value="D:/temp/debug.log" />
  14. <layout class="org.apache.log4j.PatternLayout">
  15. <param name="ConversionPattern" value="%m%n" />
  16. </layout>
  17. <filter class="org.apache.log4j.varia.LevelRangeFilter">
  18. <param name="LevelMin" value="debug" />
  19. <param name="LevelMax" value="debug" />
  20. </filter>
  21. </appender>
  22. <appender name="E" class="org.apache.log4j.DailyRollingFileAppender">
  23. <param name="File" value="D:/temp/error" />
  24. <layout class="org.apache.log4j.PatternLayout">
  25. <param name="ConversionPattern" value="%m%n" />
  26. </layout>
  27. <filter class="org.apache.log4j.varia.LevelRangeFilter">
  28. <param name="LevelMin" value="error" />
  29. <param name="LevelMax" value="fatal" />
  30. </filter>
  31. </appender>
  32. <!-- 自定义日志级别BIZLOG -->
  33. <appender name="Ext" class="org.apache.log4j.DailyRollingFileAppender">
  34. <param name="File" value="D:/temp/ext" />
  35. <layout class="org.apache.log4j.PatternLayout">
  36. <param name="ConversionPattern"
  37. value="%-d{yyyy-MM-dd HH:mm:ss.SSS} [ %t:%r ] - [ %p ] %m%n" />
  38. </layout>
  39. <filter class="com.iflytek.ossp.framework.common.log.ExtendedFilter">
  40. <param name="LevelMin" value="BIZLOG" />
  41. <param name="LevelMax" value="BIZLOG" />
  42. </filter>
  43. </appender>
  44. <!-- 自定义日志级别BIZLOG2 -->
  45. <appender name="Ext2" class="org.apache.log4j.DailyRollingFileAppender">
  46. <param name="File" value="D:/temp/ext2" />
  47. <layout class="org.apache.log4j.PatternLayout">
  48. <param name="ConversionPattern"
  49. value="%-d{yyyy-MM-dd HH:mm:ss.SSS} [ %t:%r ] - [ %p ] %m%n" />
  50. </layout>
  51. <filter class="com.iflytek.ossp.framework.common.log.ExtendedFilter">
  52. <param name="LevelMin" value="BIZLOG2" />
  53. <param name="LevelMax" value="BIZLOG2" />
  54. </filter>
  55. </appender>
  56. <root>
  57. <level value="DEBUG" />
  58. <appender-ref ref="D" />
  59. <appender-ref ref="E" />
  60. <appender-ref ref="Ext" />
  61. <appender-ref ref="Ext2" />
  62. </root>
  63. </log4j:configuration>

logback配置文件示例:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <configuration>
  3. <!-- 控制台输出 -->
  4. <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
  5. <encoder>
  6. <pattern>%date [%thread] %-5level %logger{80} - %msg%n</pattern>
  7. </encoder>
  8. </appender>
  9. <!-- 时间滚动输出 level为 DEBUG 日志 -->
  10. <appender name="D"
  11. class="ch.qos.logback.core.rolling.RollingFileAppender">
  12. <filter class="ch.qos.logback.classic.filter.LevelFilter">
  13. <level>DEBUG</level>
  14. <onMatch>ACCEPT</onMatch>
  15. <onMismatch>DENY </onMismatch>
  16. </filter>
  17. <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
  18. <FileNamePattern>D:/temp/debug.%d{yyyy-MM-dd}.log</FileNamePattern>
  19. <MaxHistory>30</MaxHistory>
  20. </rollingPolicy>
  21. <encoder>
  22. <pattern>%msg%n</pattern>
  23. </encoder>
  24. </appender>
  25. <!-- 时间滚动输出 level为 ERROR 日志 -->
  26. <appender name="E"
  27. class="ch.qos.logback.core.rolling.RollingFileAppender">
  28. <filter class="ch.qos.logback.classic.filter.LevelFilter">
  29. <level>ERROR</level>
  30. <onMatch>ACCEPT</onMatch>
  31. <onMismatch>DENY </onMismatch>
  32. </filter>
  33. <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
  34. <FileNamePattern>D:/temp/error.%d{yyyy-MM-dd}.log</FileNamePattern>
  35. <MaxHistory>30</MaxHistory>
  36. </rollingPolicy>
  37. <encoder>
  38. <pattern>%date [%thread] %-5level %logger{80} - %msg%n</pattern>
  39. </encoder>
  40. </appender>
  41. <appender name="BIZLOG"
  42. class="ch.qos.logback.core.rolling.RollingFileAppender">
  43. <filter class="ch.qos.logback.classic.filter.LevelFilter">
  44. <level>INFO</level>
  45. <onMatch>ACCEPT</onMatch>
  46. <onMismatch>DENY </onMismatch>
  47. </filter>
  48. <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
  49. <!-- 一分钟产生一个文件 -->
  50. <FileNamePattern>D:/temp/biz-%d{yyyyMMddHHmm}.log</FileNamePattern>
  51. <MaxHistory>-1</MaxHistory>
  52. </rollingPolicy>
  53. <encoder>
  54. <pattern>%msg%n</pattern>
  55. </encoder>
  56. </appender>
  57. <!-- 使用异步appender -->
  58. <appender name="ASYNC_BIZLOG" class="ch.qos.logback.classic.AsyncAppender">
  59. <queueSize>500</queueSize>
  60. <discardingThreshold>0</discardingThreshold>
  61. <appender-ref ref="BIZLOG" />
  62. </appender>
  63. <!-- 用来单独记录业务日志 -->
  64. <logger level="INFO" name="bizlog">
  65. <appender-ref ref="ASYNC_BIZLOG" />
  66. </logger>
  67. <root level="DEBUG">
  68. <appender-ref ref="D" />
  69. <appender-ref ref="E" />
  70. </root>
  71. </configuration>

Fastjson API 功能改进

@JSONField注解增加implict,使用 @JSONField(name = "bitem", implicit = true)代替XStream的 @XStreamImplicit(itemFieldName = "bitem"),目前仅支持对List 使用implicit的。

  1. @JSONField(name = "key", implicit = true)
  2. @XStreamImplicit(itemFieldName = "key")
  3. public List<String> lists;

@JSONType注解增加name,支持类似XStream对类进行别名处理的功能

  1. @XStreamAlias("abc")
  2. @JSONType(name = "abc")
  3. public static class A {

详细的示例代码

  1. package com.iflytek.ossp.framework.example.common.serializable;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import com.alibaba.fastjson.annotation.JSONField;
  5. import com.alibaba.fastjson.annotation.JSONType;
  6. import com.alibaba.fastjson.serializer.SerializerFeature;
  7. import com.iflytek.ossp.framework.common.serializable.JSONRoot;
  8. import com.iflytek.ossp.framework.common.serializable.SerializationInstance;
  9. import com.iflytek.ossp.framework.common.serializable.SerializationTools;
  10. import com.iflytek.ossp.framework.common.text.NormalizationUtils;
  11. import com.thoughtworks.xstream.annotations.XStreamAlias;
  12. import com.thoughtworks.xstream.annotations.XStreamImplicit;
  13. import com.thoughtworks.xstream.annotations.XStreamOmitField;
  14. /**
  15. * Fastjson API使用示例。
  16. * <p>
  17. * {@link SerializationTools#fastFromJson(Class, String)}<br />
  18. * {@link SerializationTools#fastToJson(Object)}<br />
  19. * 官方版本fastjson不支持类似XStream <code>@XStreamImplicit</code>的特性,fork了官方1.1.41版本:<a
  20. * href="https://github.com/zhanjindong/fastjson-1.1.41"
  21. * >https://github.com/zhanjindong/fastjson-1.1.41</a><br />
  22. * <code>@JSONField</code>注解增加implict,使用
  23. * <code>@JSONField(name = "bitem", implicit = true)</code>代替XStream的
  24. * <code>@XStreamImplicit(itemFieldName = "bitem")</code>,目前仅支持对{@link List}
  25. * 使用implicit的。
  26. *
  27. * @author jdzhan,2014-8-21
  28. *
  29. */
  30. public class FastjsonExample {
  31. static SerializationInstance tools = SerializationInstance.sharedInstance();
  32. public static void main(String[] args) throws IllegalStateException, Exception {
  33. // annotationBenchmark();
  34. fastJsonExample();
  35. }
  36. public static void fastJsonExample() throws SecurityException, IllegalArgumentException, NoSuchFieldException,
  37. IllegalAccessException {
  38. A a = new A();
  39. a.setStr1("str1");
  40. a.setStr2("str2");
  41. List<String> list = new ArrayList<String>();
  42. list.add("item1");
  43. list.add("item1");
  44. a.setLists(list);
  45. List<B> barr = new ArrayList<FastjsonExample.B>();
  46. for (int i = 0; i < 2; i++) {
  47. B b = new B();
  48. b.setBstr1("b str1");
  49. b.setBstr2("b str2");
  50. barr.add(b);
  51. }
  52. a.setBarr(barr);
  53. // fastjson
  54. String json = tools.fastToJson(a, true);
  55. System.out.println("fastjson result:\r\n" + json);
  56. A newA = tools.fastFromJson(A.class, json);
  57. System.out.println(newA);
  58. // xstream
  59. String xjson = tools.toJson(a);
  60. System.out.println("xstream result:" + NormalizationUtils.normalizeJson(json));
  61. }
  62. @XStreamAlias("abc")
  63. @JSONType(name = "abc")
  64. public static class A {
  65. /** 忽略 */
  66. @JSONField(serialize = false)
  67. // fastjson
  68. @XStreamOmitField
  69. // xstream
  70. public String str1 = "str1";
  71. /** 指定别名 */
  72. @JSONField(name = "name")
  73. // xtream
  74. @XStreamAlias("name")
  75. // fastjson
  76. public String str2;
  77. /** 未指定默认为0 */
  78. @JSONField(serialzeFeatures = { SerializerFeature.WriteNullNumberAsZero })
  79. // fastjson
  80. public int ivalue;
  81. /** 未指定默认为空字符串 */
  82. @JSONField(serialzeFeatures = { SerializerFeature.WriteNullStringAsEmpty })
  83. // fastjson
  84. public String str3;
  85. @JSONField(name = "key", implicit = true)
  86. @XStreamImplicit(itemFieldName = "key")
  87. public List<String> lists;
  88. @JSONField(name = "bitem", implicit = true)
  89. @XStreamAlias("bitems")
  90. @XStreamImplicit(itemFieldName = "bitem")
  91. public List<B> barr;
  92. public String getStr1() {
  93. return str1;
  94. }
  95. public void setStr1(String str1) {
  96. this.str1 = str1;
  97. }
  98. public String getStr2() {
  99. return str2;
  100. }
  101. public void setStr2(String str2) {
  102. this.str2 = str2;
  103. }
  104. public int getIvalue() {
  105. return ivalue;
  106. }
  107. public void setIvalue(int ivalue) {
  108. this.ivalue = ivalue;
  109. }
  110. public String getStr3() {
  111. return str3;
  112. }
  113. public void setStr3(String str3) {
  114. this.str3 = str3;
  115. }
  116. public List<String> getLists() {
  117. return lists;
  118. }
  119. public void setLists(List<String> lists) {
  120. this.lists = lists;
  121. }
  122. public List<B> getBarr() {
  123. return barr;
  124. }
  125. public void setBarr(List<B> barr) {
  126. this.barr = barr;
  127. }
  128. @Override
  129. public String toString() {
  130. return "str1:" + str1 + ",str2:" + str2 + ",str3:" + str3 + ",ivalue" + ivalue + ",lists:" + lists
  131. + "B list:" + barr;
  132. }
  133. }
  134. public static class B {
  135. private String bstr1;
  136. private String bstr2;
  137. public String getBstr1() {
  138. return bstr1;
  139. }
  140. public void setBstr1(String bstr1) {
  141. this.bstr1 = bstr1;
  142. }
  143. public String getBstr2() {
  144. return bstr2;
  145. }
  146. public void setBstr2(String bstr2) {
  147. this.bstr2 = bstr2;
  148. }
  149. @Override
  150. public String toString() {
  151. return "bstr1:" + bstr1 + ",bstr2:" + bstr2;
  152. }
  153. }
  154. }

已知问题

1.xstream 反序列化数组的问题:

  1. 1)
  2. {
  3. "item": "str0",
  4. "item": "str1",
  5. "item": "str2"
  6. }
  7. =>
  8. Test [list=[str2]]
  9. 2)
  10. {
  11. "list": [
  12. "str0",
  13. "str1",
  14. "str2"
  15. ]
  16. }
  17. =>
  18. 抛出异常:com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$DuplicateFieldException: Duplicate field list

2.simple-xml问题:

3.Fastjson
- 使用PrettyFormat特性时候,不支持ASM;
- 要使用JSONType的name和JSONField的implict特性,必须禁用asm;
- 子类无法“继承”父类字段的注解。

4.log4j和logback "jar hell"问题。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注