Adding support for encrypted passwords when using the LDAPLoginModule
This commit is contained in:
Christopher L. Shannon (cshannon) 2015-09-18 16:40:38 +00:00
parent 5107262998
commit 38a6bedf92
3 changed files with 117 additions and 3 deletions

View File

@ -0,0 +1,70 @@
/**
* 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.jaas;
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig;
import org.jasypt.properties.EncryptableProperties;
/**
* LDAPLoginModule that supports encryption
*/
public class EncryptableLDAPLoginModule extends LDAPLoginModule {
private static final String ENCRYPTION_PASSWORD = "encryptionPassword";
private static final String PASSWORD_ENV_NAME = "passwordEnvName";
private static final String PASSWORD_ALGORITHM = "encryptionAlgorithm";
private static final String DEFAULT_PASSWORD_ENV_NAME = "ACTIVEMQ_ENCRYPTION_PASSWORD";
private static final String DEFAULT_PASSWORD_ALGORITHM = "PBEWithMD5AndDES";
private final StandardPBEStringEncryptor configurationEncryptor = new StandardPBEStringEncryptor();
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
String encryptionPassword = (String)options.get(ENCRYPTION_PASSWORD);
String passwordEnvName = options.get(PASSWORD_ENV_NAME) != null ?
(String)options.get(PASSWORD_ENV_NAME) : DEFAULT_PASSWORD_ENV_NAME;
String passwordAlgorithm = options.get(PASSWORD_ALGORITHM) != null ?
(String)options.get(PASSWORD_ALGORITHM) : DEFAULT_PASSWORD_ALGORITHM;
EnvironmentStringPBEConfig envConfig = new EnvironmentStringPBEConfig();
envConfig.setAlgorithm(passwordAlgorithm);
//If the password was set, use it
//else look up the password from the environment
if (encryptionPassword == null) {
envConfig.setPasswordEnvName(passwordEnvName);
} else {
envConfig.setPassword(encryptionPassword);
}
configurationEncryptor.setConfig(envConfig);
EncryptableProperties encryptableOptions
= new EncryptableProperties(configurationEncryptor);
encryptableOptions.putAll(options);
super.initialize(subject, callbackHandler, sharedState, encryptableOptions);
}
}

View File

@ -36,6 +36,7 @@ import javax.naming.directory.InitialDirContext;
import javax.security.auth.callback.*;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import java.io.IOException;
import java.net.URL;
import java.util.HashSet;
@ -51,12 +52,12 @@ import static org.junit.Assert.fail;
"test.ldif"
)
public class LDAPLoginModuleTest extends AbstractLdapTestUnit {
private static final String BASE = "o=ActiveMQ,ou=system";
public static LdapServer ldapServer;
private static final String FILTER = "(objectclass=*)";
private static final String PRINCIPAL = "uid=admin,ou=system";
private static final String CREDENTIALS = "secret";
@ -103,10 +104,32 @@ public class LDAPLoginModuleTest extends AbstractLdapTestUnit {
assertTrue(set.contains("prefNodeName=sysPrefRoot"));
}
@Test
public void testLogin() throws LoginException {
LoginContext context = new LoginContext("LDAPLogin", new CallbackHandler() {
@Override
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
if (callbacks[i] instanceof NameCallback) {
((NameCallback) callbacks[i]).setName("first");
} else if (callbacks[i] instanceof PasswordCallback) {
((PasswordCallback) callbacks[i]).setPassword("secret".toCharArray());
} else {
throw new UnsupportedCallbackException(callbacks[i]);
}
}
}
});
context.login();
context.logout();
}
@Test
public void testEncryptedLogin() throws LoginException {
LoginContext context = new LoginContext("EncryptedLDAPLogin", new CallbackHandler() {
@Override
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
if (callbacks[i] instanceof NameCallback) {
@ -126,6 +149,7 @@ public class LDAPLoginModuleTest extends AbstractLdapTestUnit {
@Test
public void testUnauthenticated() throws LoginException {
LoginContext context = new LoginContext("UnAuthenticatedLDAPLogin", new CallbackHandler() {
@Override
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
if (callbacks[i] instanceof NameCallback) {

View File

@ -40,6 +40,26 @@ LDAPLogin {
;
};
EncryptedLDAPLogin {
org.apache.activemq.jaas.EncryptableLDAPLoginModule required
debug=true
initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory
connectionURL="ldap://localhost:1024"
connectionUsername="uid=admin,ou=system"
connectionPassword="ENC(dZSxRJoRDuI58eYkWIuH4Q==)"
connectionProtocol=s
authentication=simple
userBase="ou=system"
userSearchMatching="(uid={0})"
userSearchSubtree=false
roleBase="ou=system"
roleName=dummyRoleName
roleSearchMatching="(uid={1})"
roleSearchSubtree=false
encryptionPassword="activemq"
;
};
UnAuthenticatedLDAPLogin {
org.apache.activemq.jaas.LDAPLoginModule required
debug=true