Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
matrix
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
CI / CD
CI / CD
Pipelines
Schedules
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
mall
arch
matrix
Commits
293e7d19
Commit
293e7d19
authored
Aug 17, 2021
by
郑冰晶
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
数据库加密组件
parent
7d00ea38
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
1145 additions
and
53 deletions
+1145
-53
BizResponse.java
common-core/src/main/java/com/secoo/mall/common/core/bean/BizResponse.java
+25
-2
Response.java
common-core/src/main/java/com/secoo/mall/common/core/bean/Response.java
+8
-1
HttpClientUtils.java
common-util/src/main/java/com/secoo/mall/common/util/http/HttpClientUtils.java
+87
-45
pom.xml
matrix-datasource/matrix-datasource-security/matrix-datasource-security-core/pom.xml
+35
-0
AESSecurityAlgorithm.java
matrix-datasource/matrix-datasource-security/matrix-datasource-security-core/src/main/java/com/secoo/mall/datasource/security/algorithm/AESSecurityAlgorithm.java
+71
-0
SecurityAlgorithm.java
matrix-datasource/matrix-datasource-security/matrix-datasource-security-core/src/main/java/com/secoo/mall/datasource/security/algorithm/SecurityAlgorithm.java
+24
-0
DBType.java
matrix-datasource/matrix-datasource-security/matrix-datasource-security-core/src/main/java/com/secoo/mall/datasource/security/constant/DBType.java
+6
-0
SecurityType.java
matrix-datasource/matrix-datasource-security/matrix-datasource-security-core/src/main/java/com/secoo/mall/datasource/security/constant/SecurityType.java
+6
-0
SymbolConstants.java
matrix-datasource/matrix-datasource-security/matrix-datasource-security-core/src/main/java/com/secoo/mall/datasource/security/constant/SymbolConstants.java
+7
-0
SecurityException.java
matrix-datasource/matrix-datasource-security/matrix-datasource-security-core/src/main/java/com/secoo/mall/datasource/security/exception/SecurityException.java
+16
-0
TableColumnException.java
matrix-datasource/matrix-datasource-security/matrix-datasource-security-core/src/main/java/com/secoo/mall/datasource/security/exception/TableColumnException.java
+40
-0
AbsSecurityFilter.java
matrix-datasource/matrix-datasource-security/matrix-datasource-security-core/src/main/java/com/secoo/mall/datasource/security/filter/AbsSecurityFilter.java
+185
-0
MysqlSecurityFilter.java
matrix-datasource/matrix-datasource-security/matrix-datasource-security-core/src/main/java/com/secoo/mall/datasource/security/filter/MysqlSecurityFilter.java
+285
-0
ColumnRule.java
matrix-datasource/matrix-datasource-security/matrix-datasource-security-core/src/main/java/com/secoo/mall/datasource/security/rule/ColumnRule.java
+70
-0
DataSourceRule.java
matrix-datasource/matrix-datasource-security/matrix-datasource-security-core/src/main/java/com/secoo/mall/datasource/security/rule/DataSourceRule.java
+30
-0
TableRule.java
matrix-datasource/matrix-datasource-security/matrix-datasource-security-core/src/main/java/com/secoo/mall/datasource/security/rule/TableRule.java
+30
-0
pom.xml
matrix-datasource/matrix-datasource-security/matrix-datasource-security-starter/pom.xml
+38
-0
DataSourceSecurityAutoConfiguration.java
matrix-datasource/matrix-datasource-security/matrix-datasource-security-starter/src/main/java/com/secoo/mall/datasource/security/config/DataSourceSecurityAutoConfiguration.java
+76
-0
DataSourceSecurityProperties.java
matrix-datasource/matrix-datasource-security/matrix-datasource-security-starter/src/main/java/com/secoo/mall/datasource/security/config/DataSourceSecurityProperties.java
+70
-0
pom.xml
matrix-datasource/matrix-datasource-security/pom.xml
+35
-0
pom.xml
matrix-datasource/pom.xml
+1
-0
pom.xml
pom.xml
+0
-5
No files found.
common-core/src/main/java/com/secoo/mall/common/core/bean/BizResponse.java
View file @
293e7d19
...
...
@@ -17,9 +17,31 @@ public class BizResponse<T> extends Response<T> {
super
(
code
,
msg
);
}
public
BizResponse
(
Integer
code
,
String
msg
,
T
data
)
{
super
(
code
,
msg
,
data
);
}
public
boolean
isSuccess
()
{
return
getCode
()
!=
null
&&
getCode
()
==
CommonConstant
.
Success
.
CODE
;
return
getCode
()
!=
null
&&
getCode
().
equals
(
CommonConstant
.
Success
.
CODE
);
}
public
static
<
T
>
BizResponse
<
T
>
success
(
T
data
)
{
return
new
BizResponse
<>(
CommonConstant
.
Success
.
CODE
,
CommonConstant
.
Success
.
MSG
,
data
);
}
public
static
<
T
>
BizResponse
<
T
>
success
(
Integer
code
,
String
msg
)
{
return
new
BizResponse
<>(
code
,
msg
);
}
}
public
static
<
T
>
BizResponse
<
T
>
success
(
Integer
code
,
String
msg
,
T
data
)
{
return
new
BizResponse
<>(
code
,
msg
,
data
);
}
public
static
<
T
>
BizResponse
<
T
>
fail
(
Integer
code
,
String
msg
)
{
return
new
BizResponse
<>(
code
,
msg
);
}
public
static
<
T
>
BizResponse
<
T
>
fail
(
Integer
code
,
String
msg
,
T
data
)
{
return
new
BizResponse
<>(
code
,
msg
,
data
);
}
}
\ No newline at end of file
common-core/src/main/java/com/secoo/mall/common/core/bean/Response.java
View file @
293e7d19
...
...
@@ -21,6 +21,12 @@ public class Response<T> implements Serializable {
this
.
msg
=
msg
;
}
public
Response
(
Integer
code
,
String
msg
,
T
data
)
{
this
.
code
=
code
;
this
.
msg
=
msg
;
this
.
data
=
data
;
}
public
Integer
getCode
()
{
return
code
;
}
...
...
@@ -53,4 +59,4 @@ public class Response<T> implements Serializable {
", data="
+
data
+
'}'
;
}
}
}
\ No newline at end of file
common-util/src/main/java/com/secoo/mall/common/util/http/HttpClientUtils.java
View file @
293e7d19
...
...
@@ -2,17 +2,15 @@ package com.secoo.mall.common.util.http;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONObject
;
import
com.secoo.mall.common.util.date.DateUtil
;
import
org.apache.commons.io.IOUtils
;
import
org.apache.http.HttpEntity
;
import
org.apache.http.HttpResponse
;
import
org.apache.http.NameValuePair
;
import
org.apache.http.*
;
import
org.apache.http.client.ClientProtocolException
;
import
org.apache.http.client.config.RequestConfig
;
import
org.apache.http.client.entity.UrlEncodedFormEntity
;
import
org.apache.http.client.methods.*
;
import
org.apache.http.client.utils.URIBuilder
;
import
org.apache.http.concurrent.FutureCallback
;
import
org.apache.http.conn.ConnectionKeepAliveStrategy
;
import
org.apache.http.conn.ssl.SSLConnectionSocketFactory
;
import
org.apache.http.conn.ssl.TrustSelfSignedStrategy
;
import
org.apache.http.entity.StringEntity
;
...
...
@@ -21,8 +19,12 @@ import org.apache.http.impl.client.HttpClients;
import
org.apache.http.impl.conn.PoolingHttpClientConnectionManager
;
import
org.apache.http.impl.nio.client.CloseableHttpAsyncClient
;
import
org.apache.http.impl.nio.client.HttpAsyncClients
;
import
org.apache.http.message.BasicHeaderElementIterator
;
import
org.apache.http.message.BasicNameValuePair
;
import
org.apache.http.protocol.HTTP
;
import
org.apache.http.protocol.HttpContext
;
import
org.apache.http.ssl.SSLContexts
;
import
org.apache.http.util.Args
;
import
org.apache.http.util.EntityUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
...
...
@@ -36,7 +38,7 @@ import java.nio.charset.Charset;
import
java.security.KeyManagementException
;
import
java.security.KeyStoreException
;
import
java.security.NoSuchAlgorithmException
;
import
java.t
ext.SimpleDateFormat
;
import
java.t
ime.LocalDateTime
;
import
java.util.*
;
/**
...
...
@@ -48,13 +50,16 @@ public class HttpClientUtils {
private
static
Logger
LOG
=
LoggerFactory
.
getLogger
(
HttpClientUtils
.
class
);
private
static
PoolingHttpClientConnectionManager
connMgr
;
private
static
RequestConfig
requestConfig
;
private
static
final
int
CONNECT_TIMEOUT
=
100000
;
private
static
final
int
SOCKET_TIMEOUT
=
100000
;
private
static
final
int
REQUEST_TIMEOUT
=
2000
;
private
static
final
int
CONNECT_TIMEOUT
=
10000
;
private
static
final
int
SOCKET_TIMEOUT
=
60000
;
private
static
final
int
REQUEST_TIMEOUT
=
10000
;
private
static
final
int
KEEPALIVE_TIMEOUT
=
50000
;
private
static
final
String
CHARSET
=
"UTF-8"
;
private
static
final
ConnectionKeepAliveStrategy
connectionKeepAliveStrategy
;
private
static
final
PoolingHttpClientConnectionManager
connMgr
;
private
static
RequestConfig
requestConfig
;
static
{
// 设置连接池
connMgr
=
new
PoolingHttpClientConnectionManager
();
...
...
@@ -69,8 +74,25 @@ public class HttpClientUtils {
configBuilder
.
setConnectionRequestTimeout
(
REQUEST_TIMEOUT
);
// 等待数据超时时间
configBuilder
.
setSocketTimeout
(
SOCKET_TIMEOUT
);
LOG
.
debug
(
"Http参数设置,连接超时时间[{}],Socket超时时间[{}],请求超时时间[{}]"
,
CONNECT_TIMEOUT
,
SOCKET_TIMEOUT
);
LOG
.
debug
(
"Http参数设置,连接超时时间[{}],Socket超时时间[{}],请求超时时间[{}]"
,
CONNECT_TIMEOUT
,
SOCKET_TIMEOUT
,
REQUEST_TIMEOUT
);
requestConfig
=
configBuilder
.
build
();
connectionKeepAliveStrategy
=
new
ConnectionKeepAliveStrategy
()
{
@Override
public
long
getKeepAliveDuration
(
HttpResponse
httpResponse
,
HttpContext
httpContext
)
{
Args
.
notNull
(
httpResponse
,
"HTTP response"
);
final
HeaderElementIterator
it
=
new
BasicHeaderElementIterator
(
httpResponse
.
headerIterator
(
HTTP
.
CONN_KEEP_ALIVE
));
while
(
it
.
hasNext
())
{
final
HeaderElement
he
=
it
.
nextElement
();
final
String
param
=
he
.
getName
();
final
String
value
=
he
.
getValue
();
if
(
value
!=
null
&&
param
.
equalsIgnoreCase
(
"timeout"
))
{
return
Long
.
parseLong
(
value
)
*
1000
;
}
}
return
KEEPALIVE_TIMEOUT
;
}
};
}
/**
...
...
@@ -103,7 +125,7 @@ public class HttpClientUtils {
String
result
=
doGet
(
url
,
new
HashMap
<>(
10
));
return
result
;
}
catch
(
Exception
e
)
{
LOG
.
error
(
"发送 GET 请求ERROR
:{}
"
,
e
);
LOG
.
error
(
"发送 GET 请求ERROR
:
"
,
e
);
}
return
""
;
}
...
...
@@ -125,7 +147,7 @@ public class HttpClientUtils {
String
result
=
null
;
if
(
StringUtils
.
isEmpty
(
url
))
{
LOG
.
debug
(
"warn:
doGet url is null or '' "
);
LOG
.
warn
(
"
doGet url is null or '' "
);
return
result
;
}
...
...
@@ -133,8 +155,11 @@ public class HttpClientUtils {
for
(
Map
.
Entry
<
String
,
Object
>
entry
:
params
.
entrySet
())
{
pairList
.
add
(
new
BasicNameValuePair
(
entry
.
getKey
(),
entry
.
getValue
().
toString
()));
}
CloseableHttpClient
httpclient
=
HttpClients
.
custom
().
setDefaultRequestConfig
(
requestConfig
)
.
setConnectionManager
(
connMgr
).
build
();
CloseableHttpClient
httpclient
=
HttpClients
.
custom
()
.
setDefaultRequestConfig
(
requestConfig
)
.
setConnectionManager
(
connMgr
)
.
setKeepAliveStrategy
(
connectionKeepAliveStrategy
)
.
build
();
CloseableHttpResponse
response
=
null
;
InputStream
instream
=
null
;
try
{
...
...
@@ -169,15 +194,16 @@ public class HttpClientUtils {
}
public
static
HttpEntity
doGetByDefault
(
String
url
)
throws
Exception
{
CloseableHttpClient
httpclient
=
HttpClients
.
custom
().
setDefaultRequestConfig
(
requestConfig
)
.
setConnectionManager
(
connMgr
).
build
();
CloseableHttpClient
httpclient
=
HttpClients
.
custom
()
.
setDefaultRequestConfig
(
requestConfig
)
.
setConnectionManager
(
connMgr
)
.
setKeepAliveStrategy
(
connectionKeepAliveStrategy
)
.
build
();
HttpGet
httpGet
=
new
HttpGet
(
url
);
CloseableHttpResponse
response
=
httpclient
.
execute
(
httpGet
);
LOG
.
info
(
"doGet statusCode:{}"
,
response
.
getStatusLine
().
getStatusCode
());
LOG
.
debug
(
"doGet statusCode:{}"
,
response
.
getStatusLine
().
getStatusCode
());
return
response
.
getEntity
();
...
...
@@ -186,8 +212,11 @@ public class HttpClientUtils {
public
static
String
doDelete
(
String
url
,
Map
<
String
,
String
>
headers
,
Map
<
String
,
String
>
params
)
throws
Exception
{
CloseableHttpClient
httpclient
=
HttpClients
.
custom
().
setDefaultRequestConfig
(
requestConfig
)
.
setConnectionManager
(
connMgr
).
build
();
CloseableHttpClient
httpclient
=
HttpClients
.
custom
()
.
setDefaultRequestConfig
(
requestConfig
)
.
setConnectionManager
(
connMgr
)
.
setKeepAliveStrategy
(
connectionKeepAliveStrategy
)
.
build
();
CloseableHttpResponse
response
=
null
;
InputStream
instream
=
null
;
List
<
NameValuePair
>
pairList
=
new
ArrayList
<>(
params
.
size
());
...
...
@@ -209,7 +238,7 @@ public class HttpClientUtils {
response
=
httpclient
.
execute
(
httpDelete
);
LOG
.
info
(
"httpDelete statusCode:{}"
,
response
.
getStatusLine
().
getStatusCode
());
LOG
.
debug
(
"httpDelete statusCode:{}"
,
response
.
getStatusLine
().
getStatusCode
());
HttpEntity
entity
=
response
.
getEntity
();
if
(
entity
!=
null
)
{
...
...
@@ -251,8 +280,11 @@ public class HttpClientUtils {
});
CloseableHttpClient
httpclient
=
HttpClients
.
custom
().
setDefaultRequestConfig
(
requestConfig
)
.
setConnectionManager
(
connMgr
).
build
();
CloseableHttpClient
httpclient
=
HttpClients
.
custom
()
.
setDefaultRequestConfig
(
requestConfig
)
.
setConnectionManager
(
connMgr
)
.
setKeepAliveStrategy
(
connectionKeepAliveStrategy
)
.
build
();
CloseableHttpResponse
response
=
null
;
InputStream
instream
=
null
;
try
{
...
...
@@ -272,7 +304,7 @@ public class HttpClientUtils {
}
response
=
httpclient
.
execute
(
httpPut
);
LOG
.
info
(
"doGet statusCode:{}"
,
response
.
getStatusLine
().
getStatusCode
());
LOG
.
debug
(
"doGet statusCode:{}"
,
response
.
getStatusLine
().
getStatusCode
());
HttpEntity
entity
=
response
.
getEntity
();
if
(
entity
!=
null
)
{
...
...
@@ -315,7 +347,7 @@ public class HttpClientUtils {
public
static
String
doPost
(
String
url
,
Map
<
String
,
Object
>
params
)
throws
Exception
{
if
(
StringUtils
.
isEmpty
(
url
))
{
LOG
.
info
(
"warn:
doPost url is null or '' "
);
LOG
.
warn
(
"
doPost url is null or '' "
);
return
null
;
}
List
<
NameValuePair
>
pairList
=
new
ArrayList
<>(
params
.
size
());
...
...
@@ -339,7 +371,7 @@ public class HttpClientUtils {
public
static
String
doPost
(
String
url
,
String
xml
)
throws
Exception
{
if
(
StringUtils
.
isEmpty
(
url
))
{
LOG
.
info
(
"warn:
doPost url is null or '' "
);
LOG
.
warn
(
"
doPost url is null or '' "
);
return
null
;
}
...
...
@@ -359,7 +391,7 @@ public class HttpClientUtils {
public
static
String
doPost
(
String
url
,
Object
json
)
throws
Exception
{
if
(
StringUtils
.
isEmpty
(
url
))
{
LOG
.
error
(
"warn:
doPostByJson url is null or '' "
);
LOG
.
warn
(
"
doPostByJson url is null or '' "
);
return
null
;
}
HttpPost
httpPost
=
new
HttpPost
(
url
);
...
...
@@ -373,7 +405,7 @@ public class HttpClientUtils {
public
static
String
doPost
(
String
url
,
HttpEntity
entity
,
Map
<
String
,
String
>
headers
)
throws
Exception
{
if
(
StringUtils
.
isEmpty
(
url
))
{
LOG
.
error
(
"warn:
doPostByJson url is null or '' "
);
LOG
.
warn
(
"
doPostByJson url is null or '' "
);
return
null
;
}
HttpPost
httpPost
=
new
HttpPost
(
url
);
...
...
@@ -396,7 +428,7 @@ public class HttpClientUtils {
public
static
String
doPostSsl
(
String
apiUrl
,
Map
<
String
,
Object
>
params
)
throws
Exception
{
if
(
StringUtils
.
isEmpty
(
apiUrl
))
{
LOG
.
info
(
"warn:
doPostSSL url is null or '' "
);
LOG
.
warn
(
"
doPostSSL url is null or '' "
);
return
null
;
}
...
...
@@ -421,7 +453,7 @@ public class HttpClientUtils {
public
static
String
doPostSsl
(
String
apiUrl
,
Object
json
)
throws
Exception
{
if
(
StringUtils
.
isEmpty
(
apiUrl
))
{
LOG
.
info
(
"warn:
doPostSSL By Json url is null or '' "
);
LOG
.
warn
(
"
doPostSSL By Json url is null or '' "
);
return
null
;
}
...
...
@@ -456,10 +488,17 @@ public class HttpClientUtils {
SSLContext
sslcontext
=
SSLContexts
.
custom
().
loadTrustMaterial
(
null
,
new
TrustSelfSignedStrategy
())
.
build
();
SSLConnectionSocketFactory
sslsf
=
new
SSLConnectionSocketFactory
(
sslcontext
);
httpClient
=
HttpClients
.
custom
().
setConnectionManager
(
connMgr
).
setSSLSocketFactory
(
sslsf
)
.
setDefaultRequestConfig
(
requestConfig
).
build
();
httpClient
=
HttpClients
.
custom
()
.
setConnectionManager
(
connMgr
)
.
setSSLSocketFactory
(
sslsf
)
.
setDefaultRequestConfig
(
requestConfig
)
.
setKeepAliveStrategy
(
connectionKeepAliveStrategy
)
.
build
();
}
else
{
httpClient
=
HttpClients
.
custom
().
setDefaultRequestConfig
(
requestConfig
).
setConnectionManager
(
connMgr
)
httpClient
=
HttpClients
.
custom
()
.
setDefaultRequestConfig
(
requestConfig
)
.
setConnectionManager
(
connMgr
)
.
setKeepAliveStrategy
(
connectionKeepAliveStrategy
)
.
build
();
}
response
=
httpClient
.
execute
(
httpPost
);
...
...
@@ -497,33 +536,36 @@ public class HttpClientUtils {
final
String
[]
content
=
new
String
[
1
];
content
[
0
]=
""
;
// 传入HttpPost request
CloseableHttpAsyncClient
httpclient
=
HttpAsyncClients
.
custom
().
setDefaultRequestConfig
(
requestConfig
).
build
();
LOG
.
info
(
"httpclient test begin time:{}"
,
DateUtil
.
getDateTime
());
CloseableHttpAsyncClient
httpclient
=
HttpAsyncClients
.
custom
()
.
setDefaultRequestConfig
(
requestConfig
)
.
setKeepAliveStrategy
(
connectionKeepAliveStrategy
)
.
build
();
LOG
.
debug
(
"httpclient test begin time:{}"
,
LocalDateTime
.
now
());
httpclient
.
start
();
httpclient
.
execute
(
request
,
new
FutureCallback
<
HttpResponse
>()
{
@Override
public
void
completed
(
final
HttpResponse
response
)
{
LOG
.
info
(
request
.
getRequestLine
()
+
"->"
+
response
.
getStatusLine
());
LOG
.
info
(
"httpclient test received content time:{}"
,
DateUtil
.
getDateTime
());
LOG
.
debug
(
request
.
getRequestLine
()
+
"->"
+
response
.
getStatusLine
());
LOG
.
debug
(
"httpclient test received content time:{}"
,
LocalDateTime
.
now
());
try
{
content
[
0
]
=
EntityUtils
.
toString
(
response
.
getEntity
(),
"UTF-8"
);
content
[
0
]
=
EntityUtils
.
toString
(
response
.
getEntity
(),
"UTF-8"
);
}
catch
(
IOException
e
)
{
LOG
.
error
(
"matrix HttpClientUtils asynchronousPost error"
,
e
);
}
}
@Override
public
void
failed
(
final
Exception
ex
)
{
LOG
.
info
(
"httpclient test received failed time:{}"
,
DateUtil
.
getDateTime
());
LOG
.
error
(
request
.
getRequestLine
()
+
"->"
+
ex
);
LOG
.
debug
(
"httpclient test received failed time:{}"
,
LocalDateTime
.
now
());
LOG
.
error
(
request
.
getRequestLine
()
+
"->"
,
ex
);
}
@Override
public
void
cancelled
()
{
LOG
.
info
(
"httpclient test received cancelled time:{}"
,
DateUtil
.
getDateTime
());
LOG
.
error
(
request
.
getRequestLine
()
+
" cancelled"
);
LOG
.
debug
(
"httpclient test received cancelled time:{}"
,
LocalDateTime
.
now
());
LOG
.
warn
(
request
.
getRequestLine
()
+
" cancelled"
);
}
});
LOG
.
info
(
"httpclient test end time:{}"
,
DateUtil
.
getDateTime
());
LOG
.
debug
(
"httpclient test end time:{}"
,
LocalDateTime
.
now
());
return
content
[
0
];
}
...
...
matrix-datasource/matrix-datasource-security/matrix-datasource-security-core/pom.xml
0 → 100644
View file @
293e7d19
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns=
"http://maven.apache.org/POM/4.0.0"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<parent>
<artifactId>
matrix-datasource-security
</artifactId>
<groupId>
com.secoo.mall
</groupId>
<version>
2.0.17.RELEASE
</version>
</parent>
<modelVersion>
4.0.0
</modelVersion>
<artifactId>
matrix-datasource-security-core
</artifactId>
<packaging>
jar
</packaging>
<dependencies>
<dependency>
<groupId>
com.alibaba
</groupId>
<artifactId>
druid
</artifactId>
</dependency>
<dependency>
<groupId>
mysql
</groupId>
<artifactId>
mysql-connector-java
</artifactId>
<version>
8.0.13
</version>
</dependency>
</dependencies>
<build>
<finalName>
matrix-datasource-security-starter
</finalName>
<plugins>
<plugin>
<artifactId>
maven-resources-plugin
</artifactId>
</plugin>
</plugins>
</build>
</project>
matrix-datasource/matrix-datasource-security/matrix-datasource-security-core/src/main/java/com/secoo/mall/datasource/security/algorithm/AESSecurityAlgorithm.java
0 → 100644
View file @
293e7d19
package
com
.
secoo
.
mall
.
datasource
.
security
.
algorithm
;
import
com.secoo.mall.datasource.security.constant.SecurityType
;
import
lombok.Getter
;
import
lombok.Setter
;
import
lombok.SneakyThrows
;
import
org.apache.commons.codec.digest.DigestUtils
;
import
javax.crypto.Cipher
;
import
javax.crypto.NoSuchPaddingException
;
import
javax.crypto.spec.SecretKeySpec
;
import
javax.xml.bind.DatatypeConverter
;
import
java.nio.charset.StandardCharsets
;
import
java.security.GeneralSecurityException
;
import
java.security.InvalidKeyException
;
import
java.security.NoSuchAlgorithmException
;
import
java.util.Arrays
;
/**
* AES encrypt algorithm.
*/
@Getter
@Setter
public
final
class
AESSecurityAlgorithm
implements
SecurityAlgorithm
{
private
String
aesKey
;
private
byte
[]
secretKey
;
public
AESSecurityAlgorithm
(
String
aesKey
){
if
(
aesKey
==
null
||
aesKey
.
length
()
==
0
){
throw
new
SecurityException
(
"aesKey can not be null!"
);
}
this
.
aesKey
=
aesKey
;
this
.
secretKey
=
createSecretKey
();
}
private
byte
[]
createSecretKey
()
{
return
Arrays
.
copyOf
(
DigestUtils
.
sha1
(
aesKey
),
16
);
}
@SneakyThrows
(
GeneralSecurityException
.
class
)
@Override
public
String
encrypt
(
final
Object
plaintext
)
{
if
(
null
==
plaintext
)
{
return
null
;
}
byte
[]
result
=
getCipher
(
Cipher
.
ENCRYPT_MODE
).
doFinal
(
String
.
valueOf
(
plaintext
).
getBytes
(
StandardCharsets
.
UTF_8
));
return
DatatypeConverter
.
printBase64Binary
(
result
);
}
@SneakyThrows
(
GeneralSecurityException
.
class
)
@Override
public
String
decrypt
(
final
String
ciphertext
)
{
if
(
null
==
ciphertext
)
{
return
null
;
}
byte
[]
result
=
getCipher
(
Cipher
.
DECRYPT_MODE
).
doFinal
(
DatatypeConverter
.
parseBase64Binary
(
ciphertext
));
return
new
String
(
result
,
StandardCharsets
.
UTF_8
);
}
private
Cipher
getCipher
(
final
int
decryptMode
)
throws
NoSuchPaddingException
,
NoSuchAlgorithmException
,
InvalidKeyException
{
Cipher
result
=
Cipher
.
getInstance
(
getType
());
result
.
init
(
decryptMode
,
new
SecretKeySpec
(
secretKey
,
getType
()));
return
result
;
}
public
String
getType
()
{
return
SecurityType
.
AES
;
}
}
matrix-datasource/matrix-datasource-security/matrix-datasource-security-core/src/main/java/com/secoo/mall/datasource/security/algorithm/SecurityAlgorithm.java
0 → 100644
View file @
293e7d19
package
com
.
secoo
.
mall
.
datasource
.
security
.
algorithm
;
/**
* Encrypt|decrypt algorithm for SPI.
*/
public
interface
SecurityAlgorithm
{
/**
* Encode.
*
* @param plainText plainText
* @return cipherText
*/
String
encrypt
(
Object
plainText
);
/**
* Decode.
*
* @param cipherText cipherText
* @return plainText
*/
String
decrypt
(
String
cipherText
);
}
matrix-datasource/matrix-datasource-security/matrix-datasource-security-core/src/main/java/com/secoo/mall/datasource/security/constant/DBType.java
0 → 100644
View file @
293e7d19
package
com
.
secoo
.
mall
.
datasource
.
security
.
constant
;
public
class
DBType
{
public
static
final
String
MYSQL
=
"MYSQL"
;
public
static
final
String
ORACLE
=
"ORACLE"
;
}
matrix-datasource/matrix-datasource-security/matrix-datasource-security-core/src/main/java/com/secoo/mall/datasource/security/constant/SecurityType.java
0 → 100644
View file @
293e7d19
package
com
.
secoo
.
mall
.
datasource
.
security
.
constant
;
public
class
SecurityType
{
public
static
final
String
DES
=
"DES"
;
public
static
final
String
AES
=
"AES"
;
}
matrix-datasource/matrix-datasource-security/matrix-datasource-security-core/src/main/java/com/secoo/mall/datasource/security/constant/SymbolConstants.java
0 → 100644
View file @
293e7d19
package
com
.
secoo
.
mall
.
datasource
.
security
.
constant
;
public
class
SymbolConstants
{
public
static
final
String
SEPARATOR
=
","
;
public
static
final
String
EQUAL
=
"="
;
public
static
final
String
SEPARATOR_FEN
=
";"
;
}
matrix-datasource/matrix-datasource-security/matrix-datasource-security-core/src/main/java/com/secoo/mall/datasource/security/exception/SecurityException.java
0 → 100644
View file @
293e7d19
package
com
.
secoo
.
mall
.
datasource
.
security
.
exception
;
public
class
SecurityException
extends
RuntimeException
{
public
SecurityException
(
String
message
)
{
super
(
message
);
}
public
SecurityException
(
Throwable
e
)
{
super
(
e
);
}
public
SecurityException
(
String
message
,
Throwable
e
)
{
super
(
message
,
e
);
}
}
matrix-datasource/matrix-datasource-security/matrix-datasource-security-core/src/main/java/com/secoo/mall/datasource/security/exception/TableColumnException.java
0 → 100644
View file @
293e7d19
package
com
.
secoo
.
mall
.
datasource
.
security
.
exception
;
public
class
TableColumnException
extends
RuntimeException
{
private
String
message
;
public
TableColumnException
(
String
message
)
{
this
.
message
=
message
;
}
public
TableColumnException
(
String
message
,
String
message1
)
{
super
(
message
);
this
.
message
=
message1
;
}
public
TableColumnException
(
String
message
,
Throwable
cause
,
String
message1
)
{
super
(
message
,
cause
);
this
.
message
=
message1
;
}
public
TableColumnException
(
Throwable
cause
,
String
message
)
{
super
(
cause
);
this
.
message
=
message
;
}
public
TableColumnException
(
String
message
,
Throwable
cause
,
boolean
enableSuppression
,
boolean
writableStackTrace
,
String
message1
)
{
super
(
message
,
cause
,
enableSuppression
,
writableStackTrace
);
this
.
message
=
message1
;
}
@Override
public
String
getMessage
()
{
return
message
;
}
public
void
setMessage
(
String
message
)
{
this
.
message
=
message
;
}
}
\ No newline at end of file
matrix-datasource/matrix-datasource-security/matrix-datasource-security-core/src/main/java/com/secoo/mall/datasource/security/filter/AbsSecurityFilter.java
0 → 100644
View file @
293e7d19
package
com
.
secoo
.
mall
.
datasource
.
security
.
filter
;
import
com.alibaba.druid.filter.FilterEventAdapter
;
import
com.alibaba.druid.proxy.jdbc.ResultSetProxy
;
import
com.alibaba.druid.proxy.jdbc.StatementProxy
;
import
com.secoo.mall.datasource.security.rule.ColumnRule
;
import
com.secoo.mall.datasource.security.rule.TableRule
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
java.nio.charset.Charset
;
import
java.nio.charset.StandardCharsets
;
import
java.util.*
;
import
java.util.concurrent.*
;
import
java.util.concurrent.atomic.AtomicInteger
;
public
abstract
class
AbsSecurityFilter
extends
FilterEventAdapter
{
private
static
final
Logger
log
=
LoggerFactory
.
getLogger
(
AbsSecurityFilter
.
class
);
public
static
Charset
charset
=
StandardCharsets
.
UTF_8
;
private
String
dbType
;
/**
* 加密是否开启
*/
private
boolean
enabled
=
true
;
/**
* 是否启用并行处理
*/
private
boolean
parallelEnabled
;
/**
* 建议core=max
*/
private
int
corePoolSize
;
/**
* 建议core=max
*/
private
int
maxPoolSize
;
private
Map
<
String
,
Map
<
String
,
ColumnRule
>>
tableRuleMap
;
private
ExecutorService
parallelExecutor
;
public
String
getDbType
()
{
return
dbType
;
}
public
void
setDbType
(
String
dbType
)
{
this
.
dbType
=
dbType
;
}
public
boolean
isEnabled
()
{
return
enabled
;
}
public
void
setEnabled
(
boolean
enabled
)
{
this
.
enabled
=
enabled
;
}
public
boolean
isParallelEnabled
()
{
return
parallelEnabled
;
}
public
void
setParallelEnabled
(
boolean
parallelEnabled
)
{
this
.
parallelEnabled
=
parallelEnabled
;
}
public
int
getCorePoolSize
()
{
return
corePoolSize
;
}
public
void
setCorePoolSize
(
int
corePoolSize
)
{
this
.
corePoolSize
=
corePoolSize
;
}
public
int
getMaxPoolSize
()
{
return
maxPoolSize
;
}
public
void
setMaxPoolSize
(
int
maxPoolSize
)
{
this
.
maxPoolSize
=
maxPoolSize
;
}
public
Map
<
String
,
Map
<
String
,
ColumnRule
>>
getTableRuleMap
()
{
return
tableRuleMap
;
}
public
ExecutorService
getParallelExecutor
()
{
return
parallelExecutor
;
}
protected
void
resultSetOpenAfter
(
ResultSetProxy
resultSet
)
{
if
(!
enabled
)
{
return
;
}
decryptResultSet
(
resultSet
);
}
protected
abstract
void
decryptResultSet
(
ResultSetProxy
resultSet
);
protected
void
statementExecuteBefore
(
StatementProxy
statement
,
String
sql
)
{
if
(!
enabled
)
{
return
;
}
this
.
encryptStatement
(
statement
,
sql
);
}
protected
abstract
void
encryptStatement
(
StatementProxy
statement
,
String
sql
);
private
Map
<
String
,
Map
<
String
,
ColumnRule
>>
parseTableRules
(
Set
<
TableRule
>
tableRules
)
{
if
(
tableRules
==
null
||
tableRules
.
size
()
==
0
)
{
return
null
;
}
Map
<
String
,
Map
<
String
,
ColumnRule
>>
tableRuleMap
=
new
HashMap
<>();
for
(
TableRule
tableRule:
tableRules
){
if
(
tableRule
==
null
||
tableRule
.
getColumnRules
()
==
null
||
tableRule
.
getColumnRules
().
isEmpty
()){
continue
;
}
Map
<
String
,
ColumnRule
>
columnRuleMap
=
new
HashMap
<>();
for
(
ColumnRule
columnRule:
tableRule
.
getColumnRules
()){
columnRuleMap
.
put
(
columnRule
.
getLogicColumn
(),
columnRule
);
}
tableRuleMap
.
put
(
tableRule
.
getTableName
(),
columnRuleMap
);
}
return
tableRuleMap
;
}
public
void
init
(
Set
<
TableRule
>
tableRules
)
{
if
(
enabled
)
{
return
;
}
if
(
tableRules
==
null
||
tableRules
.
isEmpty
())
{
throw
new
SecurityException
(
"security tableRules is null"
);
}
this
.
tableRuleMap
=
this
.
parseTableRules
(
tableRules
);
log
.
info
(
"security tableRules is enable:{}"
,
tableRuleMap
);
if
(
parallelEnabled
)
{
if
(
corePoolSize
<=
0
||
maxPoolSize
<=
0
)
{
throw
new
SecurityException
(
"corePoolSize("
+
corePoolSize
+
") or maxPoolSize("
+
maxPoolSize
+
") is invalid"
);
}
log
.
debug
(
"init security parallelExecutors : corePoolSize={}, maxPoolSize={}"
,
this
.
corePoolSize
,
this
.
maxPoolSize
);
this
.
parallelExecutor
=
new
ThreadPoolExecutor
(
this
.
corePoolSize
,
this
.
maxPoolSize
,
300
,
TimeUnit
.
SECONDS
,
new
SynchronousQueue
<
Runnable
>(),
new
NamedThreadFactory
(
"matrix-security-"
),
new
ThreadPoolExecutor
.
CallerRunsPolicy
()
);
}
}
public
void
destroy
()
{
if
(
this
.
parallelExecutor
!=
null
){
try
{
parallelExecutor
.
shutdown
();
parallelExecutor
.
awaitTermination
(
1
,
TimeUnit
.
MINUTES
);
}
catch
(
InterruptedException
e
)
{
log
.
warn
(
"interrupted when shutdown the executor:"
,
e
);
}
}
}
static
class
NamedThreadFactory
implements
ThreadFactory
{
private
final
AtomicInteger
threadNumber
=
new
AtomicInteger
(
1
);
private
final
String
namePrefix
;
NamedThreadFactory
(
String
namePrefix
)
{
this
.
namePrefix
=
namePrefix
;
}
public
Thread
newThread
(
Runnable
runnable
)
{
return
new
Thread
(
runnable
,
namePrefix
+
threadNumber
.
getAndIncrement
());
}
}
}
matrix-datasource/matrix-datasource-security/matrix-datasource-security-core/src/main/java/com/secoo/mall/datasource/security/filter/MysqlSecurityFilter.java
0 → 100644
View file @
293e7d19
package
com
.
secoo
.
mall
.
datasource
.
security
.
filter
;
import
com.alibaba.druid.proxy.jdbc.ResultSetProxy
;
import
com.alibaba.druid.proxy.jdbc.StatementProxy
;
import
com.alibaba.druid.sql.SQLUtils
;
import
com.alibaba.druid.sql.ast.SQLExpr
;
import
com.alibaba.druid.sql.ast.SQLStatement
;
import
com.alibaba.druid.sql.ast.expr.*
;
import
com.alibaba.druid.sql.ast.statement.SQLSelectStatement
;
import
com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem
;
import
com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement
;
import
com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement
;
import
com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement
;
import
com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor
;
import
com.alibaba.druid.stat.TableStat
;
import
com.alibaba.druid.util.JdbcConstants
;
import
com.mysql.cj.BindValue
;
import
com.mysql.cj.jdbc.ClientPreparedStatement
;
import
com.mysql.cj.jdbc.result.ResultSetImpl
;
import
com.mysql.cj.protocol.ResultsetRows
;
import
com.mysql.cj.result.Field
;
import
com.mysql.cj.result.Row
;
import
com.mysql.cj.util.StringUtils
;
import
com.secoo.mall.datasource.security.rule.ColumnRule
;
import
com.secoo.mall.datasource.security.rule.TableRule
;
import
lombok.extern.slf4j.Slf4j
;
import
java.sql.Statement
;
import
java.util.*
;
import
java.util.concurrent.Callable
;
import
java.util.concurrent.Future
;
@Slf4j
public
class
MysqlSecurityFilter
extends
AbsSecurityFilter
{
@Override
protected
void
decryptResultSet
(
ResultSetProxy
resultSet
)
{
// 结果集
ResultsetRows
rows
=
((
ResultSetImpl
)
resultSet
.
getRawObject
()).
getRows
();
// 结果集字段描述
Field
[]
fields
=
rows
.
getMetadata
().
getFields
();
List
<
Future
<
Boolean
>>
futureList
=
new
LinkedList
<>();
for
(
final
Field
field:
fields
)
{
Map
<
String
,
ColumnRule
>
columnRuleMap
=
this
.
getTableRuleMap
().
get
(
field
.
getOriginalTableName
());
if
(
columnRuleMap
==
null
||
columnRuleMap
.
isEmpty
())
{
continue
;
}
ColumnRule
columnRule
=
columnRuleMap
.
get
(
field
.
getOriginalName
());
if
(
columnRule
!=
null
)
{
for
(
int
rowIndex
=
0
;
rowIndex
<
rows
.
size
();
rowIndex
++)
{
final
Row
row
=
rows
.
get
(
rowIndex
);
decrypt
(
futureList
,
columnRule
,
field
,
row
);
}
}
}
for
(
Future
<
Boolean
>
future
:
futureList
)
{
try
{
future
.
get
();
}
catch
(
Exception
e
)
{
log
.
error
(
"解密出现异常,异常部分未解密"
,
e
);
}
}
}
@Override
protected
void
encryptStatement
(
StatementProxy
statement
,
String
sql
)
{
// 解析sql
List
<
SQLStatement
>
stmtList
=
SQLUtils
.
parseStatements
(
sql
,
this
.
getDbType
());
Statement
rawObject
=
statement
.
getRawObject
();
if
(!(
rawObject
instanceof
ClientPreparedStatement
))
{
log
.
debug
(
"不需要处理的statement:{}"
,
rawObject
);
return
;
}
BindValue
[]
bindValues
=
((
ClientPreparedStatement
)
rawObject
).
getQueryBindings
().
getBindValues
();
// 解析出语句,通常只有一条,不支持超过一条语句的SQL
for
(
SQLStatement
stmt
:
stmtList
)
{
MySqlSchemaStatVisitor
visitor
=
new
MySqlSchemaStatVisitor
();
stmt
.
accept
(
visitor
);
List
<
Future
<
Boolean
>>
futureList
=
new
LinkedList
<>();
int
index
=
0
;
// 查询语句或删除语句,只有查询条件需要加密
if
(
stmt
instanceof
SQLSelectStatement
||
stmt
instanceof
MySqlDeleteStatement
)
{
// 遍历查询条件
for
(
TableStat
.
Condition
condition
:
visitor
.
getConditions
())
{
// 遍历查询条件值,一般只有一个,但in/between语句等可能有多个
for
(
Object
conditionValue
:
condition
.
getValues
())
{
// 解析出条件值为空才是查询条件
if
(
conditionValue
!=
null
)
{
continue
;
}
TableStat
.
Column
column
=
condition
.
getColumn
();
Map
<
String
,
ColumnRule
>
columnRuleMap
=
this
.
getTableRuleMap
().
get
(
column
.
getTable
());
if
(
columnRuleMap
==
null
||
columnRuleMap
.
isEmpty
())
{
continue
;
}
// 需要加密的字段
ColumnRule
columnRule
=
columnRuleMap
.
get
(
column
.
getName
());
if
(
columnRule
!=
null
)
{
encrypt
(
futureList
,
columnRule
,
bindValues
[
index
]);
}
index
++;
}
}
}
// 插入语句
else
if
(
stmt
instanceof
MySqlInsertStatement
)
{
MySqlInsertStatement
insertStmt
=
(
MySqlInsertStatement
)
stmt
;
// 插入语句应该只有一个表
String
tableName
=
insertStmt
.
getTableName
().
getSimpleName
();
Map
<
String
,
ColumnRule
>
columnRuleMap
=
this
.
getTableRuleMap
().
get
(
tableName
);
if
(
columnRuleMap
==
null
||
columnRuleMap
.
isEmpty
())
{
continue
;
}
// valuesSize>1为batch insert语句
int
valuesSize
=
insertStmt
.
getValuesList
().
size
();
Collection
<
TableStat
.
Column
>
columns
=
visitor
.
getColumns
();
// 字段数量
int
columnSize
=
columns
.
size
();
for
(
TableStat
.
Column
column
:
columns
)
{
// 需要加密的字段
ColumnRule
columnRule
=
columnRuleMap
.
get
(
column
.
getName
());
if
(
columnRule
!=
null
)
{
for
(
int
valueIndex
=
0
;
valueIndex
<
valuesSize
;
valueIndex
++)
{
BindValue
bindValue
=
bindValues
[
index
+
valueIndex
*
columnSize
];
encrypt
(
futureList
,
columnRule
,
bindValue
);
}
}
index
++;
}
}
else
if
(
stmt
instanceof
MySqlUpdateStatement
)
{
MySqlUpdateStatement
updateStat
=
(
MySqlUpdateStatement
)
stmt
;
// 更新语句应该只有一个表
String
tableName
=
updateStat
.
getTableName
().
getSimpleName
();
Map
<
String
,
ColumnRule
>
columnRuleMap
=
this
.
getTableRuleMap
().
get
(
tableName
);
if
(
columnRuleMap
==
null
||
columnRuleMap
.
isEmpty
())
{
continue
;
}
// 先处理set语句
for
(
SQLUpdateSetItem
item
:
updateStat
.
getItems
())
{
SQLExpr
column
=
item
.
getColumn
();
if
(
item
.
getValue
()
instanceof
SQLVariantRefExpr
&&
column
instanceof
SQLIdentifierExpr
)
{
// 需要加密的字段
String
columnName
=
((
SQLIdentifierExpr
)
column
).
getName
();
ColumnRule
columnRule
=
columnRuleMap
.
get
(
columnName
);
if
(
columnRule
!=
null
)
{
encrypt
(
futureList
,
columnRule
,
bindValues
[
index
]);
}
index
++;
}
}
// 再处理where语句
for
(
TableStat
.
Condition
condition
:
visitor
.
getConditions
())
{
// 遍历查询条件值,一般只有一个,但in/between语句等可能有多个
for
(
Object
conditionValue
:
condition
.
getValues
())
{
// 解析出条件值为空才是查询条件
if
(
conditionValue
==
null
)
{
continue
;
}
TableStat
.
Column
column
=
condition
.
getColumn
();
ColumnRule
columnRule
=
columnRuleMap
.
get
(
column
.
getName
());
if
(
columnRule
!=
null
)
{
encrypt
(
futureList
,
columnRule
,
bindValues
[
index
]);
}
index
++;
}
}
}
// 其他,一般没有了
else
{
for
(
TableStat
.
Column
column
:
visitor
.
getColumns
())
{
Map
<
String
,
ColumnRule
>
columnRuleMap
=
this
.
getTableRuleMap
().
get
(
column
.
getTable
());
if
(
columnRuleMap
==
null
||
columnRuleMap
.
isEmpty
())
{
continue
;
}
// 需要加密的字段
ColumnRule
columnRule
=
columnRuleMap
.
get
(
column
.
getName
());
if
(
columnRule
!=
null
)
{
encrypt
(
futureList
,
columnRule
,
bindValues
[
index
]);
}
index
++;
}
}
for
(
Future
<
Boolean
>
future
:
futureList
)
{
try
{
future
.
get
();
}
catch
(
Exception
e
)
{
log
.
error
(
"加密出现异常,异常部分未加密"
,
e
);
}
}
}
}
private
void
encrypt
(
List
<
Future
<
Boolean
>>
futureList
,
final
ColumnRule
columnRule
,
final
BindValue
bindValue
)
{
final
String
origValue
=
getBindValue
(
bindValue
);
if
(
origValue
==
null
)
{
return
;
}
if
(
this
.
isParallelEnabled
())
{
Future
<
Boolean
>
future
=
this
.
getParallelExecutor
().
submit
(
new
Callable
<
Boolean
>()
{
@Override
public
Boolean
call
()
throws
Exception
{
encrypt
(
columnRule
,
origValue
,
bindValue
);
return
true
;
}
});
futureList
.
add
(
future
);
}
else
{
encrypt
(
columnRule
,
origValue
,
bindValue
);
}
}
private
void
encrypt
(
ColumnRule
columnRule
,
String
origValue
,
BindValue
bindValue
)
{
String
encryptValue
=
columnRule
.
getSecurityAlgorithm
().
encrypt
(
origValue
);
encryptValue
=
"'"
+
encryptValue
+
"'"
;
bindValue
.
setByteValue
(
encryptValue
.
getBytes
(
charset
));
log
.
debug
(
"字段加密:columnRule={},origValue={},encryptValue={}"
,
columnRule
,
origValue
,
encryptValue
);
}
private
void
decrypt
(
List
<
Future
<
Boolean
>>
futureList
,
final
ColumnRule
columnRule
,
final
Field
field
,
final
Row
row
)
{
int
index
=
field
.
getCollationIndex
();
byte
[]
bytes
=
row
.
getBytes
(
index
);
if
(
bytes
!=
null
&&
bytes
.
length
>
0
)
{
final
String
origValue
=
StringUtils
.
toString
(
bytes
,
charset
.
name
());
if
(
this
.
isParallelEnabled
())
{
Future
<
Boolean
>
future
=
this
.
getParallelExecutor
().
submit
(
new
Callable
<
Boolean
>()
{
@Override
public
Boolean
call
()
{
decrypt
(
columnRule
,
row
,
origValue
,
index
);
return
true
;
}
});
futureList
.
add
(
future
);
}
else
{
decrypt
(
columnRule
,
row
,
origValue
,
index
);
}
}
}
private
void
decrypt
(
ColumnRule
columnRule
,
Row
row
,
String
origValue
,
int
index
)
{
String
decryptValue
=
columnRule
.
getSecurityAlgorithm
().
decrypt
(
origValue
);
row
.
setBytes
(
index
,
decryptValue
.
getBytes
(
charset
));
log
.
debug
(
"字段解密:columnRule={},origValue={},decryptValue={}"
,
columnRule
,
origValue
,
decryptValue
);
}
private
String
getBindValue
(
BindValue
bindValue
)
{
if
(
bindValue
.
isNull
())
{
return
null
;
}
byte
[]
byteValue
=
bindValue
.
getByteValue
();
if
(
byteValue
==
null
||
byteValue
.
length
==
0
)
{
return
null
;
}
String
origValue
=
StringUtils
.
toString
(
byteValue
,
charset
.
name
());
if
(
"''"
.
equals
(
origValue
)
||
""
.
equals
(
origValue
))
{
return
null
;
}
// 参数可能自带''单引号,需要去掉''单引号
if
(
origValue
.
startsWith
(
"'"
)
&&
origValue
.
endsWith
(
"'"
))
{
origValue
=
origValue
.
substring
(
1
,
origValue
.
length
()
-
1
);
}
return
origValue
;
}
public
void
init
(
Set
<
TableRule
>
tableRules
)
{
super
.
init
(
tableRules
);
this
.
setDbType
(
JdbcConstants
.
MYSQL
);
}
}
matrix-datasource/matrix-datasource-security/matrix-datasource-security-core/src/main/java/com/secoo/mall/datasource/security/rule/ColumnRule.java
0 → 100644
View file @
293e7d19
package
com
.
secoo
.
mall
.
datasource
.
security
.
rule
;
import
com.secoo.mall.datasource.security.algorithm.AESSecurityAlgorithm
;
import
com.secoo.mall.datasource.security.algorithm.SecurityAlgorithm
;
public
class
ColumnRule
{
private
String
encryptType
;
/**
* 加密器配置
*/
private
String
encryptKey
;
/**
* 逻辑字段名称
*/
private
String
logicColumn
;
/**
* 明文字段名称
*/
private
String
plainColumn
;
/**
* 加密字段名称
*/
private
String
cipherColumn
;
/**
* 加密器
*/
private
SecurityAlgorithm
securityAlgorithm
;
public
String
getEncryptKey
()
{
return
encryptKey
;
}
public
void
setEncryptKey
(
String
encryptKey
)
{
this
.
encryptKey
=
encryptKey
;
this
.
securityAlgorithm
=
new
AESSecurityAlgorithm
(
encryptKey
);
}
public
String
getLogicColumn
()
{
return
logicColumn
;
}
public
void
setLogicColumn
(
String
logicColumn
)
{
this
.
logicColumn
=
logicColumn
;
}
public
String
getPlainColumn
()
{
return
plainColumn
;
}
public
void
setPlainColumn
(
String
plainColumn
)
{
this
.
plainColumn
=
plainColumn
;
}
public
String
getCipherColumn
()
{
return
cipherColumn
;
}
public
void
setCipherColumn
(
String
cipherColumn
)
{
this
.
cipherColumn
=
cipherColumn
;
}
public
SecurityAlgorithm
getSecurityAlgorithm
()
{
return
securityAlgorithm
;
}
public
void
setSecurityAlgorithm
(
SecurityAlgorithm
securityAlgorithm
)
{
this
.
securityAlgorithm
=
securityAlgorithm
;
}
}
matrix-datasource/matrix-datasource-security/matrix-datasource-security-core/src/main/java/com/secoo/mall/datasource/security/rule/DataSourceRule.java
0 → 100644
View file @
293e7d19
package
com
.
secoo
.
mall
.
datasource
.
security
.
rule
;
import
java.util.Set
;
public
class
DataSourceRule
{
/**
* 数据库名
*/
private
String
datasourceName
;
/**
* 表规则
*/
private
Set
<
TableRule
>
tableRules
;
public
String
getDatasourceName
()
{
return
datasourceName
;
}
public
void
setDatasourceName
(
String
datasourceName
)
{
this
.
datasourceName
=
datasourceName
;
}
public
Set
<
TableRule
>
getTableRules
()
{
return
tableRules
;
}
public
void
setTableRules
(
Set
<
TableRule
>
tableRules
)
{
this
.
tableRules
=
tableRules
;
}
}
matrix-datasource/matrix-datasource-security/matrix-datasource-security-core/src/main/java/com/secoo/mall/datasource/security/rule/TableRule.java
0 → 100644
View file @
293e7d19
package
com
.
secoo
.
mall
.
datasource
.
security
.
rule
;
import
java.util.Set
;
public
class
TableRule
{
/**
* 表名
*/
private
String
tableName
;
/**
* 列规则
*/
private
Set
<
ColumnRule
>
columnRules
;
public
String
getTableName
()
{
return
tableName
;
}
public
void
setTableName
(
String
tableName
)
{
this
.
tableName
=
tableName
;
}
public
Set
<
ColumnRule
>
getColumnRules
()
{
return
columnRules
;
}
public
void
setColumnRules
(
Set
<
ColumnRule
>
columnRules
)
{
this
.
columnRules
=
columnRules
;
}
}
matrix-datasource/matrix-datasource-security/matrix-datasource-security-starter/pom.xml
0 → 100644
View file @
293e7d19
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns=
"http://maven.apache.org/POM/4.0.0"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<parent>
<artifactId>
matrix-datasource-security
</artifactId>
<groupId>
com.secoo.mall
</groupId>
<version>
2.0.17.RELEASE
</version>
</parent>
<modelVersion>
4.0.0
</modelVersion>
<artifactId>
matrix-datasource-security-starter
</artifactId>
<packaging>
jar
</packaging>
<dependencies>
<dependency>
<groupId>
com.secoo.mall
</groupId>
<artifactId>
matrix-datasource-security-core
</artifactId>
</dependency>
<dependency>
<groupId>
com.secoo.mall
</groupId>
<artifactId>
matrix-datasource-core
</artifactId>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter
</artifactId>
</dependency>
</dependencies>
<build>
<finalName>
matrix-datasource-security-starter
</finalName>
<plugins>
<plugin>
<artifactId>
maven-resources-plugin
</artifactId>
</plugin>
</plugins>
</build>
</project>
matrix-datasource/matrix-datasource-security/matrix-datasource-security-starter/src/main/java/com/secoo/mall/datasource/security/config/DataSourceSecurityAutoConfiguration.java
0 → 100644
View file @
293e7d19
package
com
.
secoo
.
mall
.
datasource
.
security
.
config
;
import
com.alibaba.druid.filter.Filter
;
import
com.alibaba.druid.pool.DruidDataSource
;
import
com.secoo.mall.datasource.bean.MatrixDataSource
;
import
com.secoo.mall.datasource.security.constant.DBType
;
import
com.secoo.mall.datasource.security.filter.MysqlSecurityFilter
;
import
org.springframework.beans.BeansException
;
import
org.springframework.beans.factory.SmartInitializingSingleton
;
import
org.springframework.boot.context.properties.EnableConfigurationProperties
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.context.ApplicationContextAware
;
import
org.springframework.context.ConfigurableApplicationContext
;
import
org.springframework.context.annotation.Configuration
;
import
javax.sql.DataSource
;
import
java.util.ArrayList
;
import
java.util.Map
;
@Configuration
@EnableConfigurationProperties
(
DataSourceSecurityProperties
.
class
)
public
class
DataSourceSecurityAutoConfiguration
implements
ApplicationContextAware
,
SmartInitializingSingleton
{
private
ConfigurableApplicationContext
applicationContext
;
private
DataSourceSecurityProperties
properties
;
DataSourceSecurityAutoConfiguration
(
DataSourceSecurityProperties
properties
){
this
.
properties
=
properties
;
}
@Override
public
void
afterSingletonsInstantiated
()
{
if
(
properties
==
null
||
properties
.
getDatasourceRules
()
==
null
||
properties
.
getDatasourceRules
().
size
()
==
0
){
throw
new
RuntimeException
(
"DataSourceSecurityProperties is null!"
);
}
Map
<
String
,
DataSource
>
dataSourceBeans
=
this
.
applicationContext
.
getBeansOfType
(
DataSource
.
class
);
properties
.
getDatasourceRules
().
forEach
(
datasourceRule
->
{
DataSource
dataSource
=
dataSourceBeans
.
get
(
datasourceRule
.
getDatasourceName
());
if
(
dataSource
==
null
){
return
;
}
DruidDataSource
druidDataSource
=
null
;
if
(
dataSource
instanceof
DruidDataSource
){
druidDataSource
=
(
DruidDataSource
)
dataSource
;
}
else
if
(
dataSource
instanceof
MatrixDataSource
){
druidDataSource
=
(
DruidDataSource
)
((
MatrixDataSource
)
dataSource
).
getTargetDataSource
(((
MatrixDataSource
)
dataSource
).
getDsName
());
}
if
(
druidDataSource
==
null
){
return
;
}
if
(
druidDataSource
.
getDbType
().
equals
(
DBType
.
MYSQL
)){
MysqlSecurityFilter
securityFilter
=
new
MysqlSecurityFilter
();
securityFilter
.
setEnabled
(
properties
.
getEnabled
()
!=
null
&&
properties
.
getEnabled
());
securityFilter
.
setParallelEnabled
(
properties
.
getParallelEnabled
()
!=
null
&&
properties
.
getParallelEnabled
());
if
(
securityFilter
.
isParallelEnabled
()){
securityFilter
.
setCorePoolSize
(
properties
.
getCorePoolSize
()
==
null
?
0
:
properties
.
getCorePoolSize
());
securityFilter
.
setMaxPoolSize
(
properties
.
getMaxPoolSize
()
==
null
?
Integer
.
MAX_VALUE
:
properties
.
getMaxPoolSize
());
}
securityFilter
.
init
(
datasourceRule
.
getTableRules
());
druidDataSource
.
setProxyFilters
(
new
ArrayList
<
Filter
>(){{
add
(
securityFilter
);}});
}
});
}
@Override
public
void
setApplicationContext
(
ApplicationContext
applicationContext
)
throws
BeansException
{
this
.
applicationContext
=
(
ConfigurableApplicationContext
)
applicationContext
;
}
}
matrix-datasource/matrix-datasource-security/matrix-datasource-security-starter/src/main/java/com/secoo/mall/datasource/security/config/DataSourceSecurityProperties.java
0 → 100644
View file @
293e7d19
package
com
.
secoo
.
mall
.
datasource
.
security
.
config
;
import
com.secoo.mall.datasource.security.rule.DataSourceRule
;
import
org.springframework.boot.context.properties.ConfigurationProperties
;
import
java.util.Set
;
@ConfigurationProperties
(
prefix
=
DataSourceSecurityProperties
.
PREFIX
)
public
class
DataSourceSecurityProperties
{
public
static
final
String
PREFIX
=
"spring.matrix.security"
;
private
Boolean
enabled
=
true
;
/**
* 是否启用并行处理,默认不启用
*/
private
Boolean
parallelEnabled
=
false
;
/**
* 建议core=max
*/
private
Integer
corePoolSize
;
/**
* 建议core=max
*/
private
Integer
maxPoolSize
;
/**
* 加解密规则
*/
public
Set
<
DataSourceRule
>
datasourceRules
;
public
Boolean
getEnabled
()
{
return
enabled
;
}
public
void
setEnabled
(
Boolean
enabled
)
{
this
.
enabled
=
enabled
;
}
public
Boolean
getParallelEnabled
()
{
return
parallelEnabled
;
}
public
void
setParallelEnabled
(
Boolean
parallelEnabled
)
{
this
.
parallelEnabled
=
parallelEnabled
;
}
public
Integer
getCorePoolSize
()
{
return
corePoolSize
;
}
public
void
setCorePoolSize
(
Integer
corePoolSize
)
{
this
.
corePoolSize
=
corePoolSize
;
}
public
Integer
getMaxPoolSize
()
{
return
maxPoolSize
;
}
public
void
setMaxPoolSize
(
Integer
maxPoolSize
)
{
this
.
maxPoolSize
=
maxPoolSize
;
}
public
Set
<
DataSourceRule
>
getDatasourceRules
()
{
return
datasourceRules
;
}
public
void
setDatasourceRules
(
Set
<
DataSourceRule
>
datasourceRules
)
{
this
.
datasourceRules
=
datasourceRules
;
}
}
matrix-datasource/matrix-datasource-security/pom.xml
0 → 100644
View file @
293e7d19
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns=
"http://maven.apache.org/POM/4.0.0"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<parent>
<artifactId>
matrix-datasource
</artifactId>
<groupId>
com.secoo.mall
</groupId>
<version>
2.0.17.RELEASE
</version>
</parent>
<modelVersion>
4.0.0
</modelVersion>
<artifactId>
matrix-datasource-security
</artifactId>
<packaging>
pom
</packaging>
<modules>
<module>
matrix-datasource-security-core
</module>
<module>
matrix-datasource-security-starter
</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>
com.secoo.mall
</groupId>
<artifactId>
matrix-datasource-security-core
</artifactId>
<version>
2.0.17.RELEASE
</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>
junit
</groupId>
<artifactId>
junit
</artifactId>
<scope>
test
</scope>
</dependency>
</dependencies>
</project>
matrix-datasource/pom.xml
View file @
293e7d19
...
...
@@ -14,6 +14,7 @@
<modules>
<module>
matrix-datasource-core
</module>
<module>
matrix-datasource-druid
</module>
<module>
matrix-datasource-security
</module>
</modules>
<dependencyManagement>
...
...
pom.xml
View file @
293e7d19
...
...
@@ -210,11 +210,6 @@
<artifactId>
joda-time
</artifactId>
<version>
2.10
</version>
</dependency>
<dependency>
<groupId>
com.esotericsoftware
</groupId>
<artifactId>
kryo
</artifactId>
<version>
4.0.2
</version>
</dependency>
<!--protobuf-->
<dependency>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment