ARTEMIS-1252 Add service loading of password codec to obtain its implementation from the app's root context
This commit is contained in:
parent
43a7890b1a
commit
1ecbd97cd4
|
@ -20,6 +20,7 @@ import java.security.AccessController;
|
|||
import java.security.PrivilegedAction;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
import org.apache.activemq.artemis.api.core.ActiveMQException;
|
||||
import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
|
||||
|
@ -108,22 +109,33 @@ public final class PasswordMaskingUtil {
|
|||
|
||||
// semi colons
|
||||
String[] parts = codecDesc.split(";");
|
||||
|
||||
if (parts.length < 1)
|
||||
throw new ActiveMQException(ActiveMQExceptionType.ILLEGAL_STATE, "Invalid PasswordCodec value: " + codecDesc);
|
||||
|
||||
final String codecClassName = parts[0];
|
||||
|
||||
// load class
|
||||
codecInstance = AccessController.doPrivileged(new PrivilegedAction<SensitiveDataCodec<String>>() {
|
||||
@Override
|
||||
public SensitiveDataCodec<String> run() {
|
||||
ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
||||
codecInstance = AccessController.doPrivileged((PrivilegedAction<SensitiveDataCodec<String>>) () -> {
|
||||
ServiceLoader<SensitiveDataCodec> serviceLoader = ServiceLoader.load(SensitiveDataCodec.class, PasswordMaskingUtil.class.getClassLoader());
|
||||
try {
|
||||
Class<?> clazz = loader.loadClass(codecClassName);
|
||||
return (SensitiveDataCodec<String>) clazz.newInstance();
|
||||
// Service load the codec, if a service is available
|
||||
for (SensitiveDataCodec<String> codec : serviceLoader) {
|
||||
if ((codec.getClass().getCanonicalName()).equals(codecClassName)) {
|
||||
return codec.getClass().newInstance();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw ActiveMQUtilBundle.BUNDLE.errorCreatingCodec(e, codecClassName);
|
||||
// Will ignore the exception and attempt to load the class directly
|
||||
}
|
||||
try {
|
||||
// If a service is not available, load the codec class using this class's class loader
|
||||
return (SensitiveDataCodec<String>) PasswordMaskingUtil.class.getClassLoader().loadClass(codecClassName).newInstance();
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
// As a last resort, load the codec class using the current thread's context class loader
|
||||
return (SensitiveDataCodec<String>) Thread.currentThread().getContextClassLoader().loadClass(codecClassName).newInstance();
|
||||
} catch (Exception e2) {
|
||||
throw ActiveMQUtilBundle.BUNDLE.errorCreatingCodec(e2, codecClassName);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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.activemq.artemis.utils;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class PasswordMaskingUtilTest {
|
||||
|
||||
@Test
|
||||
public void testGetCodecUsingServiceLoader() throws Exception {
|
||||
SensitiveDataCodec<String> codec = PasswordMaskingUtil.getCodec(PasswordMaskingUtil.getDefaultCodec().getClass().getCanonicalName());
|
||||
assertTrue(codec instanceof DefaultSensitiveStringCodec);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testGetCodecUsingInvalidCodec() throws Exception {
|
||||
PasswordMaskingUtil.getCodec("codec doesn't exist");
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
org.apache.activemq.artemis.utils.DefaultSensitiveStringCodec
|
|
@ -464,11 +464,12 @@ If you don't want to use the jar-with-dependencies, make sure the classpath is c
|
|||
|
||||
Just copy "80cf731af62c290" and replace your plaintext password with it.
|
||||
|
||||
#### Using a different decoder
|
||||
#### Using a custom decoder
|
||||
|
||||
It is possible to use a different decoder rather than the built-in one.
|
||||
Simply make sure the decoder is in Apache ActiveMQ Artemis's classpath and configure
|
||||
the server to use it as follows:
|
||||
It is possible to use a custom decoder rather than the built-in one.
|
||||
Simply make sure the decoder is in Apache ActiveMQ Artemis's classpath. The custom decoder
|
||||
can also be service loaded rather than class loaded, if the decoder's service provider is installed in the classpath.
|
||||
Then configure the server to use it as follows:
|
||||
|
||||
```xml
|
||||
<password-codec>com.foo.SomeDecoder;key1=value1;key2=value2</password-codec>
|
||||
|
|
Loading…
Reference in New Issue