@zhanjindong
2015-02-12T10:10:21.000000Z
字数 11722
阅读 3060
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
<dependency>
<groupId>com.iflytek</groupId>
<artifactId>ossp-framework-security</artifactId>
<version>1.0.2-SNAPSHOT</version>
</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配置如下:
<filter>
<filter-name>xssFilter</filter-name>
<filter-class>com.iflytek.ossp.framework.security.filters.XssFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>xssFilter</filter-name>
<url-pattern>/security/xss.jsp</url-pattern>
</filter-mapping>
有的过滤器可能会有参数,具体请参看[Javadoc]
http://172.16.82.32:8282/framework-doc/1.0.2-SNAPSHOT/javadoc。
public class LoggerFactoryExample {
// 因为同时存在log4j和logback两个日志系统,如果使用slf4j不同的情况绑定的具体日志系统不确定,
// 所以这种情况建议直接使用log4j api
private static Logger log4jLogger = Logger.getLogger(LoggerFactoryExample.class);
// logback 只能通过slf4j facade来访问
private static org.slf4j.Logger logbackLogger = LogbackFactory.getLogger(LoggerFactoryExample.class);
public static void main(String[] args) {
log4jLogger.debug("log4j debug");
logbackLogger.debug("logback debug");
}
}
public class ExtendedLoggerExample {
private static ExtendedLogger logger = ExtendedLogger.getLogger(ExtendedLoggerExample.class);
private static final ExtendedLevel BIZLOG = new ExtendedLevel(70000, "BIZLOG");
private static final ExtendedLevel BIZLOG2 = new ExtendedLevel(80000, "BIZLOG2");
public static void main(String[] args) {
ExtendedLogger.register(new ExtendedLevel[] { BIZLOG, BIZLOG2 });
logger.debug("ExtendedLogger debug test!");
logger.error("ExtendedLogger error test!");
logger.log(BIZLOG, "ExtendedLogger biz log test!");
logger.log(BIZLOG2, "ExtendedLogger biz log2 test!");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//log4j/log4j Configuration//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
threshold="null" debug="null">
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%-d{yyyy-MM-dd HH:mm:ss.SSS} [ %t:%r ] - [ %p ] %m%n" />
</layout>
</appender>
<appender name="D" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="D:/temp/debug.log" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%m%n" />
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="debug" />
<param name="LevelMax" value="debug" />
</filter>
</appender>
<appender name="E" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="D:/temp/error" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%m%n" />
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="error" />
<param name="LevelMax" value="fatal" />
</filter>
</appender>
<!-- 自定义日志级别BIZLOG -->
<appender name="Ext" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="D:/temp/ext" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%-d{yyyy-MM-dd HH:mm:ss.SSS} [ %t:%r ] - [ %p ] %m%n" />
</layout>
<filter class="com.iflytek.ossp.framework.common.log.ExtendedFilter">
<param name="LevelMin" value="BIZLOG" />
<param name="LevelMax" value="BIZLOG" />
</filter>
</appender>
<!-- 自定义日志级别BIZLOG2 -->
<appender name="Ext2" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="D:/temp/ext2" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%-d{yyyy-MM-dd HH:mm:ss.SSS} [ %t:%r ] - [ %p ] %m%n" />
</layout>
<filter class="com.iflytek.ossp.framework.common.log.ExtendedFilter">
<param name="LevelMin" value="BIZLOG2" />
<param name="LevelMax" value="BIZLOG2" />
</filter>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="D" />
<appender-ref ref="E" />
<appender-ref ref="Ext" />
<appender-ref ref="Ext2" />
</root>
</log4j:configuration>
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 控制台输出 -->
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%date [%thread] %-5level %logger{80} - %msg%n</pattern>
</encoder>
</appender>
<!-- 时间滚动输出 level为 DEBUG 日志 -->
<appender name="D"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY </onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>D:/temp/debug.%d{yyyy-MM-dd}.log</FileNamePattern>
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<!-- 时间滚动输出 level为 ERROR 日志 -->
<appender name="E"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY </onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>D:/temp/error.%d{yyyy-MM-dd}.log</FileNamePattern>
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder>
<pattern>%date [%thread] %-5level %logger{80} - %msg%n</pattern>
</encoder>
</appender>
<appender name="BIZLOG"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY </onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 一分钟产生一个文件 -->
<FileNamePattern>D:/temp/biz-%d{yyyyMMddHHmm}.log</FileNamePattern>
<MaxHistory>-1</MaxHistory>
</rollingPolicy>
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<!-- 使用异步appender -->
<appender name="ASYNC_BIZLOG" class="ch.qos.logback.classic.AsyncAppender">
<queueSize>500</queueSize>
<discardingThreshold>0</discardingThreshold>
<appender-ref ref="BIZLOG" />
</appender>
<!-- 用来单独记录业务日志 -->
<logger level="INFO" name="bizlog">
<appender-ref ref="ASYNC_BIZLOG" />
</logger>
<root level="DEBUG">
<appender-ref ref="D" />
<appender-ref ref="E" />
</root>
</configuration>
@JSONField注解增加implict,使用 @JSONField(name = "bitem", implicit = true)代替XStream的 @XStreamImplicit(itemFieldName = "bitem"),目前仅支持对List 使用implicit的。
@JSONField(name = "key", implicit = true)
@XStreamImplicit(itemFieldName = "key")
public List<String> lists;
@JSONType注解增加name,支持类似XStream对类进行别名处理的功能
:
@XStreamAlias("abc")
@JSONType(name = "abc")
public static class A {
详细的示例代码
:
package com.iflytek.ossp.framework.example.common.serializable;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.annotation.JSONType;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.iflytek.ossp.framework.common.serializable.JSONRoot;
import com.iflytek.ossp.framework.common.serializable.SerializationInstance;
import com.iflytek.ossp.framework.common.serializable.SerializationTools;
import com.iflytek.ossp.framework.common.text.NormalizationUtils;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
/**
* Fastjson API使用示例。
* <p>
* {@link SerializationTools#fastFromJson(Class, String)}<br />
* {@link SerializationTools#fastToJson(Object)}<br />
* 官方版本fastjson不支持类似XStream <code>@XStreamImplicit</code>的特性,fork了官方1.1.41版本:<a
* href="https://github.com/zhanjindong/fastjson-1.1.41"
* >https://github.com/zhanjindong/fastjson-1.1.41</a><br />
* <code>@JSONField</code>注解增加implict,使用
* <code>@JSONField(name = "bitem", implicit = true)</code>代替XStream的
* <code>@XStreamImplicit(itemFieldName = "bitem")</code>,目前仅支持对{@link List}
* 使用implicit的。
*
* @author jdzhan,2014-8-21
*
*/
public class FastjsonExample {
static SerializationInstance tools = SerializationInstance.sharedInstance();
public static void main(String[] args) throws IllegalStateException, Exception {
// annotationBenchmark();
fastJsonExample();
}
public static void fastJsonExample() throws SecurityException, IllegalArgumentException, NoSuchFieldException,
IllegalAccessException {
A a = new A();
a.setStr1("str1");
a.setStr2("str2");
List<String> list = new ArrayList<String>();
list.add("item1");
list.add("item1");
a.setLists(list);
List<B> barr = new ArrayList<FastjsonExample.B>();
for (int i = 0; i < 2; i++) {
B b = new B();
b.setBstr1("b str1");
b.setBstr2("b str2");
barr.add(b);
}
a.setBarr(barr);
// fastjson
String json = tools.fastToJson(a, true);
System.out.println("fastjson result:\r\n" + json);
A newA = tools.fastFromJson(A.class, json);
System.out.println(newA);
// xstream
String xjson = tools.toJson(a);
System.out.println("xstream result:" + NormalizationUtils.normalizeJson(json));
}
@XStreamAlias("abc")
@JSONType(name = "abc")
public static class A {
/** 忽略 */
@JSONField(serialize = false)
// fastjson
@XStreamOmitField
// xstream
public String str1 = "str1";
/** 指定别名 */
@JSONField(name = "name")
// xtream
@XStreamAlias("name")
// fastjson
public String str2;
/** 未指定默认为0 */
@JSONField(serialzeFeatures = { SerializerFeature.WriteNullNumberAsZero })
// fastjson
public int ivalue;
/** 未指定默认为空字符串 */
@JSONField(serialzeFeatures = { SerializerFeature.WriteNullStringAsEmpty })
// fastjson
public String str3;
@JSONField(name = "key", implicit = true)
@XStreamImplicit(itemFieldName = "key")
public List<String> lists;
@JSONField(name = "bitem", implicit = true)
@XStreamAlias("bitems")
@XStreamImplicit(itemFieldName = "bitem")
public List<B> barr;
public String getStr1() {
return str1;
}
public void setStr1(String str1) {
this.str1 = str1;
}
public String getStr2() {
return str2;
}
public void setStr2(String str2) {
this.str2 = str2;
}
public int getIvalue() {
return ivalue;
}
public void setIvalue(int ivalue) {
this.ivalue = ivalue;
}
public String getStr3() {
return str3;
}
public void setStr3(String str3) {
this.str3 = str3;
}
public List<String> getLists() {
return lists;
}
public void setLists(List<String> lists) {
this.lists = lists;
}
public List<B> getBarr() {
return barr;
}
public void setBarr(List<B> barr) {
this.barr = barr;
}
@Override
public String toString() {
return "str1:" + str1 + ",str2:" + str2 + ",str3:" + str3 + ",ivalue" + ivalue + ",lists:" + lists
+ "B list:" + barr;
}
}
public static class B {
private String bstr1;
private String bstr2;
public String getBstr1() {
return bstr1;
}
public void setBstr1(String bstr1) {
this.bstr1 = bstr1;
}
public String getBstr2() {
return bstr2;
}
public void setBstr2(String bstr2) {
this.bstr2 = bstr2;
}
@Override
public String toString() {
return "bstr1:" + bstr1 + ",bstr2:" + bstr2;
}
}
}
1.xstream 反序列化数组的问题:
1)
{
"item": "str0",
"item": "str1",
"item": "str2"
}
=>
Test [list=[str2]]
2)
{
"list": [
"str0",
"str1",
"str2"
]
}
=>
抛出异常:com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$DuplicateFieldException: Duplicate field list
2.simple-xml问题:
序列化数组的时候会多出属性length
@ElementArray(name = "items", entry = "item")
private String[] arr = new String[2];
=>
<items length="2">
<item>string in index 0</item>
<item>string in index 1</itemvn clccm>
</items>
序列化接口的时候会出现class属性
@ElementList(name = "items", entry = "item")
public List<String> lists = new ArrayList<>();
=>
<items class="java.util.ArrayList">
<item>item 1</item>
<item>item 2</item>
</items>
xstream支持将节点反序列为对应注解为“XML属性”的字段,simple-xml不支持
3.Fastjson
- 使用PrettyFormat特性时候,不支持ASM;
- 要使用JSONType的name和JSONField的implict特性,必须禁用asm;
- 子类无法“继承”父类字段的注解。
4.log4j和logback "jar hell"问题。