您的位置:首页 > 运维架构 > Tomcat

tomcat 加密数据源配置

2016-01-10 10:10 483 查看
配置数据源

1) 配置位置

可以选择以下位置中的Context></Context>标签中进行配置

%TOMCAT_HOME%\conf\server.xml。

%TOMCAT_HOME%\conf\context.xml。

应用中META-INF/context.xml,这个是私有的,只对这个应用可见。

2) mysql配置样例

3) oracle配置样例

4)参数说明

driverClassName:驱动类名称。

username:数据库用户名

password:数据库密码

url:访问的数据库路径。其中url的内容组成解析上篇博客中已经分析

maxActive:并发连接的最大数。设置为0则无限制。

maxWait:是等待连接的最大连接的时间。

maxIdle:是连接池中空闲的连接的个数。

3、web.xml配置(tomcat 1.6需要添加,1.7不需要)

4、spring配置

5. 加密数据源配置

1.	加入datasource.jar和驱动包到tomcat lib下面
<pre>2.	生成加密字符串 进入lib目录执行命令(XXX为要加密的字符串)
java -cp datasource.jar com.datasource.security.encrypt.CipherEncrypter XXX
3.	在server.xml  GlobalNamingResources标签中加入
<Resource name="jdbc/Quartz" auth="Container" type="javax.sql.DataSource"
factory="com.datasource.sectuiry.MyBasicDataSourceFactory" maxActive="20" maxIdle="5"
maxWait="10000" username="QkSk8tx1auc=" password="QkSk8tx1auc="
driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:@10.118.242.50:1521:npdb"
validationQuery="select 1 from dual"/>
4.	在context.xml中加入
<ResourceLink global="jdbc/Quartz" name="jdbc/Quartz" type="javax.sql.DataSource" />



加密数据源 源码

<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-dbcp</artifactId>
<version>7.0.62</version>
</dependency>


package com.datasource.security.encrypt;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class CipherEncrypter
{
Cipher ecipher;
Cipher dcipher;
byte[] salt = { -87, -101, -56, 50, 86, 53, -29, 3 };

int iterationCount = 19;
private static CipherEncrypter cipherEncrypter;

private CipherEncrypter(String passPhrase)
{
try
{
PBEKeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray());
SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);
this.ecipher = Cipher.getInstance(key.getAlgorithm());
this.dcipher = Cipher.getInstance(key.getAlgorithm());

AlgorithmParameterSpec paramSpec = new PBEParameterSpec(this.salt, this.iterationCount);

this.ecipher.init(1, key, paramSpec);
this.dcipher.init(2, key, paramSpec);
} catch (InvalidAlgorithmParameterException localInvalidAlgorithmParameterException) {
} catch (InvalidKeySpecException localInvalidKeySpecException) {
} catch (NoSuchPaddingException localNoSuchPaddingException) {
} catch (NoSuchAlgorithmException localNoSuchAlgorithmException) {
} catch (InvalidKeyException localInvalidKeyException) {
}
}

private CipherEncrypter() {
this("sfpay");
}

public static CipherEncrypter getInstance() {
if (cipherEncrypter == null) {
cipherEncrypter = new CipherEncrypter();
}
return cipherEncrypter;
}

public static String encrypt(String str) {
try {
byte[] utf8 = str.getBytes("UTF8");
byte[] enc = getInstance().ecipher.doFinal(utf8);
return new BASE64Encoder().encode(enc);
} catch (BadPaddingException localBadPaddingException) {
} catch (IllegalBlockSizeException localIllegalBlockSizeException) {
} catch (UnsupportedEncodingException localUnsupportedEncodingException) {
} catch (Exception localException) {
}
return null;
}

public static String decrypt(String str)
{
try {
byte[] dec = new BASE64Decoder().decodeBuffer(str);

byte[] utf8 = getInstance().dcipher.doFinal(dec);

return new String(utf8, "UTF8");
} catch (BadPaddingException localBadPaddingException) {
} catch (IllegalBlockSizeException localIllegalBlockSizeException) {
} catch (UnsupportedEncodingException localUnsupportedEncodingException) {
} catch (IOException localIOException) {
}
return null;
}

public static void main(String[] args) {
if (args.length != 1)
return;
System.out.println("encrypted string : [" + encrypt(args[0]) + "]");
}
}
package com.security.datasource.security
import java.io.ByteArrayInputStream;
import java.sql.SQLException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import java.util.StringTokenizer;

import javax.naming.Context;
import javax.naming.Name;
import javax.naming.RefAddr;
import javax.naming.Reference;
import javax.sql.DataSource;

import org.apache.tomcat.dbcp.dbcp.BasicDataSource;
import org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory;

import com.datasource.security.encrypt.CipherEncrypter;

public class MyBasicDataSourceFactory extends BasicDataSourceFactory
{

protected static final String PROP_DEFAULTAUTOCOMMIT = "defaultAutoCommit";
protected static final String PROP_DEFAULTREADONLY = "defaultReadOnly";
protected static final String PROP_DEFAULTTRANSACTIONISOLATION = "defaultTransactionIsolation";
protected static final String PROP_DEFAULTCATALOG = "defaultCatalog";
protected static final String PROP_DRIVERCLASSNAME = "driverClassName";
protected static final String PROP_MAXACTIVE = "maxActive";
protected static final String PROP_MAXIDLE = "maxIdle";
protected static final String PROP_MINIDLE = "minIdle";
protected static final String PROP_INITIALSIZE = "initialSize";
protected static final String PROP_MAXWAIT = "maxWait";
protected static final String PROP_TESTONBORROW = "testOnBorrow";
protected static final String PROP_TESTONRETURN = "testOnReturn";
protected static final String PROP_TIMEBETWEENEVICTIONRUNSMILLIS = "timeBetweenEvictionRunsMillis";
protected static final String PROP_NUMTESTSPEREVICTIONRUN = "numTestsPerEvictionRun";
protected static final String PROP_MINEVICTABLEIDLETIMEMILLIS = "minEvictableIdleTimeMillis";
protected static final String PROP_TESTWHILEIDLE = "testWhileIdle";
protected static final String PROP_PASSWORD = "password";
protected static final String PROP_URL = "url";
protected static final String PROP_USERNAME = "username";
protected static final String PROP_VALIDATIONQUERY = "validationQuery";
protected static final String PROP_VALIDATIONQUERY_TIMEOUT = "validationQueryTimeout";
protected static final String PROP_INITCONNECTIONSQLS = "initConnectionSqls";
protected static final String PROP_ACCESSTOUNDERLYINGCONNECTIONALLOWED = "accessToUnderlyingConnectionAllowed";
protected static final String PROP_REMOVEABANDONED = "removeAbandoned";
protected static final String PROP_REMOVEABANDONEDTIMEOUT = "removeAbandonedTimeout";
protected static final String PROP_LOGABANDONED = "logAbandoned";
protected static final String PROP_POOLPREPAREDSTATEMENTS = "poolPreparedStatements";
protected static final String PROP_MAXOPENPREPAREDSTATEMENTS = "maxOpenPreparedStatements";
protected static final String PROP_CONNECTIONPROPERTIES = "connectionProperties";
protected static final String[] ALL_PROPERTIES = {
"defaultAutoCommit",
"defaultReadOnly",
"defaultTransactionIsolation",
"defaultCatalog",
"driverClassName",
"maxActive",
"maxIdle",
"minIdle",
"initialSize",
"maxWait",
"testOnBorrow",
"testOnReturn",
"timeBetweenEvictionRunsMillis",
"numTestsPerEvictionRun",
"minEvictableIdleTimeMillis",
"testWhileIdle",
"password",
"url",
"username",
"validationQuery",
"validationQueryTimeout",
"initConnectionSqls",
"accessToUnderlyingConnectionAllowed",
"removeAbandoned",
"removeAbandonedTimeout",
"logAbandoned",
"poolPreparedStatements",
"maxOpenPreparedStatements",
"connectionProperties" };

public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment)
throws Exception
{
if ((obj == null) || (!(obj instanceof Reference))) {
return null;
}
Reference ref = (Reference)obj;
if (!"javax.sql.DataSource".equals(ref.getClassName())) {
return null;
}

Properties properties = new Properties();
for (int i = 0; i < ALL_PROPERTIES.length; i++) {
String propertyName = ALL_PROPERTIES[i];
RefAddr ra = ref.get(propertyName);
if (ra != null) {
String propertyValue = ra.getContent().toString();
properties.setProperty(propertyName, propertyValue);
}
}

return createDataSource(properties);
}

public static DataSource createDataSource(Properties properties)
throws Exception
{
final BasicDataSource dataSource = new BasicDataSource();
String value = null;

value = properties.getProperty("defaultAutoCommit");
if (value != null) {
dataSource.setDefaultAutoCommit(Boolean.valueOf(value).booleanValue());
}

value = properties.getProperty("defaultReadOnly");
if (value != null) {
dataSource.setDefaultReadOnly(Boolean.valueOf(value).booleanValue());
}

value = properties.getProperty("defaultTransactionIsolation");
if (value != null)
{
int level = -1;
if ("NONE".equalsIgnoreCase(value)) {
level = 0;
}
else if ("READ_COMMITTED".equalsIgnoreCase(value)) {
level = 2;
}
else if ("READ_UNCOMMITTED".equalsIgnoreCase(value)) {
level = 1;
}
else if ("REPEATABLE_READ".equalsIgnoreCase(value)) {
level = 4;
}
else if ("SERIALIZABLE".equalsIgnoreCase(value))
level = 8;
else {
try
{
level = Integer.parseInt(value);
} catch (NumberFormatException e) {
System.err.println("Could not parse defaultTransactionIsolation: " + value);
System.err.println("WARNING: defaultTransactionIsolation not set");
System.err.println("using default value of database driver");

level = -1;
}
}
dataSource.setDefaultTransactionIsolation(level);
}

value = properties.getProperty("defaultCatalog");
if (value != null) {
dataSource.setDefaultCatalog(value);
}

value = properties.getProperty("driverClassName");
if (value != null) {
dataSource.setDriverClassName(value);
}

value = properties.getProperty("maxActive");
if (value != null) {
dataSource.setMaxActive(Integer.parseInt(value));
}

value = properties.getProperty("maxIdle");
if (value != null) {
dataSource.setMaxIdle(Integer.parseInt(value));
}

value = properties.getProperty("minIdle");
if (value != null) {
dataSource.setMinIdle(Integer.parseInt(value));
}

value = properties.getProperty("initialSize");
if (value != null) {
dataSource.setInitialSize(Integer.parseInt(value));
}

value = properties.getProperty("maxWait");
if (value != null) {
dataSource.setMaxWait(Long.parseLong(value));
}

value = properties.getProperty("testOnBorrow");
if (value != null) {
dataSource.setTestOnBorrow(Boolean.valueOf(value).booleanValue());
}

value = properties.getProperty("testOnReturn");
if (value != null) {
dataSource.setTestOnReturn(Boolean.valueOf(value).booleanValue());
}

value = properties.getProperty("timeBetweenEvictionRunsMillis");
if (value != null) {
dataSource.setTimeBetweenEvictionRunsMillis(Long.parseLong(value));
}

value = properties.getProperty("numTestsPerEvictionRun");
if (value != null) {
dataSource.setNumTestsPerEvictionRun(Integer.parseInt(value));
}

value = properties.getProperty("minEvictableIdleTimeMillis");
if (value != null) {
dataSource.setMinEvictableIdleTimeMillis(Long.parseLong(value));
}

value = properties.getProperty("testWhileIdle");
if (value != null) {
dataSource.setTestWhileIdle(Boolean.valueOf(value).booleanValue());
}

value = properties.getProperty("password");
if (value != null) {
dataSource.setPassword(CipherEncrypter.decrypt(value.trim()));
}

value = properties.getProperty("url");
if (value != null) {
dataSource.setUrl(value);
}

value = properties.getProperty("username");
if (value != null) {
dataSource.setUsername(CipherEncrypter.decrypt(value.trim()));
}

value = properties.getProperty("validationQuery");
if (value != null) {
dataSource.setValidationQuery(value);
}

value = properties.getProperty("validationQueryTimeout");
if (value != null) {
dataSource.setValidationQueryTimeout(Integer.parseInt(value));
}

value = properties.getProperty("accessToUnderlyingConnectionAllowed");
if (value != null) {
dataSource.setAccessToUnderlyingConnectionAllowed(Boolean.valueOf(value).booleanValue());
}

value = properties.getProperty("removeAbandoned");
if (value != null) {
dataSource.setRemoveAbandoned(Boolean.valueOf(value).booleanValue());
}

value = properties.getProperty("removeAbandonedTimeout");
if (value != null) {
dataSource.setRemoveAbandonedTimeout(Integer.parseInt(value));
}

value = properties.getProperty("logAbandoned");
if (value != null) {
dataSource.setLogAbandoned(Boolean.valueOf(value).booleanValue());
}

value = properties.getProperty("poolPreparedStatements");
if (value != null) {
dataSource.setPoolPreparedStatements(Boolean.valueOf(value).booleanValue());
}

value = properties.getProperty("maxOpenPreparedStatements");
if (value != null) {
dataSource.setMaxOpenPreparedStatements(Integer.parseInt(value));
}

value = properties.getProperty("initConnectionSqls");
if (value != null) {
StringTokenizer tokenizer = new StringTokenizer(value, ";");
dataSource.setConnectionInitSqls(Collections.list(tokenizer));
}

value = properties.getProperty("connectionProperties");
if (value != null) {
Properties p = getProperties(value);
Enumeration e = p.propertyNames();
while (e.hasMoreElements()) {
String propertyName = (String)e.nextElement();
dataSource.addConnectionProperty(propertyName, p.getProperty(propertyName));
}

}

if (dataSource.getInitialSize() > 0) {
dataSource.getLogWriter();
}

Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
try {
dataSource.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});

return dataSource;
}

protected static Properties getProperties(String propText)
throws Exception
{
Properties p = new Properties();
if (propText != null) {
p.load(new ByteArrayInputStream(propText.replace(';', '\n').getBytes()));
}
return p;
}

}


6. httponly防XSS攻击

1)在tomcat7的/tomcat/apache-tomcat-7.0.62/conf/web.xml中设置:

web.xml

2) 默认对JSESSIONID的cookie已设置了HttpOnly, 具体的设置是在/tomcat/apache-tomcat-7.0.62/conf/context.xml配置

context.xml


7.jvm参数配置

1、打开/tomcat/apache-tomcat-7.0.62/bin/setenv.sh。

2、根据需要对以下参数进行调整

JAVA_OPTS="$JAVA_OPTS -server -Xms2048m -Xmx2048m -XX:PermSize=256M -XX:MaxPermSize=256M -Xss256k -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:-CMSParallelRemarkEnabled -XX:ParallelGCThreads=8 -XX:MaxTenuringThreshold=10 -XX:GCTimeRatio=19 -XX:+DisableExplicitGC"

参数说明

参数名
说明
-server
如果不配置该参数,JVM会根据应用服务器硬件配置自动选择不同模式,server模式启动比较慢,

但是运行期速度得到了优化,适合于服务器端运行的JVM。
-Xms
设置Java堆初始化时的大小,建议与-Xmx一致。
-Xmx
设置java heap的最大值,这个值决定了最多可用的Java堆内存。
-XX:PermSize
初始化永久内存区域大小,根据加载的class数量进行调整,建议与-XX:MaxPermSize设置成一致。
-XX:MaxPermSize
设置永久内存区域最大大小。
-Xss
设置每个线程的堆栈大小,根据应用的线程所需内存大小进行调整,在相同物理内存下,减小这个值能生成更多的线程。
-XX:+UseConcMarkSweepGC
指定在 老年代 使用 并发垃圾回收。gc thread 和 app thread 并行 ( 在 init-mark 和 remark 时

pause app thread)。app pause 时间较短 , 适合交互性强的系统 , 如 web server。

它可以并发执行收集操作,降低应用停止时间,同时它也是并行处理模式,可以有效地利用多处理器的系统的多进程处理。
-XX:+UseParNewGC
指定在新生代使用parallel collector, 是 UseParallelGC 的 gc 的升级版本 , 有更好的性能或者优点 , 可以和 CMS gc 一起使用
-XX:-CMSParallelRemarkEnabled
在使用 UseParNewGC 的情况下 , 尽量减少 mark 的时间。
-XX:ParallelGCThreads
配置并行收集器的线程数,即:同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相等。
-XX:MaxTenuringThreshold
设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入老年代。

对于老年代比较多的应用,可以提高效率。如果将此值设置为一个较大值,

则年轻代对象会在Survivor区进行多次复制,这样可以增加对象在年轻代的存活时间,增加在年轻代即被回收的概率。
-XX:GCTimeRatio
设置垃圾回收时间占程序运行时间的百分比。该参数设置为n的话,

则垃圾回收时间占程序运行时间百分比的公式为1/(1+n) ,如果n=19表示java可以用5%的时间来做垃圾回收,1/(1+19)=1/20=5%。
-XX:+DisableExplicitGC
禁止 java 程序中显示的调用full gc, 如 System.gc() 的调用。 最好加上防止程序在代码里误用了,对性能造成冲击。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: