mirror of https://github.com/apache/activemq.git
https://issues.apache.org/jira/browse/AMQ-5876 - load groups properties into per user set once also to avoid parse per login attempt
This commit is contained in:
parent
4d73b08923
commit
8d63083dff
|
@ -21,7 +21,6 @@ import java.io.IOException;
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
@ -52,7 +51,6 @@ public abstract class CertificateLoginModule extends PropertiesLoader implements
|
||||||
|
|
||||||
private X509Certificate certificates[];
|
private X509Certificate certificates[];
|
||||||
private String username;
|
private String username;
|
||||||
private Set<String> groups;
|
|
||||||
private Set<Principal> principals = new HashSet<Principal>();
|
private Set<Principal> principals = new HashSet<Principal>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -87,8 +85,6 @@ public abstract class CertificateLoginModule extends PropertiesLoader implements
|
||||||
throw new FailedLoginException("No user for client certificate: " + getDistinguishedName(certificates));
|
throw new FailedLoginException("No user for client certificate: " + getDistinguishedName(certificates));
|
||||||
}
|
}
|
||||||
|
|
||||||
groups = getUserGroups(username);
|
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
LOG.debug("Certificate for user: " + username);
|
LOG.debug("Certificate for user: " + username);
|
||||||
}
|
}
|
||||||
|
@ -102,7 +98,7 @@ public abstract class CertificateLoginModule extends PropertiesLoader implements
|
||||||
public boolean commit() throws LoginException {
|
public boolean commit() throws LoginException {
|
||||||
principals.add(new UserPrincipal(username));
|
principals.add(new UserPrincipal(username));
|
||||||
|
|
||||||
for (String group : groups) {
|
for (String group : getUserGroups(username)) {
|
||||||
principals.add(new GroupPrincipal(group));
|
principals.add(new GroupPrincipal(group));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,8 +143,8 @@ public abstract class CertificateLoginModule extends PropertiesLoader implements
|
||||||
* Helper method.
|
* Helper method.
|
||||||
*/
|
*/
|
||||||
private void clear() {
|
private void clear() {
|
||||||
groups.clear();
|
|
||||||
certificates = null;
|
certificates = null;
|
||||||
|
username = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -47,7 +47,7 @@ public class PropertiesLoginModule extends PropertiesLoader implements LoginModu
|
||||||
private CallbackHandler callbackHandler;
|
private CallbackHandler callbackHandler;
|
||||||
|
|
||||||
private Properties users;
|
private Properties users;
|
||||||
private Properties groups;
|
private Map<String,Set<String>> groups;
|
||||||
private String user;
|
private String user;
|
||||||
private final Set<Principal> principals = new HashSet<Principal>();
|
private final Set<Principal> principals = new HashSet<Principal>();
|
||||||
private boolean loginSucceeded;
|
private boolean loginSucceeded;
|
||||||
|
@ -59,7 +59,7 @@ public class PropertiesLoginModule extends PropertiesLoader implements LoginModu
|
||||||
loginSucceeded = false;
|
loginSucceeded = false;
|
||||||
init(options);
|
init(options);
|
||||||
users = load(USER_FILE_PROP_NAME, "user", options).getProps();
|
users = load(USER_FILE_PROP_NAME, "user", options).getProps();
|
||||||
groups = load(GROUP_FILE_PROP_NAME, "group", options).getProps();
|
groups = load(GROUP_FILE_PROP_NAME, "group", options).invertedPropertiesValuesMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -105,14 +105,10 @@ public class PropertiesLoginModule extends PropertiesLoader implements LoginModu
|
||||||
if (result) {
|
if (result) {
|
||||||
principals.add(new UserPrincipal(user));
|
principals.add(new UserPrincipal(user));
|
||||||
|
|
||||||
for (Map.Entry<Object, Object> entry : groups.entrySet()) {
|
Set<String> matchedGroups = groups.get(user);
|
||||||
String name = (String) entry.getKey();
|
if (matchedGroups != null) {
|
||||||
String[] userList = ((String)entry.getValue()).split(",");
|
for (String entry : matchedGroups) {
|
||||||
for (int i = 0; i < userList.length; i++) {
|
principals.add(new GroupPrincipal(entry));
|
||||||
if (user.equals(userList[i])) {
|
|
||||||
principals.add(new GroupPrincipal(name));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,10 @@ import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import java.util.Set;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -30,6 +32,7 @@ public class ReloadableProperties {
|
||||||
|
|
||||||
private Properties props = new Properties();
|
private Properties props = new Properties();
|
||||||
private Map<String, String> invertedProps;
|
private Map<String, String> invertedProps;
|
||||||
|
private Map<String, Set<String>> invertedValueProps;
|
||||||
private long reloadTime = -1;
|
private long reloadTime = -1;
|
||||||
private final PropertiesLoader.FileNameKey key;
|
private final PropertiesLoader.FileNameKey key;
|
||||||
|
|
||||||
|
@ -71,6 +74,24 @@ public class ReloadableProperties {
|
||||||
return invertedProps;
|
return invertedProps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public synchronized Map<String, Set<String>> invertedPropertiesValuesMap() {
|
||||||
|
if (invertedValueProps == null) {
|
||||||
|
invertedValueProps = new HashMap<>(props.size());
|
||||||
|
for (Map.Entry<Object, Object> val : props.entrySet()) {
|
||||||
|
String[] userList = ((String)val.getValue()).split(",");
|
||||||
|
for (String user : userList) {
|
||||||
|
Set<String> set = invertedValueProps.get(user);
|
||||||
|
if (set == null) {
|
||||||
|
set = new HashSet<>();
|
||||||
|
invertedValueProps.put(user, set);
|
||||||
|
}
|
||||||
|
set.add((String)val.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return invertedValueProps;
|
||||||
|
}
|
||||||
|
|
||||||
private void load(final File source, Properties props) throws IOException {
|
private void load(final File source, Properties props) throws IOException {
|
||||||
FileInputStream in = new FileInputStream(source);
|
FileInputStream in = new FileInputStream(source);
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
package org.apache.activemq.jaas;
|
package org.apache.activemq.jaas;
|
||||||
|
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -46,7 +47,7 @@ public class TextFileCertificateLoginModule extends CertificateLoginModule {
|
||||||
private static final String USER_FILE_PROP_NAME = "org.apache.activemq.jaas.textfiledn.user";
|
private static final String USER_FILE_PROP_NAME = "org.apache.activemq.jaas.textfiledn.user";
|
||||||
private static final String GROUP_FILE_PROP_NAME = "org.apache.activemq.jaas.textfiledn.group";
|
private static final String GROUP_FILE_PROP_NAME = "org.apache.activemq.jaas.textfiledn.group";
|
||||||
|
|
||||||
private Properties groups;
|
private Map<String, Set<String>> groupsByUser;
|
||||||
private Map<String, String> usersByDn;
|
private Map<String, String> usersByDn;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,7 +58,7 @@ public class TextFileCertificateLoginModule extends CertificateLoginModule {
|
||||||
super.initialize(subject, callbackHandler, sharedState, options);
|
super.initialize(subject, callbackHandler, sharedState, options);
|
||||||
|
|
||||||
usersByDn = load(USER_FILE_PROP_NAME, "", options).invertedPropertiesMap();
|
usersByDn = load(USER_FILE_PROP_NAME, "", options).invertedPropertiesMap();
|
||||||
groups = load(GROUP_FILE_PROP_NAME, "", options).getProps();
|
groupsByUser = load(GROUP_FILE_PROP_NAME, "", options).invertedPropertiesValuesMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -89,18 +90,10 @@ public class TextFileCertificateLoginModule extends CertificateLoginModule {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Set<String> getUserGroups(String username) throws LoginException {
|
protected Set<String> getUserGroups(String username) throws LoginException {
|
||||||
Set<String> userGroups = new HashSet<String>();
|
Set<String> userGroups = groupsByUser.get(username);
|
||||||
for (Enumeration<Object> enumeration = groups.keys(); enumeration.hasMoreElements();) {
|
if (userGroups == null) {
|
||||||
String groupName = (String)enumeration.nextElement();
|
userGroups = Collections.emptySet();
|
||||||
String[] userList = (groups.getProperty(groupName) + "").split(",");
|
|
||||||
for (int i = 0; i < userList.length; i++) {
|
|
||||||
if (username.equals(userList[i])) {
|
|
||||||
userGroups.add(groupName);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return userGroups;
|
return userGroups;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue