1
0
mirror of https://github.com/apache/dubbo.git synced 2024-10-23 07:04:37 +08:00

Add serialization check (#11217)

This commit is contained in:
Albumen Kevin 2023-01-11 11:41:52 +08:00 committed by GitHub
parent 671c7ff950
commit 84c1c35aae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
54 changed files with 1540 additions and 244 deletions

View File

@ -22,6 +22,7 @@ import org.apache.dubbo.common.convert.ConverterUtil;
import org.apache.dubbo.common.lang.ShutdownHookCallbacks;
import org.apache.dubbo.common.status.reporter.FrameworkStatusReportService;
import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository;
import org.apache.dubbo.common.utils.SerializeSecurityManager;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.FrameworkModel;
import org.apache.dubbo.rpc.model.ModuleModel;
@ -33,6 +34,7 @@ public class CommonScopeModelInitializer implements ScopeModelInitializer {
ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
beanFactory.registerBean(FrameworkExecutorRepository.class);
beanFactory.registerBean(ConverterUtil.class);
beanFactory.registerBean(SerializeSecurityManager.class);
}
@Override

View File

@ -429,6 +429,8 @@ public interface CommonConstants {
String SERIALIZE_BLOCKED_LIST_FILE_PATH = "security/serialize.blockedlist";
String SERIALIZE_ALLOW_LIST_FILE_PATH = "security/serialize.allowlist";
String QOS_LIVE_PROBE_EXTENSION = "dubbo.application.liveness-probe";
String QOS_READY_PROBE_EXTENSION = "dubbo.application.readiness-probe";

View File

@ -0,0 +1,26 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.utils;
import java.util.Set;
public interface AllowClassNotifyListener {
SerializeCheckStatus DEFAULT_STATUS = SerializeCheckStatus.STRICT;
void notify(SerializeCheckStatus status, Set<String> prefixList);
}

View File

@ -24,11 +24,11 @@ import java.io.IOException;
import java.lang.ref.SoftReference;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
@ -46,7 +46,7 @@ public class ClassLoaderResourceLoader {
GlobalResourcesRepository.registerGlobalDisposable(() -> destroy());
}
public static Map<ClassLoader, Set<URL>> loadResources(String fileName, List<ClassLoader> classLoaders) throws InterruptedException {
public static Map<ClassLoader, Set<URL>> loadResources(String fileName, Collection<ClassLoader> classLoaders) throws InterruptedException {
Map<ClassLoader, Set<URL>> resources = new ConcurrentHashMap<>();
CountDownLatch countDownLatch = new CountDownLatch(classLoaders.size());
for (ClassLoader classLoader : classLoaders) {

View File

@ -0,0 +1,23 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.utils;
public enum SerializeCheckStatus {
DISABLED,
WARN,
STRICT,
}

View File

@ -17,7 +17,6 @@
package org.apache.dubbo.common.utils;
import org.apache.dubbo.common.beanutil.JavaBeanSerializeUtil;
import org.apache.dubbo.common.config.ConfigurationUtils;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
@ -52,10 +51,10 @@ public class SerializeClassChecker {
private final AtomicLong counter = new AtomicLong(0);
private SerializeClassChecker() {
String openCheckClass = ConfigurationUtils.getProperty(CommonConstants.CLASS_DESERIALIZE_OPEN_CHECK, "true");
String openCheckClass = System.getProperty(CommonConstants.CLASS_DESERIALIZE_OPEN_CHECK, "true");
OPEN_CHECK_CLASS = Boolean.parseBoolean(openCheckClass);
String blockAllClassExceptAllow = ConfigurationUtils.getProperty(CLASS_DESERIALIZE_BLOCK_ALL, "false");
String blockAllClassExceptAllow = System.getProperty(CLASS_DESERIALIZE_BLOCK_ALL, "false");
BLOCK_ALL_CLASS_EXCEPT_ALLOW = Boolean.parseBoolean(blockAllClassExceptAllow);
@ -79,8 +78,8 @@ public class SerializeClassChecker {
logger.error(COMMON_IO_EXCEPTION, "", "", "Failed to load blocked class list! Will ignore default blocked list.", e);
}
String allowedClassList = ConfigurationUtils.getProperty(CLASS_DESERIALIZE_ALLOWED_LIST, "").trim().toLowerCase(Locale.ROOT);
String blockedClassList = ConfigurationUtils.getProperty(CLASS_DESERIALIZE_BLOCKED_LIST, "").trim().toLowerCase(Locale.ROOT);
String allowedClassList = System.getProperty(CLASS_DESERIALIZE_ALLOWED_LIST, "").trim().toLowerCase(Locale.ROOT);
String blockedClassList = System.getProperty(CLASS_DESERIALIZE_BLOCKED_LIST, "").trim().toLowerCase(Locale.ROOT);
if (StringUtils.isNotEmpty(allowedClassList)) {
String[] classStrings = allowedClassList.trim().split(",");
@ -120,34 +119,45 @@ public class SerializeClassChecker {
* @throws IllegalArgumentException if class is blocked
*/
public void validateClass(String name) {
validateClass(name, true);
}
public boolean validateClass(String name, boolean failOnError) {
if (!OPEN_CHECK_CLASS) {
return;
return true;
}
name = name.toLowerCase(Locale.ROOT);
if (CACHE == CLASS_ALLOW_LFU_CACHE.get(name)) {
return;
return true;
}
if (CACHE == CLASS_BLOCK_LFU_CACHE.get(name)) {
error(name);
if (failOnError) {
error(name);
}
return false;
}
for (String allowedPrefix : CLASS_DESERIALIZE_ALLOWED_SET) {
if (name.startsWith(allowedPrefix)) {
CLASS_ALLOW_LFU_CACHE.put(name, CACHE);
return;
return true;
}
}
for (String blockedPrefix : CLASS_DESERIALIZE_BLOCKED_SET) {
if (BLOCK_ALL_CLASS_EXCEPT_ALLOW || name.startsWith(blockedPrefix)) {
CLASS_BLOCK_LFU_CACHE.put(name, CACHE);
error(name);
if (failOnError) {
error(name);
}
return false;
}
}
CLASS_ALLOW_LFU_CACHE.put(name, CACHE);
return true;
}
private void error(String name) {

View File

@ -0,0 +1,220 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.utils;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.rpc.model.FrameworkModel;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.net.URL;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static org.apache.dubbo.common.constants.CommonConstants.SERIALIZE_ALLOW_LIST_FILE_PATH;
public class SerializeSecurityManager {
private final Set<String> allowedPrefix = new LinkedHashSet<>();
private final static Logger logger = LoggerFactory.getLogger(SerializeSecurityManager.class);
private final SerializeClassChecker checker = SerializeClassChecker.getInstance();
private final Set<AllowClassNotifyListener> listeners = new ConcurrentHashSet<>();
private volatile SerializeCheckStatus checkStatus = AllowClassNotifyListener.DEFAULT_STATUS;
public SerializeSecurityManager(FrameworkModel frameworkModel) {
try {
Set<ClassLoader> classLoaders = frameworkModel.getClassLoaders();
List<URL> urls = ClassLoaderResourceLoader.loadResources(SERIALIZE_ALLOW_LIST_FILE_PATH, classLoaders)
.values()
.stream()
.flatMap(Set::stream)
.collect(Collectors.toList());
for (URL u : urls) {
try {
String[] lines = IOUtils.readLines(u.openStream());
for (String line : lines) {
line = line.trim();
if (StringUtils.isEmpty(line) || line.startsWith("#")) {
continue;
}
allowedPrefix.add(line);
}
} catch (IOException e) {
logger.error("Failed to load allow class list! Will ignore allow lis from " + u, e);
}
}
} catch (InterruptedException e) {
logger.error("Failed to load allow class list! Will ignore allow list from configuration.", e);
}
}
public void registerInterface(Class<?> clazz) {
Set<Class<?>> markedClass = new HashSet<>();
markedClass.add(clazz);
addToAllow(clazz.getName());
Method[] methodsToExport = clazz.getMethods();
for (Method method : methodsToExport) {
Class<?>[] parameterTypes = method.getParameterTypes();
for (Class<?> parameterType : parameterTypes) {
checkClass(markedClass, parameterType);
}
Type[] genericParameterTypes = method.getGenericParameterTypes();
for (Type genericParameterType : genericParameterTypes) {
checkType(markedClass, genericParameterType);
}
Class<?> returnType = method.getReturnType();
checkClass(markedClass, returnType);
Type genericReturnType = method.getGenericReturnType();
checkType(markedClass, genericReturnType);
Class<?>[] exceptionTypes = method.getExceptionTypes();
for (Class<?> exceptionType : exceptionTypes) {
checkClass(markedClass, exceptionType);
}
Type[] genericExceptionTypes = method.getGenericExceptionTypes();
for (Type genericExceptionType : genericExceptionTypes) {
checkType(markedClass, genericExceptionType);
}
}
}
private void checkType(Set<Class<?>> markedClass, Type type) {
if (type instanceof Class) {
checkClass(markedClass, (Class<?>) type);
} else if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
checkClass(markedClass, (Class<?>) parameterizedType.getRawType());
for (Type actualTypeArgument : parameterizedType.getActualTypeArguments()) {
checkType(markedClass, actualTypeArgument);
}
} else if (type instanceof GenericArrayType) {
GenericArrayType genericArrayType = (GenericArrayType) type;
checkType(markedClass, genericArrayType.getGenericComponentType());
} else if (type instanceof TypeVariable) {
TypeVariable typeVariable = (TypeVariable) type;
for (Type bound : typeVariable.getBounds()) {
checkType(markedClass, bound);
}
} else if (type instanceof WildcardType) {
WildcardType wildcardType = (WildcardType) type;
for (Type bound : wildcardType.getUpperBounds()) {
checkType(markedClass, bound);
}
for (Type bound : wildcardType.getLowerBounds()) {
checkType(markedClass, bound);
}
}
}
private void checkClass(Set<Class<?>> markedClass, Class<?> clazz) {
if (markedClass.contains(clazz)) {
return;
}
markedClass.add(clazz);
addToAllow(clazz.getName());
Class<?>[] interfaces = clazz.getInterfaces();
for (Class<?> interfaceClass : interfaces) {
checkClass(markedClass, interfaceClass);
}
Class<?> superclass = clazz.getSuperclass();
if (superclass != null) {
checkClass(markedClass, superclass);
}
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (Modifier.isTransient(field.getModifiers())) {
continue;
}
Class<?> fieldClass = field.getType();
checkClass(markedClass, fieldClass);
checkType(markedClass, field.getGenericType());
}
}
protected void addToAllow(String className) {
if (!checker.validateClass(className, false)) {
return;
}
boolean modified;
// ignore jdk
if (className.startsWith("java.") || className.startsWith("javax.") || className.startsWith("com.sun.") ||
className.startsWith("sun.") || className.startsWith("jdk.")) {
modified = allowedPrefix.add(className);
if (modified) {
notifyListeners();
}
return;
}
// add group package
String[] subs = className.split("\\.");
if (subs.length > 3) {
modified = allowedPrefix.add(subs[0] + "." + subs[1] + "." + subs[2]);
} else {
modified = allowedPrefix.add(className);
}
if (modified) {
notifyListeners();
}
}
public void registerListener(AllowClassNotifyListener listener) {
listeners.add(listener);
listener.notify(checkStatus, allowedPrefix);
}
private void notifyListeners() {
for (AllowClassNotifyListener listener : listeners) {
listener.notify(checkStatus, allowedPrefix);
}
}
protected Set<String> getAllowedPrefix() {
return allowedPrefix;
}
}

View File

@ -0,0 +1,125 @@
#
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
boolean
byte
char
double
float
int
long
short
java.lang.AutoCloseable
java.lang.Boolean
java.lang.Byte
java.lang.Character
java.lang.Class
java.lang.Cloneable
java.lang.Double
java.lang.Exception
java.lang.Float
java.lang.IllegalAccessError
java.lang.IllegalAccessException
java.lang.IllegalArgumentException
java.lang.IllegalMonitorStateException
java.lang.IllegalStateException
java.lang.IllegalThreadStateException
java.lang.IndexOutOfBoundsException
java.lang.InstantiationError
java.lang.InstantiationException
java.lang.Integer
java.lang.InternalError
java.lang.InterruptedException
java.lang.LinkageError
java.lang.Long
java.lang.NegativeArraySizeException
java.lang.NoClassDefFoundError
java.lang.NoSuchFieldError
java.lang.NoSuchFieldException
java.lang.NoSuchMethodError
java.lang.NoSuchMethodException
java.lang.NullPointerException
java.lang.Number
java.lang.NumberFormatException
java.lang.Object
java.lang.OutOfMemoryError
java.lang.RuntimeException
java.lang.SecurityException
java.lang.Short
java.lang.StackOverflowError
java.lang.StackTraceElement
java.lang.String
java.lang.StringIndexOutOfBoundsException
java.lang.TypeNotPresentException
java.lang.VerifyError
java.math.BigDecimal
java.math.BigInteger
java.text.SimpleDateFormat
java.time.format.DateTimeFormatter
java.time.Instant
java.time.LocalDate
java.time.LocalDateTime
java.time.LocalTime
java.util.ArrayList
java.util.Arrays$ArrayList
java.util.BitSet
java.util.Calendar
java.util.Collections$EmptyList
java.util.Collections$EmptyMap
java.util.Collections$SingletonSet
java.util.Collections$UnmodifiableCollection
java.util.Collections$UnmodifiableList
java.util.Collections$UnmodifiableMap
java.util.Collections$UnmodifiableNavigableMap
java.util.Collections$UnmodifiableNavigableSet
java.util.Collections$UnmodifiableRandomAccessList
java.util.Collections$UnmodifiableSet
java.util.Collections$UnmodifiableSortedMap
java.util.Collections$UnmodifiableSortedSet
java.util.concurrent.atomic.AtomicBoolean
java.util.concurrent.atomic.AtomicInteger
java.util.concurrent.atomic.AtomicIntegerArray
java.util.concurrent.atomic.AtomicLong
java.util.concurrent.atomic.AtomicLongArray
java.util.concurrent.atomic.AtomicReference
java.util.concurrent.ConcurrentHashMap
java.util.concurrent.ConcurrentLinkedQueue
java.util.concurrent.ConcurrentMap
java.util.concurrent.ConcurrentSkipListMap
java.util.concurrent.ConcurrentSkipListSet
java.util.concurrent.CopyOnWriteArrayList
java.util.concurrent.TimeUnit
java.util.Currency
java.util.Date
java.util.EnumSet
java.util.HashMap
java.util.HashSet
java.util.Hashtable
java.util.IdentityHashMap
java.util.LinkedHashMap
java.util.LinkedHashSet
java.util.LinkedList
java.util.List
java.util.Locale
java.util.Map
java.util.Set
java.util.TreeMap
java.util.TreeSet
java.util.UUID
java.util.WeakHashMap
org.apache.dubbo

View File

@ -18,33 +18,38 @@
#
aj.org.objectweb.asm.
br.com.anteros.
bsh.
ch.qos.logback.
clojure.core$constantly
clojure.main$eval_opt
com.alibaba.citrus.springext.support.parser.abstractnamedproxybeandefinitionparser$proxytargetfactory
com.alibaba.citrus.springext.util.springextutil.abstractproxy
com.alibaba.druid.pool.druiddatasource
clojure.
com.alibaba.citrus.springext.support.parser.
com.alibaba.citrus.springext.util.SpringExtUtil.
com.alibaba.druid.pool.
com.alibaba.druid.stat.jdbcdatasourcestat
com.alibaba.fastjson.annotation
com.alipay.custrelation.service.model.redress.pair
com.alibaba.hotcode.internal.org.apache.commons.collections.functors.
com.alipay.custrelation.service.model.redress.
com.alipay.oceanbase.obproxy.druid.pool.
com.caucho.
com.ibatis.
com.ibm.jtc.jax.xml.bind.v2.runtime.unmarshaller.
com.ibm.xltxe.rnm1.xtq.bcel.util.
com.mchange
com.mysql.cj.jdbc.admin.
com.mysql.cj.jdbc.mysqlconnectionpooldatasource
com.mysql.cj.jdbc.mysqldatasource
com.mysql.cj.jdbc.mysqlxadatasource
com.mysql.cj.log.
com.mysql.jdbc.util.
com.p6spy.engine.
com.rometools.rome.feed.impl.equalsbean
com.rometools.rome.feed.impl.tostringbean
com.rometools.rome.feed.
com.sun.
com.taobao.eagleeye.wrapper
com.taobao.vipserver.commons.collections.functors.
com.zaxxer.hikari.
flex.messaging.util.concurrent.
java.awt.i
java.awt.p
java.beans.expression
groovy.lang.
java.awt.
java.beans.
java.io.closeable
java.io.serializable
java.lang.autocloseable
@ -52,41 +57,46 @@ java.lang.class
java.lang.cloneable
java.lang.iterable
java.lang.object
java.lang.ProcessBuilder
java.lang.readable
java.lang.runnable
java.lang.Runtime
java.lang.thread
java.lang.unixprocess
java.net.inetaddress
java.net.socket
java.net.url
java.rmi
java.security.signedobject
java.security.
java.util.collection
java.util.eventlistener
java.util.jar.
java.util.logging.
java.util.prefs.
java.util.ServiceLoader
java.util.serviceloader$lazyiterator
java.util.StringTokenizer
javassist.
javax.activation.
javax.imageio.imageio$containsfilter
javax.imageio.spi.serviceregistry
javax.imageio.
javax.management.
javax.media.jai.remote.
javax.naming.
javax.net.
javax.print.
javax.script.
javax.sound.
javax.swing.j
javax.swing.
javax.tools.
javax.xml
jdk.internal.
jodd.db.connection.
junit.
net.bytebuddy.dynamic.loading.bytearrayclassloader
net.bytebuddy.dynamic.loading.
net.sf.cglib.
net.sf.ehcache.hibernate.
net.sf.ehcache.transaction.manager.
ognl.
oracle.jdbc.
oracle.jms.aq
oracle.net
@ -100,10 +110,12 @@ org.apache.aries.transaction.
org.apache.axis2.jaxws.spi.handler.
org.apache.axis2.transport.jms.
org.apache.bcel
org.apache.carbondata.core.scan.expression.
org.apache.carbondata.core.scan.expression.expressionresult
org.apache.catalina.
org.apache.cocoon.
org.apache.commons.beanutils
org.apache.commons.codec.
org.apache.commons.collections.comparators.
org.apache.commons.collections.functors
org.apache.commons.collections.functors.
@ -112,6 +124,7 @@ org.apache.commons.collections4.comparators
org.apache.commons.collections4.functors
org.apache.commons.collections4.transformer
org.apache.commons.configuration
org.apache.commons.configuration2.
org.apache.commons.dbcp
org.apache.commons.fileupload
org.apache.commons.jelly.
@ -130,32 +143,43 @@ org.apache.ibatis.ognl.
org.apache.ibatis.parsing.
org.apache.ibatis.reflection.
org.apache.ibatis.scripting.
org.apache.ignite.cache.
org.apache.ignite.cache.jta.
org.apache.log.output.db.
org.apache.log4j.
org.apache.logging.
org.apache.myfaces.context.servlet
org.apache.myfaces.view.facelets.el.
org.apache.openjpa.ee.
org.apache.shiro.jndi.
org.apache.shiro.realm.
org.apache.shiro.
org.apache.tomcat
org.apache.velocity.
org.apache.wicket.util
org.apache.xalan
org.apache.xbean.
org.apache.xpath.xpathcontext
org.apache.xpath.
org.apache.zookeeper.
org.aspectj.
org.codehaus.groovy.runtime
org.codehaus.jackson.
org.datanucleus.store.rdbms.datasource.dbcp.datasources.
org.dom4j.
org.eclipse.jetty.
org.geotools.filter.constantexpression
org.geotools.filter.
org.h2.jdbcx.
org.h2.server.
org.h2.value.
org.hibernate
org.javasimon.
org.jaxen.
org.jboss
org.jdom.
org.jdom2.transform.
org.junit.
org.logicalcobwebs.
org.mockito.
org.mortbay.jetty.
org.mortbay.log.
org.mozilla.javascript
org.objectweb.asm.
org.osjava.sj.
@ -163,5 +187,11 @@ org.python.core
org.quartz.
org.slf4j.
org.springframework.
org.yaml.snakeyaml.tokens.directivetoken
sun.rmi.server.unicastref
org.thymeleaf.
org.yaml.snakeyaml.tokens.
pstore.shaded.org.apache.commons.collections.
sun.print.
sun.rmi.server.
sun.rmi.transport.
weblogic.ejb20.internal.
weblogic.jms.common.

View File

@ -0,0 +1,29 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.pojo;
public class Demo1 {
private Simple simple;
public Simple getSimple() {
return simple;
}
public void setSimple(Simple simple) {
this.simple = simple;
}
}

View File

@ -0,0 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.pojo;
public class Demo2 {
}

View File

@ -0,0 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.pojo;
public class Demo3 {
}

View File

@ -0,0 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.pojo;
public class Demo4 extends Demo3 {
}

View File

@ -0,0 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.pojo;
public class Demo5 {
}

View File

@ -0,0 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.pojo;
public class Demo6 {
}

View File

@ -0,0 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.pojo;
public class Demo7 {
}

View File

@ -0,0 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.pojo;
public class Demo8 {
}

View File

@ -0,0 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.pojo;
public class DemoException1 extends Exception{
}

View File

@ -0,0 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.pojo;
public class DemoException2 extends Exception {
}

View File

@ -0,0 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.pojo;
public class DemoException3 extends DemoException2 {
}

View File

@ -0,0 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.pojo;
public class Simple {
}

View File

@ -0,0 +1,52 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.service;
import com.pojo.Demo1;
import com.pojo.Demo2;
import com.pojo.Demo4;
import com.pojo.Demo5;
import com.pojo.Demo6;
import com.pojo.Demo7;
import com.pojo.Demo8;
import com.pojo.DemoException1;
import com.pojo.DemoException3;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
public interface DemoService1<T extends Demo8> {
Demo1 getDemo1();
void setDemo2(Demo2 demo2);
List<Demo4> getDemo4s();
List<HashSet<LinkedList<Set<Vector<Map<? extends Demo5, ? super Demo6>>>>>> getDemo5s();
List<Demo7>[] getDemo7s();
List<T> getTs();
void echo1() throws DemoException1;
void echo2() throws DemoException3;
}

View File

@ -0,0 +1,20 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.service;
public interface DemoService2 extends DemoService1 {
}

View File

@ -0,0 +1,128 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.utils;
import org.apache.dubbo.rpc.model.FrameworkModel;
import com.service.DemoService1;
import com.service.DemoService2;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
public class SerializeSecurityManagerTest {
@Test
public void test() {
SerializeSecurityManager ssm = new SerializeSecurityManager(FrameworkModel.defaultModel());
ssm.registerListener(new TestAllowClassNotifyListener());
Assertions.assertTrue(ssm.getAllowedPrefix().contains("java.util.HashMap"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.example.DemoInterface"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.sun.Interface1"));
Assertions.assertFalse(ssm.getAllowedPrefix().contains("com.sun.Interface2"));
Assertions.assertEquals(ssm.getAllowedPrefix(), TestAllowClassNotifyListener.getPrefixList());
}
@Test
public void addToAllow() {
SerializeSecurityManager ssm = new SerializeSecurityManager(FrameworkModel.defaultModel());
ssm.registerListener(new TestAllowClassNotifyListener());
Assertions.assertFalse(ssm.getAllowedPrefix().contains("com.sun.Interface2"));
Assertions.assertEquals(ssm.getAllowedPrefix(), TestAllowClassNotifyListener.getPrefixList());
ssm.addToAllow("com.sun.Interface2");
Assertions.assertFalse(ssm.getAllowedPrefix().contains("com.sun.Interface2"));
Assertions.assertEquals(ssm.getAllowedPrefix(), TestAllowClassNotifyListener.getPrefixList());
ssm.addToAllow("java.util.Interface1");
Assertions.assertTrue(ssm.getAllowedPrefix().contains("java.util.Interface1"));
Assertions.assertEquals(ssm.getAllowedPrefix(), TestAllowClassNotifyListener.getPrefixList());
ssm.addToAllow("java.util.package.Interface1");
Assertions.assertTrue(ssm.getAllowedPrefix().contains("java.util.package.Interface1"));
Assertions.assertEquals(ssm.getAllowedPrefix(), TestAllowClassNotifyListener.getPrefixList());
ssm.addToAllow("com.example.Interface2");
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.example.Interface2"));
Assertions.assertEquals(ssm.getAllowedPrefix(), TestAllowClassNotifyListener.getPrefixList());
ssm.addToAllow("com.example.package.Interface1");
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.example.package"));
Assertions.assertEquals(ssm.getAllowedPrefix(), TestAllowClassNotifyListener.getPrefixList());
}
@Test
public void testRegister1() {
SerializeSecurityManager ssm = new SerializeSecurityManager(FrameworkModel.defaultModel());
ssm.registerListener(new TestAllowClassNotifyListener());
ssm.registerInterface(DemoService1.class);
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.service.DemoService1"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo1"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo2"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo3"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo4"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo5"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo6"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo7"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo8"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Simple"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains(List.class.getName()));
Assertions.assertTrue(ssm.getAllowedPrefix().contains(Set.class.getName()));
Assertions.assertTrue(ssm.getAllowedPrefix().contains(Map.class.getName()));
Assertions.assertTrue(ssm.getAllowedPrefix().contains(LinkedList.class.getName()));
Assertions.assertTrue(ssm.getAllowedPrefix().contains(Vector.class.getName()));
Assertions.assertTrue(ssm.getAllowedPrefix().contains(HashSet.class.getName()));
Assertions.assertEquals(ssm.getAllowedPrefix(), TestAllowClassNotifyListener.getPrefixList());
}
@Test
public void testRegister2() {
SerializeSecurityManager ssm = new SerializeSecurityManager(FrameworkModel.defaultModel());
ssm.registerListener(new TestAllowClassNotifyListener());
ssm.registerInterface(DemoService2.class);
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.service.DemoService2"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo1"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo2"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo3"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo4"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo5"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo6"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo7"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo8"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Simple"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains(List.class.getName()));
Assertions.assertTrue(ssm.getAllowedPrefix().contains(Set.class.getName()));
Assertions.assertTrue(ssm.getAllowedPrefix().contains(Map.class.getName()));
Assertions.assertTrue(ssm.getAllowedPrefix().contains(LinkedList.class.getName()));
Assertions.assertTrue(ssm.getAllowedPrefix().contains(Vector.class.getName()));
Assertions.assertTrue(ssm.getAllowedPrefix().contains(HashSet.class.getName()));
Assertions.assertEquals(ssm.getAllowedPrefix(), TestAllowClassNotifyListener.getPrefixList());
}
}

View File

@ -0,0 +1,33 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.utils;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
public class TestAllowClassNotifyListener implements AllowClassNotifyListener {
private final static AtomicReference<Set<String>> prefixList = new AtomicReference<>();
@Override
public void notify(SerializeCheckStatus status, Set<String> prefixList) {
TestAllowClassNotifyListener.prefixList.set(prefixList);
}
public static Set<String> getPrefixList() {
return prefixList.get();
}
}

View File

@ -0,0 +1,20 @@
#
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
com.example.DemoInterface
com.sun.Interface1

View File

@ -1038,6 +1038,7 @@ class ReferenceConfigTest {
@Test
@DisabledForJreRange(min = JRE.JAVA_16)
public void testDifferentClassLoaderRequest() throws Exception {
FrameworkModel frameworkModel = FrameworkModel.defaultModel();
String basePath = DemoService.class.getProtectionDomain().getCodeSource().getLocation().getFile();
basePath = java.net.URLDecoder.decode(basePath, "UTF-8");
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
@ -1046,7 +1047,7 @@ class ReferenceConfigTest {
TestClassLoader2 classLoader3 = new TestClassLoader2(classLoader2, basePath);
ApplicationConfig applicationConfig = new ApplicationConfig("TestApp");
ApplicationModel applicationModel = new ApplicationModel(FrameworkModel.defaultModel());
ApplicationModel applicationModel = new ApplicationModel(frameworkModel);
applicationModel.getApplicationConfigManager().setApplication(applicationConfig);
ModuleModel moduleModel = new ModuleModel(applicationModel);

View File

@ -0,0 +1,19 @@
#
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
demo.

View File

@ -887,4 +887,5 @@
</build>
</profile>
</profiles>
</project>

View File

@ -657,12 +657,6 @@
META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization
</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>
META-INF/dubbo/internal/org.apache.dubbo.common.serialize.hessian2.dubbo.Hessian2FactoryInitializer
</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>

View File

@ -274,12 +274,6 @@
META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization
</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>
META-INF/dubbo/internal/org.apache.dubbo.common.serialize.hessian2.dubbo.Hessian2FactoryInitializer
</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>

View File

@ -1065,19 +1065,6 @@
}
]
},
{
"name": "org.apache.dubbo.common.serialize.hessian2.dubbo.DefaultHessian2FactoryInitializer",
"allPublicMethods": true,
"methods": [
{
"name": "<init>",
"parameterTypes": []
}
]
},
{
"name": "org.apache.dubbo.common.serialize.hessian2.dubbo.WhitelistHessian2FactoryInitializer"
},
{
"name": "org.apache.dubbo.common.status.reporter.FrameworkStatusReportService",
"methods": [

View File

@ -28,9 +28,6 @@
{
"pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization\\E"
},
{
"pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.serialize.hessian2.dubbo.Hessian2FactoryInitializer\\E"
},
{
"pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.threadpool.ThreadPool\\E"
},

View File

@ -0,0 +1,91 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.rpc.protocol;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.common.utils.SerializeSecurityManager;
import org.apache.dubbo.rpc.Exporter;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Protocol;
import org.apache.dubbo.rpc.ProtocolServer;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.model.ScopeModel;
import org.apache.dubbo.rpc.model.ScopeModelUtil;
import org.apache.dubbo.rpc.model.ServiceDescriptor;
import org.apache.dubbo.rpc.model.ServiceModel;
import java.util.List;
import java.util.Optional;
@Activate(order = 200)
public class ProtocolSecurityWrapper implements Protocol {
private final Protocol protocol;
public ProtocolSecurityWrapper(Protocol protocol) {
if (protocol == null) {
throw new IllegalArgumentException("protocol == null");
}
this.protocol = protocol;
}
@Override
public int getDefaultPort() {
return protocol.getDefaultPort();
}
@Override
public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
ServiceModel serviceModel = invoker.getUrl().getServiceModel();
ScopeModel scopeModel = invoker.getUrl().getScopeModel();
Optional.ofNullable(serviceModel)
.map(ServiceModel::getServiceModel)
.map(ServiceDescriptor::getServiceInterfaceClass)
.ifPresent((interfaceClass) -> {
SerializeSecurityManager serializeSecurityManager = ScopeModelUtil.getFrameworkModel(scopeModel)
.getBeanFactory().getBean(SerializeSecurityManager.class);
serializeSecurityManager.registerInterface(interfaceClass);
});
return protocol.export(invoker);
}
@Override
public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
ServiceModel serviceModel = url.getServiceModel();
ScopeModel scopeModel = url.getScopeModel();
SerializeSecurityManager serializeSecurityManager = ScopeModelUtil.getFrameworkModel(scopeModel)
.getBeanFactory().getBean(SerializeSecurityManager.class);
Optional.ofNullable(serviceModel)
.map(ServiceModel::getServiceModel)
.map(ServiceDescriptor::getServiceInterfaceClass)
.ifPresent(serializeSecurityManager::registerInterface);
serializeSecurityManager.registerInterface(type);
return protocol.refer(type, url);
}
@Override
public void destroy() {
protocol.destroy();
}
@Override
public List<ProtocolServer> getServers() {
return protocol.getServers();
}
}

View File

@ -1,3 +1,4 @@
listener=org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper
mock=org.apache.dubbo.rpc.support.MockProtocol
serializationwrapper=org.apache.dubbo.rpc.protocol.ProtocolSerializationWrapper
securitywrapper=org.apache.dubbo.rpc.protocol.ProtocolSecurityWrapper

View File

@ -32,11 +32,15 @@ public class FastJson2ObjectInput implements ObjectInput {
private final Fastjson2CreatorManager fastjson2CreatorManager;
private final Fastjson2SecurityManager fastjson2SecurityManager;
private volatile ClassLoader classLoader;
private final InputStream is;
public FastJson2ObjectInput(Fastjson2CreatorManager fastjson2CreatorManager, InputStream in) {
public FastJson2ObjectInput(Fastjson2CreatorManager fastjson2CreatorManager,
Fastjson2SecurityManager fastjson2SecurityManager, InputStream in) {
this.fastjson2CreatorManager = fastjson2CreatorManager;
this.fastjson2SecurityManager = fastjson2SecurityManager;
this.classLoader = Thread.currentThread().getContextClassLoader();
this.is = in;
fastjson2CreatorManager.setCreator(classLoader);
@ -107,8 +111,9 @@ public class FastJson2ObjectInput implements ObjectInput {
if (read != length) {
throw new IllegalArgumentException("deserialize failed. expected read length: " + length + " but actual read: " + read);
}
return (T) JSONB.parseObject(bytes, Object.class, JSONReader.Feature.SupportAutoType,
return (T) JSONB.parseObject(bytes, Object.class, fastjson2SecurityManager.getSecurityFilter(),
JSONReader.Feature.UseDefaultConstructorAsPossible,
JSONReader.Feature.ErrorOnNoneSerializable,
JSONReader.Feature.UseNativeObject,
JSONReader.Feature.FieldBased);
}
@ -123,8 +128,9 @@ public class FastJson2ObjectInput implements ObjectInput {
if (read != length) {
throw new IllegalArgumentException("deserialize failed. expected read length: " + length + " but actual read: " + read);
}
return (T) JSONB.parseObject(bytes, Object.class, JSONReader.Feature.SupportAutoType,
return (T) JSONB.parseObject(bytes, Object.class, fastjson2SecurityManager.getSecurityFilter(),
JSONReader.Feature.UseDefaultConstructorAsPossible,
JSONReader.Feature.ErrorOnNoneSerializable,
JSONReader.Feature.UseNativeObject,
JSONReader.Feature.FieldBased);
}

View File

@ -98,6 +98,7 @@ public class FastJson2ObjectOutput implements ObjectOutput {
updateClassLoaderIfNeed();
byte[] bytes = JSONB.toBytes(obj, JSONWriter.Feature.WriteClassName,
JSONWriter.Feature.FieldBased,
JSONWriter.Feature.ErrorOnNoneSerializable,
JSONWriter.Feature.ReferenceDetection,
JSONWriter.Feature.WriteNulls,
JSONWriter.Feature.NotWriteDefaultValue,

View File

@ -39,8 +39,11 @@ public class FastJson2Serialization implements Serialization {
private final Fastjson2CreatorManager fastjson2CreatorManager;
private final Fastjson2SecurityManager fastjson2SecurityManager;
public FastJson2Serialization(FrameworkModel frameworkModel) {
this.fastjson2CreatorManager = frameworkModel.getBeanFactory().getBean(Fastjson2CreatorManager.class);
this.fastjson2SecurityManager = frameworkModel.getBeanFactory().getBean(Fastjson2SecurityManager.class);
}
@Override
@ -60,7 +63,7 @@ public class FastJson2Serialization implements Serialization {
@Override
public ObjectInput deserialize(URL url, InputStream input) throws IOException {
return new FastJson2ObjectInput(fastjson2CreatorManager, input);
return new FastJson2ObjectInput(fastjson2CreatorManager, fastjson2SecurityManager, input);
}
}

View File

@ -23,10 +23,12 @@ import org.apache.dubbo.rpc.model.ModuleModel;
import org.apache.dubbo.rpc.model.ScopeModelInitializer;
public class Fastjson2ScopeModelInitializer implements ScopeModelInitializer {
@Override
public void initializeFrameworkModel(FrameworkModel frameworkModel) {
ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
beanFactory.registerBean(Fastjson2CreatorManager.class);
beanFactory.registerBean(Fastjson2SecurityManager.class);
}
@Override

View File

@ -0,0 +1,114 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.serialize.fastjson2;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.AllowClassNotifyListener;
import org.apache.dubbo.common.utils.ConcurrentHashSet;
import org.apache.dubbo.common.utils.SerializeCheckStatus;
import org.apache.dubbo.common.utils.SerializeSecurityManager;
import org.apache.dubbo.rpc.model.FrameworkModel;
import com.alibaba.fastjson2.filter.ContextAutoTypeBeforeHandler;
import com.alibaba.fastjson2.filter.Filter;
import com.alibaba.fastjson2.util.TypeUtils;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import static com.alibaba.fastjson2.util.TypeUtils.loadClass;
public class Fastjson2SecurityManager implements AllowClassNotifyListener {
private Filter securityFilter = new Handler(AllowClassNotifyListener.DEFAULT_STATUS, new String[0]);
private final static Logger logger = LoggerFactory.getLogger(Fastjson2SecurityManager.class);
private final static Set<String> warnedClasses = new ConcurrentHashSet<>(1);
public Fastjson2SecurityManager(FrameworkModel frameworkModel) {
SerializeSecurityManager securityManager = frameworkModel.getBeanFactory().getOrRegisterBean(SerializeSecurityManager.class);
securityManager.registerListener(this);
}
public void notify(SerializeCheckStatus status, Set<String> prefixList) {
this.securityFilter = new Handler(status, prefixList.toArray(new String[0]));
}
public Filter getSecurityFilter() {
return securityFilter;
}
public static class Handler extends ContextAutoTypeBeforeHandler {
final SerializeCheckStatus status;
final Map<String, Class<?>> classCache = new ConcurrentHashMap<>(16, 0.75f, 1);
public Handler(SerializeCheckStatus status, String[] acceptNames) {
super(true, acceptNames);
this.status = status;
}
@Override
public Class<?> apply(String typeName, Class<?> expectClass, long features) {
switch (status) {
case STRICT:
return super.apply(typeName, expectClass, features);
case WARN:
Class<?> tryLoad = super.apply(typeName, expectClass, features);
if (tryLoad != null) {
return tryLoad;
}
case DISABLED:
Class<?> localClass = loadClassDirectly(typeName);
if (localClass != null) {
if (status == SerializeCheckStatus.WARN && warnedClasses.add(typeName)) {
logger.error("[Serialization Security] Serialized class " + localClass.getName() + " is not in allow list. " +
"Current mode is `WARN`, will allow to deserialize it by default. " +
"Dubbo will set to `STRICT` mode by default in the future. " +
"Please add it into security/serialize.allowlist or follow FAQ to configure it.");
}
return localClass;
}
default:
return null;
}
}
public Class<?> loadClassDirectly(String typeName) {
Class<?> clazz = classCache.get(typeName);
if (clazz == null) {
clazz = TypeUtils.getMapping(typeName);
}
if (clazz == null) {
clazz = loadClass(typeName);
}
if (clazz != null) {
Class<?> origin = classCache.putIfAbsent(typeName, clazz);
if (origin != null) {
clazz = origin;
}
}
return clazz;
}
}
}

View File

@ -0,0 +1,117 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.serialize.hessian2;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.AllowClassNotifyListener;
import org.apache.dubbo.common.utils.ConcurrentHashSet;
import org.apache.dubbo.common.utils.SerializeCheckStatus;
import org.apache.dubbo.common.utils.SerializeSecurityManager;
import org.apache.dubbo.rpc.model.FrameworkModel;
import java.util.Arrays;
import java.util.Set;
/**
* Inspired by Fastjson2
* see com.alibaba.fastjson2.filter.ContextAutoTypeBeforeHandler#apply(java.lang.String, java.lang.Class, long)
*/
public class Hessian2AllowClassManager implements AllowClassNotifyListener {
private static final long MAGIC_HASH_CODE = 0xcbf29ce484222325L;
private static final long MAGIC_PRIME = 0x100000001b3L;
private static final Logger logger = LoggerFactory.getLogger(Hessian2AllowClassManager.class);
private volatile SerializeCheckStatus checkStatus = AllowClassNotifyListener.DEFAULT_STATUS;
private final static Set<String> warnedClasses = new ConcurrentHashSet<>(1);
private volatile long[] allowPrefixes = new long[0];
public Hessian2AllowClassManager(FrameworkModel frameworkModel) {
SerializeSecurityManager serializeSecurityManager = frameworkModel.getBeanFactory().getOrRegisterBean(SerializeSecurityManager.class);
serializeSecurityManager.registerListener(this);
}
@Override
public void notify(SerializeCheckStatus status, Set<String> prefixList) {
this.checkStatus = status;
long[] array = new long[prefixList.size()];
int index = 0;
for (String name : prefixList) {
if (name == null || name.isEmpty()) {
continue;
}
long hashCode = MAGIC_HASH_CODE;
for (int j = 0; j < name.length(); ++j) {
char ch = name.charAt(j);
if (ch == '$') {
ch = '.';
}
hashCode ^= ch;
hashCode *= MAGIC_PRIME;
}
array[index++] = hashCode;
}
if (index != array.length) {
array = Arrays.copyOf(array, index);
}
Arrays.sort(array);
this.allowPrefixes = array;
}
public Class<?> loadClass(ClassLoader classLoader, String className) throws ClassNotFoundException {
if (checkStatus == SerializeCheckStatus.DISABLED) {
return Class.forName(className, false, classLoader);
}
long hash = MAGIC_HASH_CODE;
for (int i = 0, typeNameLength = className.length(); i < typeNameLength; ++i) {
char ch = className.charAt(i);
if (ch == '$') {
ch = '.';
}
hash ^= ch;
hash *= MAGIC_PRIME;
if (Arrays.binarySearch(allowPrefixes, hash) >= 0) {
return Class.forName(className, false, classLoader);
}
}
if (checkStatus == SerializeCheckStatus.STRICT) {
String msg = "[Serialization Security] Serialized class " + className + " is not in allow list. " +
"Current mode is `STRICT`, will disallow to deserialize it by default. " +
"Please add it into security/serialize.allowlist or follow FAQ to configure it.";
if (warnedClasses.add(className)) {
logger.error(msg);
}
throw new IllegalArgumentException(msg);
} else {
Class<?> clazz = Class.forName(className, false, classLoader);
if (warnedClasses.add(className)) {
logger.error("[Serialization Security] Serialized class " + clazz.getName() + " is not in allow list. " +
"Current mode is `WARN`, will allow to deserialize it by default. " +
"Dubbo will set to `STRICT` mode by default in the future. " +
"Please add it into security/serialize.allowlist or follow FAQ to configure it.");
}
return clazz;
}
}
}

View File

@ -14,18 +14,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.serialize.hessian2.dubbo;
package org.apache.dubbo.common.serialize.hessian2;
import org.apache.dubbo.common.serialize.hessian2.Hessian2SerializerFactory;
import org.apache.dubbo.rpc.model.FrameworkModel;
import org.apache.dubbo.rpc.model.ScopeClassLoaderListener;
import com.alibaba.com.caucho.hessian.io.SerializerFactory;
public class DefaultHessian2FactoryInitializer extends AbstractHessian2FactoryInitializer {
public class Hessian2ClassLoaderListener implements ScopeClassLoaderListener<FrameworkModel> {
@Override
protected SerializerFactory createSerializerFactory() {
Hessian2SerializerFactory hessian2SerializerFactory = new Hessian2SerializerFactory();
hessian2SerializerFactory.setAllowNonSerializable(Boolean.parseBoolean(System.getProperty("dubbo.hessian.allowNonSerializable", "false")));
hessian2SerializerFactory.getClassFactory().allow("org.apache.dubbo.*");
return hessian2SerializerFactory;
public void onAddClassLoader(FrameworkModel scopeModel, ClassLoader classLoader) {
// noop
}
@Override
public void onRemoveClassLoader(FrameworkModel scopeModel, ClassLoader classLoader) {
Hessian2FactoryManager hessian2FactoryManager = scopeModel.getBeanFactory().getBean(Hessian2FactoryManager.class);
hessian2FactoryManager.onRemoveClassLoader(classLoader);
}
}

View File

@ -0,0 +1,110 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.serialize.hessian2;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.model.FrameworkModel;
import com.alibaba.com.caucho.hessian.io.SerializerFactory;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class Hessian2FactoryManager {
String WHITELIST = "dubbo.application.hessian2.whitelist";
String ALLOW = "dubbo.application.hessian2.allow";
String DENY = "dubbo.application.hessian2.deny";
private volatile SerializerFactory SYSTEM_SERIALIZER_FACTORY;
private final Map<ClassLoader, SerializerFactory> CL_2_SERIALIZER_FACTORY = new ConcurrentHashMap<>();
private final Hessian2AllowClassManager hessian2AllowClassManager;
public Hessian2FactoryManager(FrameworkModel frameworkModel) {
hessian2AllowClassManager = new Hessian2AllowClassManager(frameworkModel);
}
public SerializerFactory getSerializerFactory(ClassLoader classLoader) {
if (classLoader == null) {
// system classloader
if (SYSTEM_SERIALIZER_FACTORY == null) {
synchronized (this) {
if (SYSTEM_SERIALIZER_FACTORY == null) {
SYSTEM_SERIALIZER_FACTORY = createSerializerFactory();
}
}
}
return SYSTEM_SERIALIZER_FACTORY;
}
if (!CL_2_SERIALIZER_FACTORY.containsKey(classLoader)) {
synchronized (this) {
if (!CL_2_SERIALIZER_FACTORY.containsKey(classLoader)) {
SerializerFactory serializerFactory = createSerializerFactory();
CL_2_SERIALIZER_FACTORY.put(classLoader, serializerFactory);
return serializerFactory;
}
}
}
return CL_2_SERIALIZER_FACTORY.get(classLoader);
}
private SerializerFactory createSerializerFactory() {
String whitelist = System.getProperty(WHITELIST);
if (StringUtils.isNotEmpty(whitelist)) {
return createWhiteListSerializerFactory();
}
return createDefaultSerializerFactory();
}
private SerializerFactory createDefaultSerializerFactory() {
Hessian2SerializerFactory hessian2SerializerFactory = new Hessian2SerializerFactory(hessian2AllowClassManager);
hessian2SerializerFactory.setAllowNonSerializable(Boolean.parseBoolean(System.getProperty("dubbo.hessian.allowNonSerializable", "false")));
hessian2SerializerFactory.getClassFactory().allow("org.apache.dubbo.*");
return hessian2SerializerFactory;
}
public SerializerFactory createWhiteListSerializerFactory() {
SerializerFactory serializerFactory = new Hessian2SerializerFactory(hessian2AllowClassManager);
String whiteList = System.getProperty(WHITELIST);
if ("true".equals(whiteList)) {
serializerFactory.getClassFactory().setWhitelist(true);
String allowPattern = System.getProperty(ALLOW);
if (StringUtils.isNotEmpty(allowPattern)) {
for (String pattern : allowPattern.split(";")) {
serializerFactory.getClassFactory().allow(pattern);
}
}
} else {
serializerFactory.getClassFactory().setWhitelist(false);
String denyPattern = System.getProperty(DENY);
if (StringUtils.isNotEmpty(denyPattern)) {
for (String pattern : denyPattern.split(";")) {
serializerFactory.getClassFactory().deny(pattern);
}
}
}
serializerFactory.setAllowNonSerializable(Boolean.parseBoolean(System.getProperty("dubbo.hessian.allowNonSerializable", "false")));
serializerFactory.getClassFactory().allow("org.apache.dubbo.*");
return serializerFactory;
}
public void onRemoveClassLoader(ClassLoader classLoader) {
CL_2_SERIALIZER_FACTORY.remove(classLoader);
}
}

View File

@ -18,7 +18,7 @@ package org.apache.dubbo.common.serialize.hessian2;
import org.apache.dubbo.common.serialize.Cleanable;
import org.apache.dubbo.common.serialize.ObjectInput;
import org.apache.dubbo.common.serialize.hessian2.dubbo.Hessian2FactoryInitializer;
import org.apache.dubbo.rpc.model.FrameworkModel;
import com.alibaba.com.caucho.hessian.io.Hessian2Input;
@ -31,12 +31,19 @@ import java.lang.reflect.Type;
*/
public class Hessian2ObjectInput implements ObjectInput, Cleanable {
private final Hessian2Input mH2i;
private final Hessian2FactoryInitializer hessian2FactoryInitializer;
private final Hessian2FactoryManager hessian2FactoryManager;
@Deprecated
public Hessian2ObjectInput(InputStream is) {
mH2i = new Hessian2Input(is);
hessian2FactoryInitializer = Hessian2FactoryInitializer.getInstance();
mH2i.setSerializerFactory(hessian2FactoryInitializer.getSerializerFactory());
this.hessian2FactoryManager = FrameworkModel.defaultModel().getBeanFactory().getOrRegisterBean(Hessian2FactoryManager.class);
mH2i.setSerializerFactory(hessian2FactoryManager.getSerializerFactory(Thread.currentThread().getContextClassLoader()));
}
public Hessian2ObjectInput(InputStream is, Hessian2FactoryManager hessian2FactoryManager) {
mH2i = new Hessian2Input(is);
this.hessian2FactoryManager = hessian2FactoryManager;
mH2i.setSerializerFactory(hessian2FactoryManager.getSerializerFactory(Thread.currentThread().getContextClassLoader()));
}
@Override
@ -87,7 +94,7 @@ public class Hessian2ObjectInput implements ObjectInput, Cleanable {
@Override
public Object readObject() throws IOException {
if (!mH2i.getSerializerFactory().getClassLoader().equals(Thread.currentThread().getContextClassLoader())) {
mH2i.setSerializerFactory(hessian2FactoryInitializer.getSerializerFactory());
mH2i.setSerializerFactory(hessian2FactoryManager.getSerializerFactory(Thread.currentThread().getContextClassLoader()));
}
return mH2i.readObject();
}
@ -97,7 +104,7 @@ public class Hessian2ObjectInput implements ObjectInput, Cleanable {
public <T> T readObject(Class<T> cls) throws IOException,
ClassNotFoundException {
if (!mH2i.getSerializerFactory().getClassLoader().equals(Thread.currentThread().getContextClassLoader())) {
mH2i.setSerializerFactory(hessian2FactoryInitializer.getSerializerFactory());
mH2i.setSerializerFactory(hessian2FactoryManager.getSerializerFactory(Thread.currentThread().getContextClassLoader()));
}
return (T) mH2i.readObject(cls);
}
@ -105,7 +112,7 @@ public class Hessian2ObjectInput implements ObjectInput, Cleanable {
@Override
public <T> T readObject(Class<T> cls, Type type) throws IOException, ClassNotFoundException {
if (!mH2i.getSerializerFactory().getClassLoader().equals(Thread.currentThread().getContextClassLoader())) {
mH2i.setSerializerFactory(hessian2FactoryInitializer.getSerializerFactory());
mH2i.setSerializerFactory(hessian2FactoryManager.getSerializerFactory(Thread.currentThread().getContextClassLoader()));
}
return readObject(cls);
}

View File

@ -18,7 +18,7 @@ package org.apache.dubbo.common.serialize.hessian2;
import org.apache.dubbo.common.serialize.Cleanable;
import org.apache.dubbo.common.serialize.ObjectOutput;
import org.apache.dubbo.common.serialize.hessian2.dubbo.Hessian2FactoryInitializer;
import org.apache.dubbo.rpc.model.FrameworkModel;
import com.alibaba.com.caucho.hessian.io.Hessian2Output;
@ -32,9 +32,16 @@ public class Hessian2ObjectOutput implements ObjectOutput, Cleanable {
private final Hessian2Output mH2o;
@Deprecated
public Hessian2ObjectOutput(OutputStream os) {
mH2o = new Hessian2Output(os);
mH2o.setSerializerFactory(Hessian2FactoryInitializer.getInstance().getSerializerFactory());
Hessian2FactoryManager hessian2FactoryManager = FrameworkModel.defaultModel().getBeanFactory().getOrRegisterBean(Hessian2FactoryManager.class);
mH2o.setSerializerFactory(hessian2FactoryManager.getSerializerFactory(Thread.currentThread().getContextClassLoader()));
}
public Hessian2ObjectOutput(OutputStream os, Hessian2FactoryManager hessian2FactoryManager) {
mH2o = new Hessian2Output(os);
mH2o.setSerializerFactory(hessian2FactoryManager.getSerializerFactory(Thread.currentThread().getContextClassLoader()));
}
@Override

View File

@ -0,0 +1,41 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.serialize.hessian2;
import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.FrameworkModel;
import org.apache.dubbo.rpc.model.ModuleModel;
import org.apache.dubbo.rpc.model.ScopeModelInitializer;
public class Hessian2ScopeModelInitializer implements ScopeModelInitializer {
@Override
public void initializeFrameworkModel(FrameworkModel frameworkModel) {
ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
beanFactory.registerBean(Hessian2FactoryManager.class);
}
@Override
public void initializeApplicationModel(ApplicationModel applicationModel) {
}
@Override
public void initializeModuleModel(ModuleModel moduleModel) {
}
}

View File

@ -20,6 +20,7 @@ import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.serialize.ObjectInput;
import org.apache.dubbo.common.serialize.ObjectOutput;
import org.apache.dubbo.common.serialize.Serialization;
import org.apache.dubbo.rpc.model.FrameworkModel;
import java.io.IOException;
import java.io.InputStream;
@ -36,6 +37,12 @@ import static org.apache.dubbo.common.serialize.Constants.HESSIAN2_SERIALIZATION
*/
public class Hessian2Serialization implements Serialization {
private final Hessian2FactoryManager hessian2FactoryManager;
public Hessian2Serialization(FrameworkModel frameworkModel) {
hessian2FactoryManager = frameworkModel.getBeanFactory().getBean(Hessian2FactoryManager.class);
}
@Override
public byte getContentTypeId() {
return HESSIAN2_SERIALIZATION_ID;
@ -48,12 +55,12 @@ public class Hessian2Serialization implements Serialization {
@Override
public ObjectOutput serialize(URL url, OutputStream out) throws IOException {
return new Hessian2ObjectOutput(out);
return new Hessian2ObjectOutput(out, hessian2FactoryManager);
}
@Override
public ObjectInput deserialize(URL url, InputStream is) throws IOException {
return new Hessian2ObjectInput(is);
return new Hessian2ObjectInput(is, hessian2FactoryManager);
}
}

View File

@ -20,7 +20,14 @@ import com.alibaba.com.caucho.hessian.io.SerializerFactory;
public class Hessian2SerializerFactory extends SerializerFactory {
public Hessian2SerializerFactory() {
private Hessian2AllowClassManager hessian2AllowClassManager;
public Hessian2SerializerFactory(Hessian2AllowClassManager hessian2AllowClassManager) {
this.hessian2AllowClassManager = hessian2AllowClassManager;
}
@Override
public Class<?> loadSerializedClass(String className) throws ClassNotFoundException {
return hessian2AllowClassManager.loadClass(getClassLoader(), className);
}
}

View File

@ -1,56 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.serialize.hessian2.dubbo;
import com.alibaba.com.caucho.hessian.io.SerializerFactory;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public abstract class AbstractHessian2FactoryInitializer implements Hessian2FactoryInitializer {
private static final Map<ClassLoader, SerializerFactory> CL_2_SERIALIZER_FACTORY = new ConcurrentHashMap<>();
private static volatile SerializerFactory SYSTEM_SERIALIZER_FACTORY;
@Override
public SerializerFactory getSerializerFactory() {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (classLoader == null) {
// system classloader
if (SYSTEM_SERIALIZER_FACTORY == null) {
synchronized (AbstractHessian2FactoryInitializer.class) {
if (SYSTEM_SERIALIZER_FACTORY == null) {
SYSTEM_SERIALIZER_FACTORY = createSerializerFactory();
}
}
}
return SYSTEM_SERIALIZER_FACTORY;
}
if (!CL_2_SERIALIZER_FACTORY.containsKey(classLoader)) {
synchronized (AbstractHessian2FactoryInitializer.class) {
if (!CL_2_SERIALIZER_FACTORY.containsKey(classLoader)) {
SerializerFactory serializerFactory = createSerializerFactory();
CL_2_SERIALIZER_FACTORY.put(classLoader, serializerFactory);
return serializerFactory;
}
}
}
return CL_2_SERIALIZER_FACTORY.get(classLoader);
}
protected abstract SerializerFactory createSerializerFactory();
}

View File

@ -1,45 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.serialize.hessian2.dubbo;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.extension.ExtensionScope;
import org.apache.dubbo.common.extension.SPI;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.model.FrameworkModel;
import com.alibaba.com.caucho.hessian.io.SerializerFactory;
@SPI(value = "default", scope = ExtensionScope.FRAMEWORK)
public interface Hessian2FactoryInitializer {
String ALLOW = System.getProperty("dubbo.application.hessian2.allow");
String DENY = System.getProperty("dubbo.application.hessian2.deny");
String WHITELIST = System.getProperty("dubbo.application.hessian2.whitelist");
String ALLOW_NON_SERIALIZABLE = System.getProperty("dubbo.hessian.allowNonSerializable", "false");
SerializerFactory getSerializerFactory();
static Hessian2FactoryInitializer getInstance() {
ExtensionLoader<Hessian2FactoryInitializer> loader = FrameworkModel.defaultModel().getExtensionLoader(Hessian2FactoryInitializer.class);
if (StringUtils.isNotEmpty(WHITELIST)) {
return loader.getExtension("whitelist");
}
return loader.getDefaultExtension();
}
}

View File

@ -1,52 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.serialize.hessian2.dubbo;
import org.apache.dubbo.common.serialize.hessian2.Hessian2SerializerFactory;
import org.apache.dubbo.common.utils.StringUtils;
import com.alibaba.com.caucho.hessian.io.SerializerFactory;
/**
* see https://github.com/ebourg/hessian/commit/cf851f5131707891e723f7f6a9718c2461aed826
*/
public class WhitelistHessian2FactoryInitializer extends AbstractHessian2FactoryInitializer {
@Override
public SerializerFactory createSerializerFactory() {
SerializerFactory serializerFactory = new Hessian2SerializerFactory();
if ("true".equals(WHITELIST)) {
serializerFactory.getClassFactory().setWhitelist(true);
if (StringUtils.isNotEmpty(ALLOW)) {
for (String pattern : ALLOW.split(";")) {
serializerFactory.getClassFactory().allow(pattern);
}
}
} else {
serializerFactory.getClassFactory().setWhitelist(false);
if (StringUtils.isNotEmpty(DENY)) {
for (String pattern : DENY.split(";")) {
serializerFactory.getClassFactory().deny(pattern);
}
}
}
serializerFactory.setAllowNonSerializable(Boolean.parseBoolean(ALLOW_NON_SERIALIZABLE));
serializerFactory.getClassFactory().allow("org.apache.dubbo.*");
return serializerFactory;
}
}

View File

@ -1,2 +0,0 @@
default=org.apache.dubbo.common.serialize.hessian2.dubbo.DefaultHessian2FactoryInitializer
whitelist=org.apache.dubbo.common.serialize.hessian2.dubbo.WhitelistHessian2FactoryInitializer

View File

@ -0,0 +1 @@
hessian2=org.apache.dubbo.common.serialize.hessian2.Hessian2ScopeModelInitializer

View File

@ -834,4 +834,5 @@
</plugins>
</pluginManagement>
</build>
</project>