Refactoring Auth
this is doing some refactoring, making the SecurityStore mechnism possible to be reused on other protocols, without forcing them to implement ServerSession on checks that won't fit the Server Model from Artemis
This commit is contained in:
parent
b91b5a1aae
commit
8d98fc395f
|
@ -51,6 +51,7 @@ import org.apache.activemq.artemis.core.protocol.openwire.amq.AMQSingleConsumerB
|
|||
import org.apache.activemq.artemis.core.protocol.openwire.amq.AMQTransaction;
|
||||
import org.apache.activemq.artemis.core.remoting.CloseListener;
|
||||
import org.apache.activemq.artemis.core.remoting.FailureListener;
|
||||
import org.apache.activemq.artemis.core.security.SecurityAuth;
|
||||
import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
|
||||
import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
|
||||
import org.apache.activemq.artemis.spi.core.remoting.Acceptor;
|
||||
|
@ -105,7 +106,7 @@ import org.apache.activemq.wireformat.WireFormat;
|
|||
/**
|
||||
* Represents an activemq connection.
|
||||
*/
|
||||
public class OpenWireConnection implements RemotingConnection, CommandVisitor {
|
||||
public class OpenWireConnection implements RemotingConnection, CommandVisitor, SecurityAuth {
|
||||
|
||||
private final OpenWireProtocolManager protocolManager;
|
||||
|
||||
|
@ -190,6 +191,39 @@ public class OpenWireConnection implements RemotingConnection, CommandVisitor {
|
|||
this.creationTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
|
||||
// SecurityAuth implementation
|
||||
@Override
|
||||
public String getUsername() {
|
||||
ConnectionInfo info = getConnectionInfo();
|
||||
if (info == null) {
|
||||
return null;
|
||||
}
|
||||
return info.getUserName();
|
||||
}
|
||||
|
||||
// SecurityAuth implementation
|
||||
@Override
|
||||
public String getPassword() {
|
||||
ConnectionInfo info = getConnectionInfo();
|
||||
if (info == null) {
|
||||
return null;
|
||||
}
|
||||
return info.getPassword();
|
||||
}
|
||||
|
||||
|
||||
private ConnectionInfo getConnectionInfo() {
|
||||
if (state == null) {
|
||||
return null;
|
||||
}
|
||||
ConnectionInfo info = state.getInfo();
|
||||
if (info == null) {
|
||||
return null;
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
public String getLocalAddress() {
|
||||
return transportConnection.getLocalAddress();
|
||||
}
|
||||
|
|
|
@ -47,14 +47,12 @@ import org.apache.activemq.artemis.core.protocol.openwire.amq.AMQConnectionConte
|
|||
import org.apache.activemq.artemis.core.protocol.openwire.amq.AMQConsumer;
|
||||
import org.apache.activemq.artemis.core.protocol.openwire.amq.AMQPersistenceAdapter;
|
||||
import org.apache.activemq.artemis.core.protocol.openwire.amq.AMQProducerBrokerExchange;
|
||||
import org.apache.activemq.artemis.core.protocol.openwire.amq.AMQServerSession;
|
||||
import org.apache.activemq.artemis.core.protocol.openwire.amq.AMQSession;
|
||||
import org.apache.activemq.artemis.core.remoting.impl.netty.NettyServerConnection;
|
||||
import org.apache.activemq.artemis.core.security.CheckType;
|
||||
import org.apache.activemq.artemis.core.server.ActiveMQServer;
|
||||
import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
|
||||
import org.apache.activemq.artemis.core.server.Queue;
|
||||
import org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl;
|
||||
import org.apache.activemq.artemis.core.server.management.ManagementService;
|
||||
import org.apache.activemq.artemis.core.server.management.Notification;
|
||||
import org.apache.activemq.artemis.core.server.management.NotificationListener;
|
||||
|
@ -583,21 +581,17 @@ public class OpenWireProtocolManager implements ProtocolManager<Interceptor>, No
|
|||
ActiveMQDestination dest = info.getDestination();
|
||||
if (dest.isQueue()) {
|
||||
SimpleString qName = OpenWireUtil.toCoreAddress(dest);
|
||||
ConnectionState state = connection.getState();
|
||||
ConnectionInfo connInfo = state.getInfo();
|
||||
if (connInfo != null) {
|
||||
String user = connInfo.getUserName();
|
||||
String pass = connInfo.getPassword();
|
||||
if (connection.getState().getInfo() != null) {
|
||||
|
||||
AMQServerSession fakeSession = new AMQServerSession(user, pass);
|
||||
CheckType checkType = dest.isTemporary() ? CheckType.CREATE_NON_DURABLE_QUEUE : CheckType.CREATE_DURABLE_QUEUE;
|
||||
((ActiveMQServerImpl) server).getSecurityStore().check(qName, checkType, fakeSession);
|
||||
server.getSecurityStore().check(qName, checkType, connection);
|
||||
|
||||
((ActiveMQServerImpl) server).checkQueueCreationLimit(user);
|
||||
server.checkQueueCreationLimit(connection.getUsername());
|
||||
}
|
||||
|
||||
QueueBinding binding = (QueueBinding) server.getPostOffice().getBinding(qName);
|
||||
if (binding == null) {
|
||||
ConnectionInfo connInfo = connection.getState().getInfo();
|
||||
this.server.createQueue(qName, qName, null, connInfo == null ? null : SimpleString.toSimpleString(connInfo.getUserName()), false, dest.isTemporary());
|
||||
}
|
||||
if (dest.isTemporary()) {
|
||||
|
|
|
@ -88,11 +88,6 @@ public class AMQServerSession extends ServerSessionImpl {
|
|||
super(name, username, password, minLargeMessageSize, autoCommitSends, autoCommitAcks, preAcknowledge, persistDeliveryCountBeforeDelivery, xa, connection, storageManager, postOffice, resourceManager, securityStore, managementService, activeMQServerImpl, managementAddress, simpleString, callback, context, new AMQTransactionFactory(), queueCreator);
|
||||
}
|
||||
|
||||
//create a fake session just for security check
|
||||
public AMQServerSession(String user, String pass) {
|
||||
super(user, pass);
|
||||
}
|
||||
|
||||
protected void doClose(final boolean failed) throws Exception {
|
||||
synchronized (this) {
|
||||
if (tx != null && tx.getXid() == null) {
|
||||
|
|
|
@ -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.activemq.artemis.core.security;
|
||||
|
||||
public interface SecurityAuth {
|
||||
|
||||
String getUsername();
|
||||
|
||||
String getPassword();
|
||||
|
||||
}
|
|
@ -17,13 +17,12 @@
|
|||
package org.apache.activemq.artemis.core.security;
|
||||
|
||||
import org.apache.activemq.artemis.api.core.SimpleString;
|
||||
import org.apache.activemq.artemis.core.server.ServerSession;
|
||||
|
||||
public interface SecurityStore {
|
||||
|
||||
void authenticate(String user, String password) throws Exception;
|
||||
|
||||
void check(SimpleString address, CheckType checkType, ServerSession session) throws Exception;
|
||||
void check(SimpleString address, CheckType checkType, SecurityAuth session) throws Exception;
|
||||
|
||||
boolean isSecurityEnabled();
|
||||
|
||||
|
|
|
@ -25,10 +25,10 @@ import org.apache.activemq.artemis.api.core.management.CoreNotificationType;
|
|||
import org.apache.activemq.artemis.api.core.management.ManagementHelper;
|
||||
import org.apache.activemq.artemis.core.security.CheckType;
|
||||
import org.apache.activemq.artemis.core.security.Role;
|
||||
import org.apache.activemq.artemis.core.security.SecurityAuth;
|
||||
import org.apache.activemq.artemis.core.security.SecurityStore;
|
||||
import org.apache.activemq.artemis.core.server.ActiveMQMessageBundle;
|
||||
import org.apache.activemq.artemis.core.server.ActiveMQServerLogger;
|
||||
import org.apache.activemq.artemis.core.server.ServerSession;
|
||||
import org.apache.activemq.artemis.core.server.management.Notification;
|
||||
import org.apache.activemq.artemis.core.server.management.NotificationService;
|
||||
import org.apache.activemq.artemis.core.settings.HierarchicalRepository;
|
||||
|
@ -138,7 +138,7 @@ public class SecurityStoreImpl implements SecurityStore, HierarchicalRepositoryC
|
|||
|
||||
public void check(final SimpleString address,
|
||||
final CheckType checkType,
|
||||
final ServerSession session) throws Exception {
|
||||
final SecurityAuth session) throws Exception {
|
||||
if (securityEnabled) {
|
||||
if (trace) {
|
||||
ActiveMQServerLogger.LOGGER.trace("checking access permissions to " + address);
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.apache.activemq.artemis.core.postoffice.PostOffice;
|
|||
import org.apache.activemq.artemis.core.remoting.server.RemotingService;
|
||||
import org.apache.activemq.artemis.core.replication.ReplicationManager;
|
||||
import org.apache.activemq.artemis.core.security.Role;
|
||||
import org.apache.activemq.artemis.core.security.SecurityAuth;
|
||||
import org.apache.activemq.artemis.core.security.SecurityStore;
|
||||
import org.apache.activemq.artemis.core.server.cluster.ClusterManager;
|
||||
import org.apache.activemq.artemis.core.server.cluster.ha.HAPolicy;
|
||||
|
@ -104,6 +105,8 @@ public interface ActiveMQServer extends ActiveMQComponent {
|
|||
|
||||
void unregisterActivateCallback(ActivateCallback callback);
|
||||
|
||||
void checkQueueCreationLimit(String username) throws Exception;
|
||||
|
||||
ServerSession createSession(String name,
|
||||
String username,
|
||||
String password,
|
||||
|
@ -221,12 +224,12 @@ public interface ActiveMQServer extends ActiveMQComponent {
|
|||
|
||||
void destroyQueue(SimpleString queueName) throws Exception;
|
||||
|
||||
void destroyQueue(SimpleString queueName, ServerSession session) throws Exception;
|
||||
void destroyQueue(SimpleString queueName, SecurityAuth session) throws Exception;
|
||||
|
||||
void destroyQueue(SimpleString queueName, ServerSession session, boolean checkConsumerCount) throws Exception;
|
||||
void destroyQueue(SimpleString queueName, SecurityAuth session, boolean checkConsumerCount) throws Exception;
|
||||
|
||||
void destroyQueue(SimpleString queueName,
|
||||
ServerSession session,
|
||||
SecurityAuth session,
|
||||
boolean checkConsumerCount,
|
||||
boolean removeConsumers) throws Exception;
|
||||
|
||||
|
|
|
@ -23,18 +23,15 @@ import java.util.Set;
|
|||
import org.apache.activemq.artemis.api.core.SimpleString;
|
||||
import org.apache.activemq.artemis.core.message.impl.MessageInternal;
|
||||
import org.apache.activemq.artemis.core.persistence.OperationContext;
|
||||
import org.apache.activemq.artemis.core.security.SecurityAuth;
|
||||
import org.apache.activemq.artemis.core.transaction.Transaction;
|
||||
import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
|
||||
import org.apache.activemq.artemis.utils.json.JSONArray;
|
||||
|
||||
public interface ServerSession {
|
||||
public interface ServerSession extends SecurityAuth {
|
||||
|
||||
String getName();
|
||||
|
||||
String getUsername();
|
||||
|
||||
String getPassword();
|
||||
|
||||
int getMinLargeMessageSize();
|
||||
|
||||
Object getConnectionID();
|
||||
|
|
|
@ -16,6 +16,30 @@
|
|||
*/
|
||||
package org.apache.activemq.artemis.core.server.impl;
|
||||
|
||||
import javax.management.MBeanServer;
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
|
||||
import org.apache.activemq.artemis.api.core.Pair;
|
||||
import org.apache.activemq.artemis.api.core.SimpleString;
|
||||
|
@ -29,9 +53,9 @@ import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
|
|||
import org.apache.activemq.artemis.core.filter.Filter;
|
||||
import org.apache.activemq.artemis.core.filter.impl.FilterImpl;
|
||||
import org.apache.activemq.artemis.core.io.IOCriticalErrorListener;
|
||||
import org.apache.activemq.artemis.core.journal.JournalLoadInformation;
|
||||
import org.apache.activemq.artemis.core.io.SequentialFile;
|
||||
import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory;
|
||||
import org.apache.activemq.artemis.core.journal.JournalLoadInformation;
|
||||
import org.apache.activemq.artemis.core.management.impl.ActiveMQServerControlImpl;
|
||||
import org.apache.activemq.artemis.core.paging.PagingManager;
|
||||
import org.apache.activemq.artemis.core.paging.cursor.PageSubscription;
|
||||
|
@ -58,6 +82,7 @@ import org.apache.activemq.artemis.core.remoting.server.impl.RemotingServiceImpl
|
|||
import org.apache.activemq.artemis.core.replication.ReplicationManager;
|
||||
import org.apache.activemq.artemis.core.security.CheckType;
|
||||
import org.apache.activemq.artemis.core.security.Role;
|
||||
import org.apache.activemq.artemis.core.security.SecurityAuth;
|
||||
import org.apache.activemq.artemis.core.security.SecurityStore;
|
||||
import org.apache.activemq.artemis.core.security.impl.SecurityStoreImpl;
|
||||
import org.apache.activemq.artemis.core.server.ActivateCallback;
|
||||
|
@ -107,30 +132,6 @@ import org.apache.activemq.artemis.utils.ReusableLatch;
|
|||
import org.apache.activemq.artemis.utils.SecurityFormatter;
|
||||
import org.apache.activemq.artemis.utils.VersionLoader;
|
||||
|
||||
import javax.management.MBeanServer;
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* The ActiveMQ Artemis server implementation
|
||||
*/
|
||||
|
@ -1182,18 +1183,18 @@ public class ActiveMQServerImpl implements ActiveMQServer {
|
|||
destroyQueue(queueName, null, true);
|
||||
}
|
||||
|
||||
public void destroyQueue(final SimpleString queueName, final ServerSession session) throws Exception {
|
||||
public void destroyQueue(final SimpleString queueName, final SecurityAuth session) throws Exception {
|
||||
destroyQueue(queueName, session, true);
|
||||
}
|
||||
|
||||
public void destroyQueue(final SimpleString queueName,
|
||||
final ServerSession session,
|
||||
final SecurityAuth session,
|
||||
final boolean checkConsumerCount) throws Exception {
|
||||
destroyQueue(queueName, session, checkConsumerCount, false);
|
||||
}
|
||||
|
||||
public void destroyQueue(final SimpleString queueName,
|
||||
final ServerSession session,
|
||||
final SecurityAuth session,
|
||||
final boolean checkConsumerCount,
|
||||
final boolean removeConsumers) throws Exception {
|
||||
addressSettingsRepository.clearCache();
|
||||
|
|
|
@ -172,30 +172,6 @@ public class ServerSessionImpl implements ServerSession, FailureListener {
|
|||
|
||||
private final TransactionFactory transactionFactory;
|
||||
|
||||
//create an 'empty' session. Only used by AMQServerSession
|
||||
//in order to check username and password
|
||||
protected ServerSessionImpl(String username, String password) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
|
||||
this.transactionFactory = null;
|
||||
this.strictUpdateDeliveryCount = false;
|
||||
this.storageManager = null;
|
||||
this.server = null;
|
||||
this.securityStore = null;
|
||||
this.resourceManager = null;
|
||||
this.remotingConnection = null;
|
||||
this.preAcknowledge = false;
|
||||
this.postOffice = null;
|
||||
this.name = null;
|
||||
this.minLargeMessageSize = 0;
|
||||
this.managementService = null;
|
||||
this.managementAddress = null;
|
||||
this.context = null;
|
||||
this.callback = null;
|
||||
this.queueCreator = null;
|
||||
}
|
||||
|
||||
public ServerSessionImpl(final String name,
|
||||
final String username,
|
||||
final String password,
|
||||
|
@ -494,7 +470,7 @@ public class ServerSessionImpl implements ServerSession, FailureListener {
|
|||
securityStore.check(address, CheckType.CREATE_NON_DURABLE_QUEUE, this);
|
||||
}
|
||||
|
||||
((ActiveMQServerImpl) server).checkQueueCreationLimit(getUsername());
|
||||
server.checkQueueCreationLimit(getUsername());
|
||||
|
||||
Queue queue;
|
||||
|
||||
|
@ -538,7 +514,7 @@ public class ServerSessionImpl implements ServerSession, FailureListener {
|
|||
final SimpleString filterString) throws Exception {
|
||||
securityStore.check(address, CheckType.CREATE_NON_DURABLE_QUEUE, this);
|
||||
|
||||
((ActiveMQServerImpl) server).checkQueueCreationLimit(getUsername());
|
||||
server.checkQueueCreationLimit(getUsername());
|
||||
|
||||
server.createSharedQueue(address, name, filterString, SimpleString.toSimpleString(getUsername()), durable);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue