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. 加密数据源配置
加密数据源 源码
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
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"
参数说明
1) 配置位置
可以选择以下位置中的Context></Context>标签中进行配置
%TOMCAT_HOME%\conf\server.xml。
%TOMCAT_HOME%\conf\context.xml。
应用中META-INF/context.xml,这个是私有的,只对这个应用可见。
2) mysql配置样例
driverClassName:驱动类名称。
username:数据库用户名
password:数据库密码
url:访问的数据库路径。其中url的内容组成解析上篇博客中已经分析
maxActive:并发连接的最大数。设置为0则无限制。
maxWait:是等待连接的最大连接的时间。
maxIdle:是连接池中空闲的连接的个数。
3、web.xml配置(tomcat 1.6需要添加,1.7不需要)
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
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() 的调用。 最好加上防止程序在代码里误用了,对性能造成冲击。 |
相关文章推荐
- tomcat正常启动但是访问 404
- 深入理解Tomcat 6和Tomcat7的区别
- linux下安装tomcat8.0
- tomcat启动没有8080端口
- tomcat结合nginx使用小结
- Tomcat启动分析
- Tomcat配置常见错误以及解决方案
- eclipse中tomcat能正常启动,但是浏览器访问不了tomcat首页 问题解决
- tomcat源码阅读(一)——环境搭建
- Tomcat 系统架构与设计模式,第 1 部分: 工作原理
- Tomcat启动过程原理详解
- linux 下安装tomcat
- 转 Eclipse中启动tomcat 浏览器无法访问8080端口
- Tomcat源码阅读之Server.xml文件的处理与Catalina启动流程
- Eclipse下使用Tomcat插件打包war文件的详细过程
- tomcat jvm调优
- LINUX TOMCAT 部署 两个项目 出现Choose unique values for the 'webAppRootKey' context-param in your web.xml
- eclipse插件maven的使用,web打包成WAR,tomcat下直接运行
- 在ECLIPSE中用MAVEN和TOMCAT来建立WEBAPP
- 同一个project,tomcat启动没问题, jetty启动报错 invalid entry size