get到一項新技能(properties文件中value替換),之前也想過properties中配置項暴露但沒有落實,今天看到博客分享一下:
我們使用的項目經常是這個樣子的:
1 |
< bean id = "dataSource" class = "org.apache.commons.dbcp.BasicDataSource" |
3 |
p:driverClassName = "oracle.jdbc.driver.OracleDriver" |
4 |
p:url = "jdbc:oracle:thin:@127.0.0.1:1523:orcl" |
這裏會有一個致命的問題,如果有一個具備中間件服務器機器訪問權限的人,看到了這個例如applicationContext.xml的文件,並且打開該文件,智商再低下的人也會知道數據庫的用戶名和密碼是什麼。這對於對安全有一定要求的行業是必須杜絕的,這個也是在一般技術面試中會問到的一個問題。那就讓我們繼續往下,解答這個問題吧!
首先,我們需要將配置文件抽取到property中來:
01 |
< bean class = "org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" |
02 |
p:location = "classpath:jdbc.properties" |
03 |
p:fileEncoding = "utf-8" |
06 |
< bean id = "dataSource" class = "org.apache.commons.dbcp.BasicDataSource" |
07 |
destroy-method = "close" |
08 |
p:driverClassName = "${driverClassName}" |
10 |
p:username = "${userName}" |
11 |
p:password = "${password}" /> |
將上面的第一個代碼修改爲第二個代碼,第一個類是負責抓取jdbc.properties中的屬性並且填充到dataSource當中來,這樣,我們就可以將所有的注意力都集中在jdbc.properties上了。
下面的問題是,如何將jdbc.properties變成一個看不明白的字符呢?我們只需要擴展PropertyPlaceholderConfigurer父類PropertyResourceConfigurer的解密方法convertProperty就可以了:
01 |
package com.cardDemo.commonUtil; |
03 |
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; |
05 |
public class ConvertPwdPropertyConfigurer extends PropertyPlaceholderConfigurer{ |
07 |
protected String
convertProperty(String propertyName, String propertyValue) { |
08 |
System.out.println( "==================" +propertyName+ ":" +propertyValue); |
09 |
if ( "userName" .equals(propertyName)){ |
12 |
if ( "password" .equals(propertyName)){ |
然後將上面完成的類替換配置文件中的PropertyPlaceholderConfigurer:
1 |
< bean class = "com.cardDemo.commonUtil.ConvertPwdPropertyConfigurer" |
2 |
p:location = "classpath:jdbc.properties" |
事實上,在我剛剛的Demo項目當中,裏面的jdbc.properties裏面的文件是如下內容的:
driverClassName=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@127.0.0.1:1523:orcl
userName=someOneElseUnknowUserName
password=somePwdElseUnknowPassowrd
而實際上,真實的密碼卻是czw/czw,web程序運行的時候,顯示如下的內容:
2013-8-31 13:26:12 org.apache.catalina.core.StandardEngine start
信息: Starting Servlet Engine: Apache Tomcat/6.0.18
2013-8-31 13:26:14 org.apache.catalina.core.ApplicationContext log
信息: Initializing Spring root WebApplicationContext
==================url:jdbc:oracle:thin:@127.0.0.1:1523:orcl
==================password:somePwdElseUnknowPassowrd
==================driverClassName:oracle.jdbc.driver.OracleDriver
==================userName:someOneElseUnknowUserName
2013-8-31 13:26:17 org.apache.catalina.core.ApplicationContext log
信息: Initializing Spring FrameworkServlet 'cardDemo'
2013-8-31 13:26:18 org.apache.coyote.http11.Http11Protocol start
信息: Starting Coyote HTTP/1.1 on http-8080
2013-8-31 13:26:18 org.apache.jk.common.ChannelSocket init
信息: JK: ajp13 listening on /0.0.0.0:8009
但是,在DATASOURCE裏面獲取到的內容,卻是替換之後的正確的用戶名和密碼。這只是一個非常簡單的例子,只是告訴我們一個解決數據庫用戶名和密碼加密的一個渠道,比如,我們可以在PropertyPlaceholderConfigurer子類中寫一些比較複雜的邏輯,比如根據jdbc.properties中配置的文件中進行各種手段的加密。在其中通過其他手段替換jdbc.propertes中的用戶名和密碼等等。